Skip to content

Commit

Permalink
Check if version already exist in S3
Browse files Browse the repository at this point in the history
  • Loading branch information
Islam Monjid committed Oct 15, 2024
1 parent bf1ad01 commit 773eefb
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
30 changes: 30 additions & 0 deletions internal/project/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"golang.org/x/sync/semaphore"
)

var ErrVersionAlreadyExist = errors.New("Project version already exists")
type Translation struct {
TTL time.Duration
Checksum string
Expand Down Expand Up @@ -320,7 +321,36 @@ func (s *ServiceImpl) DeleteProjectVersionByIDAndProjectID(ctx context.Context,
return nil
}

func (s *ServiceImpl) checkProjectVersionExistInS3(ctx context.Context, projectID int, name string) (bool, error) {
s3Output, err := s.storage.ListObjects(ctx, fmt.Sprintf("%d/", projectID))
if err != nil {
return false, errors.Wrap(err, "failed to get project versions")
}

for _, object := range s3Output.CommonPrefixes {
// Example Prefix : {projectID}/{versionID_versionName_timestamp}/
// 720964/61ded6dc-c8b7-4d4e-aa70-cd37dd1216b3_1.0.0_123456789/
prefixData := strings.Split(aws.ToString(object.Prefix), "/")

versionData := strings.Split(prefixData[1], "_")
versionName := versionData[1]

if versionName == name {
return true, nil
}
}

return false, nil
}

func (s *ServiceImpl) CreateLanguagesVersion(ctx context.Context, projectID int, name string) error {
exists, err := s.checkProjectVersionExistInS3(ctx, projectID, name)
if err != nil {
return errors.Wrap(err, "Failed to check project version existence in S3")
}
if exists {
return ErrVersionAlreadyExist
}
languagesResponse, err := s.Client.ListProjectLanguages(ctx, poedit.ListProjectLanguagesRequest{
ID: projectID,
})
Expand Down
35 changes: 35 additions & 0 deletions internal/project/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,16 @@ func TestServiceCreateLanguagesVersion(t *testing.T) {
},
}

prefix := fmt.Sprintf("%d/%s_%s_%d", testID, testUUID, "1.0.0", testGenerateTimestamp())

listObjectsV2Output := &s3.ListObjectsV2Output{
CommonPrefixes: []types.CommonPrefix{
{
Prefix: &prefix,
},
},
}

exportProjectRequest := poedit.ExportProjectRequest{
ID: int(testProjectID),
Language: "en",
Expand All @@ -341,6 +351,7 @@ func TestServiceCreateLanguagesVersion(t *testing.T) {
fileName := fmt.Sprintf("%d/%s_%s_%d/%s.json", testID, testUUID, testName, testGenerateTimestamp(), "en")

t.Run("Success", func(t *testing.T) {
storage.EXPECT().ListObjects(testCtx, testStorageKeyForListing).Times(1).Return(listObjectsV2Output, nil)
poeditClient.EXPECT().ListProjectLanguages(testCtx, listProjectLanguagesRequest).Return(listAvailableLanguagesResponse, nil)
poeditClient.EXPECT().ExportProject(testCtx, exportProjectRequest).Return(exportProjectResponse, nil)

Expand All @@ -354,7 +365,28 @@ func TestServiceCreateLanguagesVersion(t *testing.T) {
assert.NoError(t, err)
})

t.Run("Fail, version already exist in S3", func(t *testing.T) {

prefixExist := fmt.Sprintf("%d/%s_%s_%d", testID, testUUID, testName, testGenerateTimestamp())

listObjectsV2Output := &s3.ListObjectsV2Output{
CommonPrefixes: []types.CommonPrefix{
{
Prefix: &prefixExist,
},
},
}

storage.EXPECT().ListObjects(testCtx, testStorageKeyForListing).Times(1).Return(listObjectsV2Output, nil)

err := service.CreateLanguagesVersion(testCtx, int(testProjectID), testName)

assert.ErrorIs(t, err, ErrVersionAlreadyExist)
assert.ErrorContains(t, err, "Project version already exists")
})

t.Run("Fail, fails to list project languages", func(t *testing.T) {
storage.EXPECT().ListObjects(testCtx, testStorageKeyForListing).Times(1).Return(listObjectsV2Output, nil)
poeditClient.EXPECT().ListProjectLanguages(testCtx, listProjectLanguagesRequest).Return(nil, errTest)

err := service.CreateLanguagesVersion(testCtx, int(testProjectID), testName)
Expand All @@ -363,6 +395,7 @@ func TestServiceCreateLanguagesVersion(t *testing.T) {
})

t.Run("Fail, fails to export project", func(t *testing.T) {
storage.EXPECT().ListObjects(testCtx, testStorageKeyForListing).Times(1).Return(listObjectsV2Output, nil)
poeditClient.EXPECT().ListProjectLanguages(testCtx, listProjectLanguagesRequest).Return(listAvailableLanguagesResponse, nil)
poeditClient.EXPECT().ExportProject(testCtx, exportProjectRequest).Return(nil, errTest)

Expand All @@ -372,6 +405,7 @@ func TestServiceCreateLanguagesVersion(t *testing.T) {
})

t.Run("Fail, fails to download file", func(t *testing.T) {
storage.EXPECT().ListObjects(testCtx, testStorageKeyForListing).Times(1).Return(listObjectsV2Output, nil)
poeditClient.EXPECT().ListProjectLanguages(testCtx, listProjectLanguagesRequest).Return(listAvailableLanguagesResponse, nil)
poeditClient.EXPECT().ExportProject(testCtx, exportProjectRequest).Return(exportProjectResponse, nil)

Expand All @@ -384,6 +418,7 @@ func TestServiceCreateLanguagesVersion(t *testing.T) {
})

t.Run("Fail, fails to upload file to S3", func(t *testing.T) {
storage.EXPECT().ListObjects(testCtx, testStorageKeyForListing).Times(1).Return(listObjectsV2Output, nil)
poeditClient.EXPECT().ListProjectLanguages(testCtx, listProjectLanguagesRequest).Return(listAvailableLanguagesResponse, nil)
poeditClient.EXPECT().ExportProject(testCtx, exportProjectRequest).Return(exportProjectResponse, nil)

Expand Down
5 changes: 5 additions & 0 deletions internal/rest/v1/private/controllers/project.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controllers

import (
"errors"
"net/http"
"time"

Expand Down Expand Up @@ -226,6 +227,10 @@ func (h *Handlers) postProjectVersion(c echo.Context, l *logrus.Entry) error {
req.Name,
)
if err != nil {
if errors.Is(err, project.ErrVersionAlreadyExist) {
return echo.ErrBadRequest
}

l.WithError(err).Error("Error creating project version")

return echo.ErrInternalServerError
Expand Down

0 comments on commit 773eefb

Please sign in to comment.