diff --git a/cmd/serve.go b/cmd/serve.go index 3818218..eea9615 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -198,6 +198,12 @@ func instantiateLogger() *logrus.Logger { logger.Warnf("Did not understand log format '%s'. Defaulting to json format", viper.GetString(confLogFormat)) logger.SetFormatter(&logrus.JSONFormatter{}) } + + logger.WithFields(logrus.Fields{ + "level": viper.GetString(confLogLevel), + "format": viper.GetString(confLogFormat), + }).Info("Logger initialized") + return logger } diff --git a/go.mod b/go.mod index d7a5f32..01f2bd0 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,11 @@ go 1.23 require ( github.com/AppsFlyer/go-sundheit v0.5.0 - github.com/aws/aws-sdk-go-v2 v1.30.3 - github.com/aws/aws-sdk-go-v2/config v1.27.27 - github.com/aws/aws-sdk-go-v2/service/s3 v1.58.3 - github.com/go-playground/validator v9.31.0+incompatible + github.com/alitto/pond v1.9.2 + github.com/aws/aws-sdk-go-v2 v1.32.2 + github.com/aws/aws-sdk-go-v2/config v1.27.43 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.32 + github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 github.com/go-playground/validator/v10 v10.22.1 github.com/go-redis/cache/v8 v8.4.4 github.com/go-redis/redis/v8 v8.11.5 @@ -32,21 +33,21 @@ require ( ) require ( - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.17 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.15 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect - github.com/aws/smithy-go v1.20.3 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.41 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 // indirect + github.com/aws/smithy-go v1.22.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -89,7 +90,6 @@ require ( golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.2.0 // indirect google.golang.org/protobuf v1.28.1 // indirect - gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 6bc988d..aebc266 100644 --- a/go.sum +++ b/go.sum @@ -45,42 +45,46 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= -github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM= -github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= -github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= -github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15 h1:Z5r7SycxmSllHYmaAZPpmN8GviDrSGhMS6bldqtXZPw= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15/go.mod h1:CetW7bDE00QoGEmPUoZuRog07SGVAUVW6LFpNP0YfIg= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.17 h1:YPYe6ZmvUfDDDELqEKtAd6bo8zxhkm+XEFEzQisqUIE= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.17/go.mod h1:oBtcnYua/CgzCWYN7NZ5j7PotFDaFSUjCYVTtfyn7vw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.15 h1:246A4lSTXWJw/rmlQI+TT2OcqeDMKBdyjEQrafMaQdA= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.15/go.mod h1:haVfg3761/WF7YPuJOER2MP0k4UAXyHaLclKXB6usDg= -github.com/aws/aws-sdk-go-v2/service/s3 v1.58.3 h1:hT8ZAZRIfqBqHbzKTII+CIiY8G2oC9OpLedkZ51DWl8= -github.com/aws/aws-sdk-go-v2/service/s3 v1.58.3/go.mod h1:Lcxzg5rojyVPU/0eFwLtcyTaek/6Mtic5B1gJo7e/zE= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= -github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= -github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs= +github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI= +github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= +github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= +github.com/aws/aws-sdk-go-v2/config v1.27.43 h1:p33fDDihFC390dhhuv8nOmX419wjOSDQRb+USt20RrU= +github.com/aws/aws-sdk-go-v2/config v1.27.43/go.mod h1:pYhbtvg1siOOg8h5an77rXle9tVG8T+BWLWAo7cOukc= +github.com/aws/aws-sdk-go-v2/credentials v1.17.41 h1:7gXo+Axmp+R4Z+AK8YFQO0ZV3L0gizGINCOWxSLY9W8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.41/go.mod h1:u4Eb8d3394YLubphT4jLEwN1rLNq2wFOlT6OuxFwPzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 h1:TMH3f/SCAWdNtXXVPPu5D6wrr4G5hI1rAxbcocKfC7Q= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17/go.mod h1:1ZRXLdTpzdJb9fwTMXiLipENRxkGMTn1sfKexGllQCw= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.32 h1:C2hE+gJ40Cb4vzhFJ+tTzjvBpPloUq7XP6PD3A2Fk7g= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.32/go.mod h1:0OmMtVNp+10JFBTfmA2AIeqBDm0YthDXmE+N7poaptk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 h1:7edmS3VOBDhK00b/MwGtGglCm7hhwNYnjJs/PgFdMQE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21/go.mod h1:Q9o5h4HoIWG8XfzxqiuK/CGUbepCJ8uTlaE3bAbxytQ= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 h1:4FMHqLfk0efmTqhXVRL5xYRqlEBNBiRI7N6w4jsEdd4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2/go.mod h1:LWoqeWlK9OZeJxsROW2RqrSPvQHKTpp69r/iDjwsSaw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 h1:t7iUP9+4wdc5lt3E41huP+GvQZJD38WLsgVp4iOtAjg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2/go.mod h1:/niFCtmuQNxqx9v8WAPq5qh7EH25U4BF6tjoyq9bObM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3 h1:xxHGZ+wUgZNACQmxtdvP5tgzfsxGS3vPpTP5Hy3iToE= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.3/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 h1:bSYXVyUzoTHoKalBmwaZxs97HU9DWWI3ehHSAMa7xOk= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.2/go.mod h1:skMqY7JElusiOUjMJMOv1jJsP7YUg7DrhgqZZWuzu1U= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 h1:AhmO1fHINP9vFYUE0LHzCWg/LfUWUF+zFPEcY9QXb7o= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2/go.mod h1:o8aQygT2+MVP0NaV6kbdE1YnnIM8RRVQzoeUH45GOdI= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 h1:CiS7i0+FUe+/YY1GvIBLLrR/XNGZ4CtM1Ll0XavNuVo= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.2/go.mod h1:HtaiBI8CjYoNVde8arShXb94UbQQi9L4EMr6D+xGBwo= +github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= +github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -136,8 +140,6 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator v9.31.0+incompatible h1:UA72EPEogEnq76ehGdEDp4Mit+3FDh548oRqwVgNsHA= -github.com/go-playground/validator v9.31.0+incompatible/go.mod h1:yrEkQXlcI+PugkyDjY2bRrL/UBU4f3rvrgkN3V8JEig= github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/cache/v8 v8.4.4 h1:Rm0wZ55X22BA2JMqVtRQNHYyzDd0I5f+Ec/C9Xx3mXY= @@ -747,8 +749,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= diff --git a/internal/project/service.go b/internal/project/service.go index 461793a..f462c91 100644 --- a/internal/project/service.go +++ b/internal/project/service.go @@ -14,6 +14,7 @@ import ( gosundheit "github.com/AppsFlyer/go-sundheit" "github.com/AppsFlyer/go-sundheit/checks" + "github.com/alitto/pond" "github.com/aws/aws-sdk-go-v2/aws" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -373,60 +374,62 @@ func (s *ServiceImpl) CreateLanguagesVersion(ctx context.Context, projectID int, ContentType string } - var translationObjects []TranslationObject + jobErrors := []error{} + pool := pond.New(10, 1000) // 25 workers, 1000 buffered jobs + + versionKey := fmt.Sprintf("%d/%s_%s_%d", projectID, uuid, name, timeStamp) for _, language := range languagesResponse.Result.Languages { for contentMetaKey, contentMeta := range contentMetaMap { - resp, err := s.Client.ExportProject(ctx, poedit.ExportProjectRequest{ - ID: projectID, - Language: language.Code, - Type: contentMetaKey, - Filters: []string{"translated"}, - }) - if err != nil { - return errors.Wrap(err, "Failed to export project") - } - - d, err := http.Get(resp.Result.URL) - if err != nil { - return errors.Wrap(err, "Failed to download project language file") - } - defer d.Body.Close() - - if d.StatusCode != http.StatusOK { - return errors.Errorf("Response code '%d' from download GET", d.StatusCode) - } - - //upload to s3 - data, err := io.ReadAll(d.Body) - if err != nil { - return errors.Wrap(err, "Failed to read project language file") - } - - reader := bytes.NewReader(data) - - s3Key := fmt.Sprintf("%d/%s_%s_%d/%s.%s", projectID, uuid, name, timeStamp, language.Code, contentMeta.Extension) - - meta := map[string]string{ - "project": fmt.Sprintf("%d", projectID), - "lang": language.Code, - "versionName": name, - "format": contentMeta.Extension, - } - - translationObjects = append(translationObjects, TranslationObject{ - S3Key: s3Key, - Reader: reader, - Meta: meta, - ContentType: contentMeta.Type, + pool.Submit(func() { + resp, err := s.Client.ExportProject(ctx, poedit.ExportProjectRequest{ + ID: projectID, + Language: language.Code, + Type: contentMetaKey, + Filters: []string{"translated"}, + }) + if err != nil { + jobErrors = append(jobErrors, errors.Wrap(err, "Failed to export project")) + } + + d, err := http.Get(resp.Result.URL) + if err != nil { + jobErrors = append(jobErrors, errors.Wrap(err, "Failed to download project language file")) + } + defer d.Body.Close() + + if d.StatusCode != http.StatusOK { + jobErrors = append(jobErrors, errors.Errorf("Response code '%d' from download GET", d.StatusCode)) + } + + s3Key := fmt.Sprintf("%s/%s.%s", versionKey, language.Code, contentMeta.Extension) + + meta := map[string]string{ + "project": fmt.Sprintf("%d", projectID), + "lang": language.Code, + "versionName": name, + "format": contentMeta.Extension, + } + + fmt.Println("Uploading to S3", s3Key) + + if err := s.storage.PutObject(ctx, s3Key, d.Body, meta, contentMeta.Type); err != nil { + jobErrors = append(jobErrors, errors.Wrap(err, "Failed to upload project language file to S3")) + } + + fmt.Println("Done uploading to S3", s3Key) }) } } - for _, translationObject := range translationObjects { - if err := s.storage.PutObject(ctx, translationObject.S3Key, translationObject.Reader, translationObject.Meta, translationObject.ContentType); err != nil { - return errors.Wrap(err, "Failed to upload project language file to S3") + pool.StopAndWait() + + if len(jobErrors) > 0 { + if err := s.storage.DeleteObjects(ctx, versionKey); err != nil { + return errors.Wrap(err, "Failed to delete project version in S3") } + + return errors.New("Failed to create language versions") } return nil diff --git a/internal/rest/v1/helpers/validator.go b/internal/rest/v1/helpers/validator.go index de97f22..4d36299 100644 --- a/internal/rest/v1/helpers/validator.go +++ b/internal/rest/v1/helpers/validator.go @@ -1,6 +1,8 @@ package helpers import ( + "regexp" + "github.com/go-playground/validator/v10" "github.com/johngb/langreg" ) @@ -13,6 +15,7 @@ func NewValidator() *Validator { v := validator.New() v.RegisterValidation("languageCode", validateLanguageCode) + v.RegisterValidation("version", validateVersion) return &Validator{ validator: v, @@ -26,3 +29,9 @@ func (cv *Validator) Validate(i interface{}) error { func validateLanguageCode(fl validator.FieldLevel) bool { return langreg.IsValidLanguageCode(fl.Field().String()) } + +func validateVersion(fl validator.FieldLevel) bool { + r := regexp.MustCompile(`^[a-zA-Z0-9.-_]*$`) + + return r.MatchString(fl.Field().String()) +} diff --git a/internal/rest/v1/private/controllers/project.go b/internal/rest/v1/private/controllers/project.go index aed1e40..756e5f0 100644 --- a/internal/rest/v1/private/controllers/project.go +++ b/internal/rest/v1/private/controllers/project.go @@ -22,6 +22,8 @@ type getAllProjectsResponse struct { } func (h *Handlers) getAllProjects(ctx echo.Context, l *logrus.Entry) error { + l.Debug("Retrieving projects") + projects, err := h.ProjectService.GetAllProjects(ctx.Request().Context()) if err != nil { l.WithError(err).Error("Error retrieving projects") @@ -74,6 +76,8 @@ func (h *Handlers) getProject(ctx echo.Context, l *logrus.Entry) error { l = l.WithField("project", req.ID) + l.Debug("Retrieving project") + project, err := h.ProjectService.GetProjectByID( ctx.Request().Context(), req.ID, @@ -128,6 +132,8 @@ func (h *Handlers) getProjectVersions(c echo.Context, l *logrus.Entry) error { l = l.WithField("project", req.ProjectID) + l.Debug("Retrieving project versions") + versions, err := h.ProjectService.GetProjectVersions( c.Request().Context(), req.ProjectID, @@ -167,7 +173,7 @@ func (h *Handlers) newGetProjectVersionsResponse( type deleteProjectVersionRequest struct { ProjectID uint `param:"project_id" validate:"required,numeric"` - VersionID string `param:"version_id" validate:"required,semver,max=20"` + VersionID string `param:"version_id" validate:"required,version,max=20"` } func (h *Handlers) deleteProjectVersion(c echo.Context, l *logrus.Entry) error { @@ -183,6 +189,8 @@ func (h *Handlers) deleteProjectVersion(c echo.Context, l *logrus.Entry) error { "version": req.VersionID, }) + l.Debug("Deleting project version") + err := h.ProjectService.DeleteProjectVersionByIDAndProjectID( c.Request().Context(), req.VersionID, @@ -194,12 +202,14 @@ func (h *Handlers) deleteProjectVersion(c echo.Context, l *logrus.Entry) error { return echo.ErrInternalServerError } + l.Info("Project version deleted") + return c.NoContent(http.StatusOK) } type postProjectVersionRequest struct { ID int `param:"id" validate:"required,numeric"` - Name string `json:"name" validate:"required,semver,max=20"` + Name string `json:"name" validate:"required,version,max=20"` } func (h *Handlers) postProjectVersion(c echo.Context, l *logrus.Entry) error { @@ -210,6 +220,13 @@ func (h *Handlers) postProjectVersion(c echo.Context, l *logrus.Entry) error { return echo.ErrBadRequest } + l = l.WithFields(logrus.Fields{ + "project": req.ID, + "name": req.Name, + }) + + l.Debug("Creating project version") + if err := c.Validate(req); err != nil { l.WithError(err).Error("Error binding request") @@ -236,5 +253,7 @@ func (h *Handlers) postProjectVersion(c echo.Context, l *logrus.Entry) error { return echo.ErrInternalServerError } + l.Info("Creating project version") + return c.NoContent(http.StatusCreated) } diff --git a/internal/rest/v1/private/controllers/project_test.go b/internal/rest/v1/private/controllers/project_test.go index 547fd3f..b8dec79 100644 --- a/internal/rest/v1/private/controllers/project_test.go +++ b/internal/rest/v1/private/controllers/project_test.go @@ -11,7 +11,7 @@ import ( "testing" "time" - "github.com/go-playground/validator" + "github.com/go-playground/validator/v10" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" diff --git a/internal/rest/v1/public/controllers/project.go b/internal/rest/v1/public/controllers/project.go index 6584406..9dee939 100644 --- a/internal/rest/v1/public/controllers/project.go +++ b/internal/rest/v1/public/controllers/project.go @@ -17,7 +17,7 @@ type getProjectLanguageRequest struct { Project int `param:"project" validate:"required"` Language string `param:"language" validate:"required,languageCode"` Format string `query:"format" validate:"omitempty,oneof=po pot mo xls xlsx csv ini resw resx android_strings apple_strings xliff properties key_value_json json yml xlf xmb xtb arb rise_360_xliff"` - Version string `query:"version" validate:"omitempty,max=20,alphanum"` + Version string `query:"version" validate:"omitempty,max=20,semver"` } func (h *Handlers) getProjectLanguage(ctx echo.Context, l *logrus.Entry) error { @@ -100,4 +100,4 @@ func (h *Handlers) getProjectLanguage(ctx echo.Context, l *logrus.Entry) error { ctx.Response().Header().Add("Content-Transfer-Encoding", "8bit") return ctx.Stream(http.StatusOK, contentMeta.Type, bytes.NewReader(trans.Data)) -} \ No newline at end of file +} diff --git a/internal/rest/v1/public/controllers/project_test.go b/internal/rest/v1/public/controllers/project_test.go index af431f3..25fcf28 100644 --- a/internal/rest/v1/public/controllers/project_test.go +++ b/internal/rest/v1/public/controllers/project_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/go-playground/validator" + "github.com/go-playground/validator/v10" "github.com/labstack/echo/v4" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" @@ -20,11 +20,11 @@ import ( ) var ( - errTest = errors.New("test error") - testID int64 = 1 - testLanguage string = "en" - testFormat string = "key_value_json" - testVersion string = "latest" + errTest = errors.New("test error") + testID int64 = 1 + testLanguage string = "en" + testFormat string = "key_value_json" + testVersion string = "latest" ) type CustomValidator struct { @@ -68,7 +68,6 @@ func TestGetProjectLanguage(t *testing.T) { } t.Run("getProjectLanguage, success", func(t *testing.T) { - projectService.EXPECT().GetTranslation(context.Background(), int(testID), testLanguage, testFormat, testVersion).Times(1).Return(&project.Translation{ Data: []byte("test"), Checksum: "test", @@ -81,11 +80,9 @@ func TestGetProjectLanguage(t *testing.T) { }) t.Run("getProjectLanguage, fail", func(t *testing.T) { - projectService.EXPECT().GetTranslation(context.Background(), int(testID), testLanguage, testFormat, testVersion).Times(1).Return(nil, errTest) err := h.getProjectLanguage(testCtx, logrus.NewEntry(logrus.New())) assert.Error(t, err) - }) } diff --git a/internal/storage/repository.go b/internal/storage/repository.go index d6d7e18..4c3d0f6 100644 --- a/internal/storage/repository.go +++ b/internal/storage/repository.go @@ -38,6 +38,30 @@ type S3API interface { params *s3.DeleteObjectsInput, optFns ...func(*s3.Options), ) (*s3.DeleteObjectsOutput, error) + + AbortMultipartUpload( + ctx context.Context, + params *s3.AbortMultipartUploadInput, + optFns ...func(*s3.Options), + ) (*s3.AbortMultipartUploadOutput, error) + + CompleteMultipartUpload( + ctx context.Context, + params *s3.CompleteMultipartUploadInput, + optFns ...func(*s3.Options), + ) (*s3.CompleteMultipartUploadOutput, error) + + CreateMultipartUpload( + ctx context.Context, + params *s3.CreateMultipartUploadInput, + optFns ...func(*s3.Options), + ) (*s3.CreateMultipartUploadOutput, error) + + UploadPart( + ctx context.Context, + params *s3.UploadPartInput, + optFns ...func(*s3.Options), + ) (*s3.UploadPartOutput, error) } type Storage interface { diff --git a/internal/storage/repository_mock.go b/internal/storage/repository_mock.go index f7d33c9..010be93 100644 --- a/internal/storage/repository_mock.go +++ b/internal/storage/repository_mock.go @@ -129,6 +129,54 @@ func (m *MockS3API) PutObject(ctx context.Context, params *s3.PutObjectInput, op return ret0, ret1 } +func (m *MockS3API) AbortMultipartUpload(ctx context.Context, params *s3.AbortMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.AbortMultipartUploadOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, params} + for _, a := range optFns { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AbortMultipartUpload", varargs...) + ret0, _ := ret[0].(*s3.AbortMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +func (m *MockS3API) CompleteMultipartUpload(ctx context.Context, params *s3.CompleteMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.CompleteMultipartUploadOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, params} + for _, a := range optFns { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CompleteMultipartUpload", varargs...) + ret0, _ := ret[0].(*s3.CompleteMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +func (m *MockS3API) CreateMultipartUpload(ctx context.Context, params *s3.CreateMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.CreateMultipartUploadOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, params} + for _, a := range optFns { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateMultipartUpload", varargs...) + ret0, _ := ret[0].(*s3.CreateMultipartUploadOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +func (m *MockS3API) UploadPart(ctx context.Context, params *s3.UploadPartInput, optFns ...func(*s3.Options)) (*s3.UploadPartOutput, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, params} + for _, a := range optFns { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UploadPart", varargs...) + ret0, _ := ret[0].(*s3.UploadPartOutput) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + // PutObject indicates an expected call of PutObject. func (mr *MockS3APIMockRecorder) PutObject(ctx, params interface{}, optFns ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() @@ -230,3 +278,27 @@ func (mr *MockStorageMockRecorder) PutObject(ctx, key, payloadReader, metadata, mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObject", reflect.TypeOf((*MockStorage)(nil).PutObject), ctx, key, payloadReader, metadata, mimeType) } + +func (mr *MockS3APIMockRecorder) AbortMultipartUpload(ctx, params interface{}, optFns ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, params}, optFns...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortMultipartUpload", reflect.TypeOf((*MockS3API)(nil).AbortMultipartUpload), varargs...) +} + +func (mr *MockS3APIMockRecorder) CompleteMultipartUpload(ctx, params interface{}, optFns ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, params}, optFns...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CompleteMultipartUpload", reflect.TypeOf((*MockS3API)(nil).CompleteMultipartUpload), varargs...) +} + +func (mr *MockS3APIMockRecorder) CreateMultipartUpload(ctx, params interface{}, optFns ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, params}, optFns...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateMultipartUpload", reflect.TypeOf((*MockS3API)(nil).CreateMultipartUpload), varargs...) +} + +func (mr *MockS3APIMockRecorder) UploadPart(ctx, params interface{}, optFns ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, params}, optFns...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UploadPart", reflect.TypeOf((*MockS3API)(nil).UploadPart), varargs...) +} diff --git a/internal/storage/repository_s3.go b/internal/storage/repository_s3.go index 1a78eef..3a1affe 100644 --- a/internal/storage/repository_s3.go +++ b/internal/storage/repository_s3.go @@ -6,6 +6,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/pkg/errors" @@ -39,7 +40,9 @@ func NewS3Client(ctx context.Context, conf S3StorageConfig) (*S3ClientImpl, erro // PutObject creates an S3 object func (c *S3ClientImpl) PutObject(ctx context.Context, key string, payloadReader io.Reader, metadata map[string]string, mimeType string) error { - if _, err := c.client.PutObject(ctx, &s3.PutObjectInput{ + uploader := manager.NewUploader(c.client) + + if _, err := uploader.Upload(ctx, &s3.PutObjectInput{ Body: payloadReader, Bucket: aws.String(c.config.Bucket), Key: aws.String(key), @@ -111,7 +114,6 @@ func (s *S3ClientImpl) GetObject(ctx context.Context, key string) (*s3.GetObject Bucket: aws.String(s.config.Bucket), Key: aws.String(key), }) - if err != nil { return nil, errors.Wrap(err, "Failed to get object from S3") } @@ -122,8 +124,8 @@ func (s *S3ClientImpl) GetObject(ctx context.Context, key string) (*s3.GetObject // ListObjects lists all objects in an S3 bucket func (s *S3ClientImpl) ListObjects(ctx context.Context, storageKey string) (*s3.ListObjectsV2Output, error) { output, err := s.client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{ - Bucket: aws.String(s.config.Bucket), - Prefix: &storageKey, + Bucket: aws.String(s.config.Bucket), + Prefix: &storageKey, Delimiter: aws.String("/"), }) if err != nil { @@ -132,3 +134,43 @@ func (s *S3ClientImpl) ListObjects(ctx context.Context, storageKey string) (*s3. return output, nil } + +func (s *S3ClientImpl) AbortMultipartUpload(ctx context.Context, uploadID string) error { + _, err := s.client.AbortMultipartUpload(ctx, &s3.AbortMultipartUploadInput{ + Bucket: aws.String(s.config.Bucket), + Key: aws.String(uploadID), + UploadId: aws.String(uploadID), + }) + if err != nil { + return errors.Wrap(err, "Failed to abort multipart upload") + } + + return nil +} + +func (s *S3ClientImpl) CompleteMultipartUpload(ctx context.Context, input *s3.CompleteMultipartUploadInput) (*s3.CompleteMultipartUploadOutput, error) { + output, err := s.client.CompleteMultipartUpload(ctx, input) + if err != nil { + return nil, errors.Wrap(err, "Failed to complete multipart upload") + } + + return output, nil +} + +func (s *S3ClientImpl) CreateMultipartUpload(ctx context.Context, input *s3.CreateMultipartUploadInput) (*s3.CreateMultipartUploadOutput, error) { + output, err := s.client.CreateMultipartUpload(ctx, input) + if err != nil { + return nil, errors.Wrap(err, "Failed to create multipart upload") + } + + return output, nil +} + +func (s *S3ClientImpl) UploadPart(ctx context.Context, input *s3.UploadPartInput) (*s3.UploadPartOutput, error) { + output, err := s.client.UploadPart(ctx, input) + if err != nil { + return nil, errors.Wrap(err, "Failed to upload part") + } + + return output, nil +} diff --git a/internal/storage/repository_s3_test.go b/internal/storage/repository_s3_test.go index 00077d8..9d487ca 100644 --- a/internal/storage/repository_s3_test.go +++ b/internal/storage/repository_s3_test.go @@ -14,11 +14,15 @@ import ( var errForTesting = errors.New("this is an error for testing") type MockS3APIMethods struct { - DeleteObjectFunction func(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) - PutObjectFunction func(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) - GetObjectFunction func(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) - ListObjectsV2Function func(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) - DeleteObjectsFunction func(ctx context.Context, params *s3.DeleteObjectsInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectsOutput, error) + DeleteObjectFunction func(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) + PutObjectFunction func(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) + GetObjectFunction func(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) + ListObjectsV2Function func(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) + DeleteObjectsFunction func(ctx context.Context, params *s3.DeleteObjectsInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectsOutput, error) + AbortMultipartUploadFunction func(ctx context.Context, params *s3.AbortMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.AbortMultipartUploadOutput, error) + CompleteMultipartUploadFunction func(ctx context.Context, params *s3.CompleteMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.CompleteMultipartUploadOutput, error) + CreateMultipartUploadFunction func(ctx context.Context, params *s3.CreateMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.CreateMultipartUploadOutput, error) + UploadPartFunction func(ctx context.Context, params *s3.UploadPartInput, optFns ...func(*s3.Options)) (*s3.UploadPartOutput, error) } func (m *MockS3APIMethods) DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error) { @@ -41,6 +45,22 @@ func (m *MockS3APIMethods) DeleteObjects(ctx context.Context, params *s3.DeleteO return m.DeleteObjectsFunction(ctx, params, optFns...) } +func (m *MockS3APIMethods) AbortMultipartUpload(ctx context.Context, params *s3.AbortMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.AbortMultipartUploadOutput, error) { + return m.AbortMultipartUploadFunction(ctx, params, optFns...) +} + +func (m *MockS3APIMethods) CompleteMultipartUpload(ctx context.Context, params *s3.CompleteMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.CompleteMultipartUploadOutput, error) { + return m.CompleteMultipartUploadFunction(ctx, params, optFns...) +} + +func (m *MockS3APIMethods) CreateMultipartUpload(ctx context.Context, params *s3.CreateMultipartUploadInput, optFns ...func(*s3.Options)) (*s3.CreateMultipartUploadOutput, error) { + return m.CreateMultipartUploadFunction(ctx, params, optFns...) +} + +func (m *MockS3APIMethods) UploadPart(ctx context.Context, params *s3.UploadPartInput, optFns ...func(*s3.Options)) (*s3.UploadPartOutput, error) { + return m.UploadPartFunction(ctx, params, optFns...) +} + func TestNewS3Client(t *testing.T) { t.Parallel() @@ -63,7 +83,6 @@ func TestDeleteObject(t *testing.T) { t.Run("Delete object, fail", func(t *testing.T) { mockClient := &MockS3APIMethods{ - DeleteObjectFunction: func( _ctx context.Context, _params *s3.DeleteObjectInput, @@ -86,7 +105,6 @@ func TestDeleteObject(t *testing.T) { }) t.Run("Delete object, success", func(t *testing.T) { mockClient := &MockS3APIMethods{ - DeleteObjectFunction: func( _ctx context.Context, _params *s3.DeleteObjectInput, @@ -122,7 +140,6 @@ func TestPutObject(t *testing.T) { t.Run("Put object, fail", func(t *testing.T) { mockClient := &MockS3APIMethods{ - PutObjectFunction: func( _ctx context.Context, _params *s3.PutObjectInput, @@ -146,7 +163,6 @@ func TestPutObject(t *testing.T) { }) t.Run("Put object, success", func(t *testing.T) { mockClient := &MockS3APIMethods{ - PutObjectFunction: func( _ctx context.Context, _params *s3.PutObjectInput, @@ -182,7 +198,6 @@ func TestGetObject(t *testing.T) { t.Run("Get object, fail", func(t *testing.T) { mockClient := &MockS3APIMethods{ - GetObjectFunction: func( _ctx context.Context, _params *s3.GetObjectInput, @@ -207,7 +222,6 @@ func TestGetObject(t *testing.T) { }) t.Run("Get object, success", func(t *testing.T) { mockClient := &MockS3APIMethods{ - GetObjectFunction: func( _ctx context.Context, _params *s3.GetObjectInput, @@ -244,7 +258,6 @@ func TestListObjects(t *testing.T) { t.Run("List objects, fail", func(t *testing.T) { mockClient := &MockS3APIMethods{ - ListObjectsV2Function: func( _ctx context.Context, _params *s3.ListObjectsV2Input, @@ -268,7 +281,6 @@ func TestListObjects(t *testing.T) { }) t.Run("List objects, success", func(t *testing.T) { mockClient := &MockS3APIMethods{ - ListObjectsV2Function: func( _ctx context.Context, _params *s3.ListObjectsV2Input, @@ -304,7 +316,6 @@ func TestDeleteObjects(t *testing.T) { t.Run("Delete objects, fail", func(t *testing.T) { mockClient := &MockS3APIMethods{ - ListObjectsV2Function: func( _ctx context.Context, _params *s3.ListObjectsV2Input, @@ -327,7 +338,6 @@ func TestDeleteObjects(t *testing.T) { }) t.Run("Delete objects, success", func(t *testing.T) { mockClient := &MockS3APIMethods{ - ListObjectsV2Function: func( _ctx context.Context, _params *s3.ListObjectsV2Input, diff --git a/pkg/poedit/projects.go b/pkg/poedit/projects.go index 8f9770d..9e54015 100644 --- a/pkg/poedit/projects.go +++ b/pkg/poedit/projects.go @@ -437,7 +437,7 @@ func (c *ClientImpl) ExportProject(ctx context.Context, r ExportProjectRequest) } } - if res.Response.Code == "4044" { + if res.Response.Code == "404" { return nil, &ErrLanguageNotFound{ ProjectID: r.ID, LanguageCode: r.Language, @@ -445,6 +445,7 @@ func (c *ClientImpl) ExportProject(ctx context.Context, r ExportProjectRequest) } if res.Response.Code != "200" { + fmt.Println(res.Response) return nil, errors.New(res.Response.Message) }