Merged in feature/localstackands3object (pull request #54)
LocalStack and S3 Objects * firstround * cleanupintegration * tidyports
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
**/*.http
|
||||||
|
**/*.cast
|
||||||
|
|
||||||
# Ignore the binary files generated by `go build`
|
# Ignore the binary files generated by `go build`
|
||||||
/main
|
/main
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ package docinitrunner
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
documentinit "queryorchestration/internal/document/init"
|
documentinit "queryorchestration/internal/document/init"
|
||||||
|
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
@@ -28,8 +31,30 @@ func New(validator *validator.Validate, svc *Services) Runner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type S3EventNotification struct {
|
||||||
|
Records []struct {
|
||||||
|
EventVersion string `json:"eventVersion"`
|
||||||
|
EventSource string `json:"eventSource"`
|
||||||
|
AwsRegion string `json:"awsRegion"`
|
||||||
|
EventTime string `json:"eventTime"`
|
||||||
|
EventName string `json:"eventName"`
|
||||||
|
S3 struct {
|
||||||
|
Bucket struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Arn string `json:"arn"`
|
||||||
|
} `json:"bucket"`
|
||||||
|
Object struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
ETag string `json:"eTag"`
|
||||||
|
VersionId string `json:"versionId"`
|
||||||
|
} `json:"object"`
|
||||||
|
} `json:"s3"`
|
||||||
|
} `json:"Records"`
|
||||||
|
}
|
||||||
|
|
||||||
func (s Runner) Process(ctx context.Context, req *types.Message) error {
|
func (s Runner) Process(ctx context.Context, req *types.Message) error {
|
||||||
var body documentinit.Create
|
var body S3EventNotification
|
||||||
err := json.Unmarshal([]byte(*req.Body), &body)
|
err := json.Unmarshal([]byte(*req.Body), &body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -40,9 +65,39 @@ func (s Runner) Process(ctx context.Context, req *types.Message) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.svc.Document.Create(ctx, &body)
|
hasErr := false
|
||||||
if err != nil {
|
|
||||||
return err
|
for _, record := range body.Records {
|
||||||
|
err := func() error {
|
||||||
|
if record.EventName != "ObjectCreated:Put" {
|
||||||
|
return fmt.Errorf("invalid event name: %s", record.EventName)
|
||||||
|
}
|
||||||
|
|
||||||
|
jobID, err := s.svc.Document.GetJobIDFromKey(record.S3.Object.Key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = s.svc.Document.Create(ctx, &documentinit.Create{
|
||||||
|
JobID: jobID,
|
||||||
|
Location: record.S3.Object.Key,
|
||||||
|
Bucket: record.S3.Bucket.Name,
|
||||||
|
Hash: record.S3.Object.ETag,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
hasErr = true
|
||||||
|
slog.Error("Error processing record", "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasErr {
|
||||||
|
return errors.New("error processing records")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -17,13 +17,11 @@ import (
|
|||||||
objectstoremock "queryorchestration/mocks/objectstore"
|
objectstoremock "queryorchestration/mocks/objectstore"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
|
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pashagolub/pgxmock/v3"
|
"github.com/pashagolub/pgxmock/v3"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DocInitConfig struct {
|
type DocInitConfig struct {
|
||||||
@@ -98,18 +96,6 @@ func TestDocInitRunner(t *testing.T) {
|
|||||||
WillReturnResult(pgxmock.NewResult("", 1))
|
WillReturnResult(pgxmock.NewResult("", 1))
|
||||||
pool.ExpectCommit()
|
pool.ExpectCommit()
|
||||||
|
|
||||||
mockStore.EXPECT().
|
|
||||||
HeadObject(
|
|
||||||
mock.Anything,
|
|
||||||
mock.MatchedBy(func(in *s3.HeadObjectInput) bool {
|
|
||||||
return *in.Bucket == doc.Bucket && *in.Key == doc.Location
|
|
||||||
}),
|
|
||||||
mock.Anything,
|
|
||||||
).
|
|
||||||
Return(&s3.HeadObjectOutput{
|
|
||||||
ETag: &docinfo.Hash,
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
err = runner.Process(ctx, msg)
|
err = runner.Process(ctx, msg)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import (
|
|||||||
"queryorchestration/internal/job/collector"
|
"queryorchestration/internal/job/collector"
|
||||||
"queryorchestration/internal/server/runner"
|
"queryorchestration/internal/server/runner"
|
||||||
"queryorchestration/internal/serviceconfig"
|
"queryorchestration/internal/serviceconfig"
|
||||||
objectstore "queryorchestration/internal/serviceconfig/objectstore"
|
|
||||||
documentcleanc "queryorchestration/internal/serviceconfig/queue/documentclean"
|
documentcleanc "queryorchestration/internal/serviceconfig/queue/documentclean"
|
||||||
|
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
@@ -22,7 +21,6 @@ import (
|
|||||||
type DocInitConfig struct {
|
type DocInitConfig struct {
|
||||||
runner.BaseConfig
|
runner.BaseConfig
|
||||||
documentcleanc.DocCleanConfig
|
documentcleanc.DocCleanConfig
|
||||||
objectstore.ObjectStoreConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -62,11 +60,5 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cfg.SetStoreClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
slog.Error(err.Error())
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
server.Listen(ctx)
|
server.Listen(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,75 @@
|
|||||||
---
|
---
|
||||||
services:
|
services:
|
||||||
|
doc_init_runner:
|
||||||
|
image: queryorchestration:latest
|
||||||
|
command: ["./docInitRunner"]
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
- localstack
|
||||||
|
environment:
|
||||||
|
QUEUE_URL: ${DOCUMENT_INIT_URL}
|
||||||
|
DOCUMENT_CLEAN_URL: ${DOCUMENT_CLEAN_URL}
|
||||||
|
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
|
||||||
|
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN}
|
||||||
|
AWS_REGION: ${AWS_REGION}
|
||||||
|
DB_USER: ${DB_USER}
|
||||||
|
DB_PASS: ${DB_PASS}
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_NAME: ${DB_NAME}
|
||||||
|
DB_NOSSL: ${DB_NOSSL}
|
||||||
|
AWS_ENDPOINT_URL: "http://localstack:4566"
|
||||||
|
AWS_S3_USE_PATH_STYLE: true
|
||||||
|
networks:
|
||||||
|
- server-network
|
||||||
|
query_runner:
|
||||||
|
image: queryorchestration:latest
|
||||||
|
command: ["./queryRunner"]
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
- localstack
|
||||||
|
environment:
|
||||||
|
QUEUE_URL: ${QUERY_RUNNER_URL}
|
||||||
|
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
|
||||||
|
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN}
|
||||||
|
AWS_REGION: ${AWS_REGION}
|
||||||
|
DB_USER: ${DB_USER}
|
||||||
|
DB_PASS: ${DB_PASS}
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_NAME: ${DB_NAME}
|
||||||
|
DB_NOSSL: ${DB_NOSSL}
|
||||||
|
AWS_ENDPOINT_URL: "http://localstack:4566"
|
||||||
|
AWS_S3_USE_PATH_STYLE: true
|
||||||
|
networks:
|
||||||
|
- server-network
|
||||||
|
query_service:
|
||||||
|
image: queryorchestration:latest
|
||||||
|
command: ["./queryService"]
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
- localstack
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
expose:
|
||||||
|
- 8080
|
||||||
|
environment:
|
||||||
|
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
|
||||||
|
AWS_SESSION_TOKEN: ${AWS_SESSION_TOKEN}
|
||||||
|
AWS_REGION: ${AWS_REGION}
|
||||||
|
DB_USER: ${DB_USER}
|
||||||
|
DB_PASS: ${DB_PASS}
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_NAME: ${DB_NAME}
|
||||||
|
DB_NOSSL: ${DB_NOSSL}
|
||||||
|
AWS_ENDPOINT_URL: "http://localstack:4566"
|
||||||
|
AWS_S3_USE_PATH_STYLE: true
|
||||||
|
networks:
|
||||||
|
- server-network
|
||||||
db:
|
db:
|
||||||
image: postgres:17.2-alpine3.21
|
image: postgres:17.2-alpine3.21
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ services:
|
|||||||
test-db:
|
test-db:
|
||||||
image: postgres:17.2-alpine3.21
|
image: postgres:17.2-alpine3.21
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5430:5432
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: ${DB_NAME}
|
POSTGRES_DB: ${DB_NAME}
|
||||||
POSTGRES_PASSWORD: ${DB_PASS}
|
POSTGRES_PASSWORD: ${DB_PASS}
|
||||||
POSTGRES_USER: ${DB_USER}
|
POSTGRES_USER: ${DB_USER}
|
||||||
expose:
|
expose:
|
||||||
- 5432
|
- 5430
|
||||||
volumes:
|
volumes:
|
||||||
- test-db-data:/var/lib/postgresql/data
|
- test-db-data:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"shell": {
|
"shell": {
|
||||||
"init_hook": [
|
"init_hook": [
|
||||||
"export DB_URI=postgres://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable",
|
"export DB_URI=postgres://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable",
|
||||||
|
"export DB_URI_TEST=postgres://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT_TEST}/${DB_NAME}?sslmode=disable",
|
||||||
"echo 'Welcome to the DoczyAI devbox!'"
|
"echo 'Welcome to the DoczyAI devbox!'"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
"DB_PASS": "pass",
|
"DB_PASS": "pass",
|
||||||
"DB_HOST": "localhost",
|
"DB_HOST": "localhost",
|
||||||
"DB_PORT": "5432",
|
"DB_PORT": "5432",
|
||||||
|
"DB_PORT_TEST": "5430",
|
||||||
"DB_NAME": "query_orchestration",
|
"DB_NAME": "query_orchestration",
|
||||||
"DB_NOSSL": "true",
|
"DB_NOSSL": "true",
|
||||||
"AWS_ACCESS_KEY_ID": "test",
|
"AWS_ACCESS_KEY_ID": "test",
|
||||||
|
|||||||
@@ -4,23 +4,25 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"queryorchestration/internal/database"
|
"queryorchestration/internal/database"
|
||||||
"queryorchestration/internal/database/repository"
|
"queryorchestration/internal/database/repository"
|
||||||
"queryorchestration/internal/document"
|
"queryorchestration/internal/document"
|
||||||
documentclean "queryorchestration/internal/document/clean"
|
documentclean "queryorchestration/internal/document/clean"
|
||||||
"queryorchestration/internal/job"
|
"queryorchestration/internal/job"
|
||||||
"queryorchestration/internal/serviceconfig/queue"
|
"queryorchestration/internal/serviceconfig/queue"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
|
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Create struct {
|
type Create struct {
|
||||||
JobID uuid.UUID `json:"jobId" validate:"required,uuid"`
|
JobID uuid.UUID
|
||||||
Location document.Location `json:"location" validate:"required"`
|
Location document.Location
|
||||||
Bucket string `json:"bucket" validate:"required"`
|
Bucket string
|
||||||
|
Hash string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Create(ctx context.Context, doc *Create) (uuid.UUID, error) {
|
func (s *Service) Create(ctx context.Context, doc *Create) (uuid.UUID, error) {
|
||||||
@@ -39,9 +41,11 @@ func (s *Service) Create(ctx context.Context, doc *Create) (uuid.UUID, error) {
|
|||||||
return uuid.Nil, err
|
return uuid.Nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.informCreate(ctx, id, j)
|
if params.ID == nil {
|
||||||
if err != nil {
|
err = s.informCreate(ctx, id, j)
|
||||||
return uuid.Nil, err
|
if err != nil {
|
||||||
|
return uuid.Nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return id, nil
|
return id, nil
|
||||||
@@ -56,17 +60,9 @@ type createDocumentParams struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) getCreateParams(ctx context.Context, doc *Create) (*createDocumentParams, error) {
|
func (s *Service) getCreateParams(ctx context.Context, doc *Create) (*createDocumentParams, error) {
|
||||||
res, err := s.cfg.GetStoreClient().HeadObject(ctx, &s3.HeadObjectInput{
|
|
||||||
Bucket: &doc.Bucket,
|
|
||||||
Key: &doc.Location,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
idbyhash, err := s.cfg.GetDBQueries().GetDocumentIDByHash(ctx, &repository.GetDocumentIDByHashParams{
|
idbyhash, err := s.cfg.GetDBQueries().GetDocumentIDByHash(ctx, &repository.GetDocumentIDByHashParams{
|
||||||
Jobid: database.MustToDBUUID(doc.JobID),
|
Jobid: database.MustToDBUUID(doc.JobID),
|
||||||
Hash: *res.ETag,
|
Hash: doc.Hash,
|
||||||
})
|
})
|
||||||
var docID *pgtype.UUID
|
var docID *pgtype.UUID
|
||||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||||
@@ -78,7 +74,7 @@ func (s *Service) getCreateParams(ctx context.Context, doc *Create) (*createDocu
|
|||||||
return &createDocumentParams{
|
return &createDocumentParams{
|
||||||
ID: docID,
|
ID: docID,
|
||||||
JobID: database.MustToDBUUID(doc.JobID),
|
JobID: database.MustToDBUUID(doc.JobID),
|
||||||
Hash: *res.ETag,
|
Hash: doc.Hash,
|
||||||
Bucket: doc.Bucket,
|
Bucket: doc.Bucket,
|
||||||
Location: doc.Location,
|
Location: doc.Location,
|
||||||
}, nil
|
}, nil
|
||||||
@@ -141,3 +137,18 @@ func (s *Service) informCreate(ctx context.Context, id uuid.UUID, j *job.Job) er
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetJobIDFromKey(key string) (uuid.UUID, error) {
|
||||||
|
re := regexp.MustCompile(`^.+/(.+)/.+$`)
|
||||||
|
match := re.FindStringSubmatch(key)
|
||||||
|
if match == nil || len(match) != 2 {
|
||||||
|
return uuid.Nil, fmt.Errorf("no job id match found in key")
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := uuid.Parse(match[1])
|
||||||
|
if err != nil {
|
||||||
|
return uuid.Nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
queuemock "queryorchestration/mocks/queue"
|
queuemock "queryorchestration/mocks/queue"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/sqs"
|
"github.com/aws/aws-sdk-go-v2/service/sqs"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pashagolub/pgxmock/v3"
|
"github.com/pashagolub/pgxmock/v3"
|
||||||
@@ -82,22 +81,11 @@ func TestCreate(t *testing.T) {
|
|||||||
WillReturnResult(pgxmock.NewResult("", 1))
|
WillReturnResult(pgxmock.NewResult("", 1))
|
||||||
pool.ExpectCommit()
|
pool.ExpectCommit()
|
||||||
|
|
||||||
mockStore.EXPECT().
|
|
||||||
HeadObject(
|
|
||||||
mock.Anything,
|
|
||||||
mock.MatchedBy(func(in *s3.HeadObjectInput) bool {
|
|
||||||
return *in.Bucket == bucket && *in.Key == location
|
|
||||||
}),
|
|
||||||
mock.Anything,
|
|
||||||
).
|
|
||||||
Return(&s3.HeadObjectOutput{
|
|
||||||
ETag: &doc.Hash,
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
id, err := svc.Create(ctx, &Create{
|
id, err := svc.Create(ctx, &Create{
|
||||||
JobID: doc.JobID,
|
JobID: doc.JobID,
|
||||||
Location: location,
|
Location: location,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
|
Hash: doc.Hash,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, doc.ID, id)
|
assert.Equal(t, doc.ID, id)
|
||||||
@@ -164,22 +152,11 @@ func TestGetCreateParams(t *testing.T) {
|
|||||||
pgxmock.NewRows([]string{"id"}),
|
pgxmock.NewRows([]string{"id"}),
|
||||||
)
|
)
|
||||||
|
|
||||||
mockStore.EXPECT().
|
|
||||||
HeadObject(
|
|
||||||
mock.Anything,
|
|
||||||
mock.MatchedBy(func(in *s3.HeadObjectInput) bool {
|
|
||||||
return *in.Bucket == bucket && *in.Key == location
|
|
||||||
}),
|
|
||||||
mock.Anything,
|
|
||||||
).
|
|
||||||
Return(&s3.HeadObjectOutput{
|
|
||||||
ETag: &doc.Hash,
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
params, err := svc.getCreateParams(ctx, &Create{
|
params, err := svc.getCreateParams(ctx, &Create{
|
||||||
JobID: doc.JobID,
|
JobID: doc.JobID,
|
||||||
Location: location,
|
Location: location,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
|
Hash: doc.Hash,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, &createDocumentParams{
|
assert.Equal(t, &createDocumentParams{
|
||||||
@@ -222,22 +199,11 @@ func TestGetCreateParamsExisting(t *testing.T) {
|
|||||||
AddRow(database.MustToDBUUID(doc.ID)),
|
AddRow(database.MustToDBUUID(doc.ID)),
|
||||||
)
|
)
|
||||||
|
|
||||||
mockStore.EXPECT().
|
|
||||||
HeadObject(
|
|
||||||
mock.Anything,
|
|
||||||
mock.MatchedBy(func(in *s3.HeadObjectInput) bool {
|
|
||||||
return *in.Bucket == bucket && *in.Key == location
|
|
||||||
}),
|
|
||||||
mock.Anything,
|
|
||||||
).
|
|
||||||
Return(&s3.HeadObjectOutput{
|
|
||||||
ETag: &doc.Hash,
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
params, err := svc.getCreateParams(ctx, &Create{
|
params, err := svc.getCreateParams(ctx, &Create{
|
||||||
JobID: doc.JobID,
|
JobID: doc.JobID,
|
||||||
Location: location,
|
Location: location,
|
||||||
Bucket: bucket,
|
Bucket: bucket,
|
||||||
|
Hash: doc.Hash,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
dbid := database.MustToDBUUID(doc.ID)
|
dbid := database.MustToDBUUID(doc.ID)
|
||||||
@@ -279,18 +245,6 @@ func TestGetCreateParamsCurrentDocErr(t *testing.T) {
|
|||||||
pool.ExpectQuery("-- name: GetDocumentIDByHash :one").WithArgs(doc.Hash, database.MustToDBUUID(doc.JobID)).
|
pool.ExpectQuery("-- name: GetDocumentIDByHash :one").WithArgs(doc.Hash, database.MustToDBUUID(doc.JobID)).
|
||||||
WillReturnError(errors.New("db err"))
|
WillReturnError(errors.New("db err"))
|
||||||
|
|
||||||
mockStore.EXPECT().
|
|
||||||
HeadObject(
|
|
||||||
mock.Anything,
|
|
||||||
mock.MatchedBy(func(in *s3.HeadObjectInput) bool {
|
|
||||||
return *in.Bucket == bucket && *in.Key == location
|
|
||||||
}),
|
|
||||||
mock.Anything,
|
|
||||||
).
|
|
||||||
Return(&s3.HeadObjectOutput{
|
|
||||||
ETag: &doc.Hash,
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
_, err = svc.getCreateParams(ctx, &Create{
|
_, err = svc.getCreateParams(ctx, &Create{
|
||||||
JobID: doc.JobID,
|
JobID: doc.JobID,
|
||||||
Location: location,
|
Location: location,
|
||||||
@@ -385,3 +339,21 @@ func TestSubmitCreateExists(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, doc.ID, id)
|
assert.Equal(t, doc.ID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetJobIDFromKey(t *testing.T) {
|
||||||
|
svc := Service{}
|
||||||
|
|
||||||
|
_, err := svc.GetJobIDFromKey("")
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
_, err = svc.GetJobIDFromKey("jkhaskhweuifhwhieh")
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
_, err = svc.GetJobIDFromKey("aaa/bbb/ccc")
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
id := uuid.New()
|
||||||
|
aid, err := svc.GetJobIDFromKey(fmt.Sprintf("aaa/%s/bbb", id.String()))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, id, aid)
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package documentinit
|
|||||||
import (
|
import (
|
||||||
"queryorchestration/internal/job"
|
"queryorchestration/internal/job"
|
||||||
"queryorchestration/internal/serviceconfig"
|
"queryorchestration/internal/serviceconfig"
|
||||||
"queryorchestration/internal/serviceconfig/objectstore"
|
|
||||||
"queryorchestration/internal/serviceconfig/queue/documentclean"
|
"queryorchestration/internal/serviceconfig/queue/documentclean"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,7 +13,6 @@ type Services struct {
|
|||||||
type ConfigProvider interface {
|
type ConfigProvider interface {
|
||||||
serviceconfig.ConfigProvider
|
serviceconfig.ConfigProvider
|
||||||
documentclean.ConfigProvider
|
documentclean.ConfigProvider
|
||||||
objectstore.ConfigProvider
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ func (c *Server) pollMessage(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, message := range result.Messages {
|
for _, message := range result.Messages {
|
||||||
slog.Info("processing message", "id", message.MessageId)
|
slog.Info("processing message", "id", *message.MessageId)
|
||||||
|
|
||||||
err := c.cfg.GetController().Process(ctx, &message)
|
err := c.cfg.GetController().Process(ctx, &message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("message process fail", "err", err)
|
slog.Error("message process fail", "id", *message.MessageId, "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.cfg.DeleteFromQueue(ctx, &queue.DeleteParams{
|
err = c.cfg.DeleteFromQueue(ctx, &queue.DeleteParams{
|
||||||
@@ -55,7 +55,7 @@ func (c *Server) pollMessage(ctx context.Context) error {
|
|||||||
ReceiptHandle: message.ReceiptHandle,
|
ReceiptHandle: message.ReceiptHandle,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("message delete fail", "err", err)
|
slog.Error("message delete fail", "id", *message.MessageId, "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,4 +47,8 @@ type S3Client interface {
|
|||||||
GetBucketLifecycleConfiguration(ctx context.Context, params *s3.GetBucketLifecycleConfigurationInput, opts ...func(*s3.Options)) (*s3.GetBucketLifecycleConfigurationOutput, error)
|
GetBucketLifecycleConfiguration(ctx context.Context, params *s3.GetBucketLifecycleConfigurationInput, opts ...func(*s3.Options)) (*s3.GetBucketLifecycleConfigurationOutput, error)
|
||||||
PutBucketLifecycleConfiguration(ctx context.Context, params *s3.PutBucketLifecycleConfigurationInput, opts ...func(*s3.Options)) (*s3.PutBucketLifecycleConfigurationOutput, error)
|
PutBucketLifecycleConfiguration(ctx context.Context, params *s3.PutBucketLifecycleConfigurationInput, opts ...func(*s3.Options)) (*s3.PutBucketLifecycleConfigurationOutput, error)
|
||||||
DeleteBucketLifecycle(ctx context.Context, params *s3.DeleteBucketLifecycleInput, opts ...func(*s3.Options)) (*s3.DeleteBucketLifecycleOutput, error)
|
DeleteBucketLifecycle(ctx context.Context, params *s3.DeleteBucketLifecycleInput, opts ...func(*s3.Options)) (*s3.DeleteBucketLifecycleOutput, error)
|
||||||
|
|
||||||
|
// Bucket Notifications
|
||||||
|
PutBucketNotificationConfiguration(ctx context.Context, params *s3.PutBucketNotificationConfigurationInput, opts ...func(*s3.Options)) (*s3.PutBucketNotificationConfigurationOutput, error)
|
||||||
|
GetBucketNotificationConfiguration(ctx context.Context, params *s3.GetBucketNotificationConfigurationInput, opts ...func(*s3.Options)) (*s3.GetBucketNotificationConfigurationOutput, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -911,6 +911,80 @@ func (_c *MockS3Client_GetBucketLifecycleConfiguration_Call) RunAndReturn(run fu
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBucketNotificationConfiguration provides a mock function with given fields: ctx, params, opts
|
||||||
|
func (_m *MockS3Client) GetBucketNotificationConfiguration(ctx context.Context, params *s3.GetBucketNotificationConfigurationInput, opts ...func(*s3.Options)) (*s3.GetBucketNotificationConfigurationOutput, error) {
|
||||||
|
_va := make([]interface{}, len(opts))
|
||||||
|
for _i := range opts {
|
||||||
|
_va[_i] = opts[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, params)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for GetBucketNotificationConfiguration")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 *s3.GetBucketNotificationConfigurationOutput
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *s3.GetBucketNotificationConfigurationInput, ...func(*s3.Options)) (*s3.GetBucketNotificationConfigurationOutput, error)); ok {
|
||||||
|
return rf(ctx, params, opts...)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *s3.GetBucketNotificationConfigurationInput, ...func(*s3.Options)) *s3.GetBucketNotificationConfigurationOutput); ok {
|
||||||
|
r0 = rf(ctx, params, opts...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*s3.GetBucketNotificationConfigurationOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, *s3.GetBucketNotificationConfigurationInput, ...func(*s3.Options)) error); ok {
|
||||||
|
r1 = rf(ctx, params, opts...)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockS3Client_GetBucketNotificationConfiguration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBucketNotificationConfiguration'
|
||||||
|
type MockS3Client_GetBucketNotificationConfiguration_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBucketNotificationConfiguration is a helper method to define mock.On call
|
||||||
|
// - ctx context.Context
|
||||||
|
// - params *s3.GetBucketNotificationConfigurationInput
|
||||||
|
// - opts ...func(*s3.Options)
|
||||||
|
func (_e *MockS3Client_Expecter) GetBucketNotificationConfiguration(ctx interface{}, params interface{}, opts ...interface{}) *MockS3Client_GetBucketNotificationConfiguration_Call {
|
||||||
|
return &MockS3Client_GetBucketNotificationConfiguration_Call{Call: _e.mock.On("GetBucketNotificationConfiguration",
|
||||||
|
append([]interface{}{ctx, params}, opts...)...)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockS3Client_GetBucketNotificationConfiguration_Call) Run(run func(ctx context.Context, params *s3.GetBucketNotificationConfigurationInput, opts ...func(*s3.Options))) *MockS3Client_GetBucketNotificationConfiguration_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
variadicArgs := make([]func(*s3.Options), len(args)-2)
|
||||||
|
for i, a := range args[2:] {
|
||||||
|
if a != nil {
|
||||||
|
variadicArgs[i] = a.(func(*s3.Options))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run(args[0].(context.Context), args[1].(*s3.GetBucketNotificationConfigurationInput), variadicArgs...)
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockS3Client_GetBucketNotificationConfiguration_Call) Return(_a0 *s3.GetBucketNotificationConfigurationOutput, _a1 error) *MockS3Client_GetBucketNotificationConfiguration_Call {
|
||||||
|
_c.Call.Return(_a0, _a1)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockS3Client_GetBucketNotificationConfiguration_Call) RunAndReturn(run func(context.Context, *s3.GetBucketNotificationConfigurationInput, ...func(*s3.Options)) (*s3.GetBucketNotificationConfigurationOutput, error)) *MockS3Client_GetBucketNotificationConfiguration_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// GetObject provides a mock function with given fields: ctx, params, opts
|
// GetObject provides a mock function with given fields: ctx, params, opts
|
||||||
func (_m *MockS3Client) GetObject(ctx context.Context, params *s3.GetObjectInput, opts ...func(*s3.Options)) (*s3.GetObjectOutput, error) {
|
func (_m *MockS3Client) GetObject(ctx context.Context, params *s3.GetObjectInput, opts ...func(*s3.Options)) (*s3.GetObjectOutput, error) {
|
||||||
_va := make([]interface{}, len(opts))
|
_va := make([]interface{}, len(opts))
|
||||||
@@ -1799,6 +1873,80 @@ func (_c *MockS3Client_PutBucketLifecycleConfiguration_Call) RunAndReturn(run fu
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PutBucketNotificationConfiguration provides a mock function with given fields: ctx, params, opts
|
||||||
|
func (_m *MockS3Client) PutBucketNotificationConfiguration(ctx context.Context, params *s3.PutBucketNotificationConfigurationInput, opts ...func(*s3.Options)) (*s3.PutBucketNotificationConfigurationOutput, error) {
|
||||||
|
_va := make([]interface{}, len(opts))
|
||||||
|
for _i := range opts {
|
||||||
|
_va[_i] = opts[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, params)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for PutBucketNotificationConfiguration")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 *s3.PutBucketNotificationConfigurationOutput
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *s3.PutBucketNotificationConfigurationInput, ...func(*s3.Options)) (*s3.PutBucketNotificationConfigurationOutput, error)); ok {
|
||||||
|
return rf(ctx, params, opts...)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *s3.PutBucketNotificationConfigurationInput, ...func(*s3.Options)) *s3.PutBucketNotificationConfigurationOutput); ok {
|
||||||
|
r0 = rf(ctx, params, opts...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*s3.PutBucketNotificationConfigurationOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, *s3.PutBucketNotificationConfigurationInput, ...func(*s3.Options)) error); ok {
|
||||||
|
r1 = rf(ctx, params, opts...)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockS3Client_PutBucketNotificationConfiguration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PutBucketNotificationConfiguration'
|
||||||
|
type MockS3Client_PutBucketNotificationConfiguration_Call struct {
|
||||||
|
*mock.Call
|
||||||
|
}
|
||||||
|
|
||||||
|
// PutBucketNotificationConfiguration is a helper method to define mock.On call
|
||||||
|
// - ctx context.Context
|
||||||
|
// - params *s3.PutBucketNotificationConfigurationInput
|
||||||
|
// - opts ...func(*s3.Options)
|
||||||
|
func (_e *MockS3Client_Expecter) PutBucketNotificationConfiguration(ctx interface{}, params interface{}, opts ...interface{}) *MockS3Client_PutBucketNotificationConfiguration_Call {
|
||||||
|
return &MockS3Client_PutBucketNotificationConfiguration_Call{Call: _e.mock.On("PutBucketNotificationConfiguration",
|
||||||
|
append([]interface{}{ctx, params}, opts...)...)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockS3Client_PutBucketNotificationConfiguration_Call) Run(run func(ctx context.Context, params *s3.PutBucketNotificationConfigurationInput, opts ...func(*s3.Options))) *MockS3Client_PutBucketNotificationConfiguration_Call {
|
||||||
|
_c.Call.Run(func(args mock.Arguments) {
|
||||||
|
variadicArgs := make([]func(*s3.Options), len(args)-2)
|
||||||
|
for i, a := range args[2:] {
|
||||||
|
if a != nil {
|
||||||
|
variadicArgs[i] = a.(func(*s3.Options))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run(args[0].(context.Context), args[1].(*s3.PutBucketNotificationConfigurationInput), variadicArgs...)
|
||||||
|
})
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockS3Client_PutBucketNotificationConfiguration_Call) Return(_a0 *s3.PutBucketNotificationConfigurationOutput, _a1 error) *MockS3Client_PutBucketNotificationConfiguration_Call {
|
||||||
|
_c.Call.Return(_a0, _a1)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (_c *MockS3Client_PutBucketNotificationConfiguration_Call) RunAndReturn(run func(context.Context, *s3.PutBucketNotificationConfigurationInput, ...func(*s3.Options)) (*s3.PutBucketNotificationConfigurationOutput, error)) *MockS3Client_PutBucketNotificationConfiguration_Call {
|
||||||
|
_c.Call.Return(run)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// PutObject provides a mock function with given fields: ctx, params, opts
|
// PutObject provides a mock function with given fields: ctx, params, opts
|
||||||
func (_m *MockS3Client) PutObject(ctx context.Context, params *s3.PutObjectInput, opts ...func(*s3.Options)) (*s3.PutObjectOutput, error) {
|
func (_m *MockS3Client) PutObject(ctx context.Context, params *s3.PutObjectInput, opts ...func(*s3.Options)) (*s3.PutObjectOutput, error) {
|
||||||
_va := make([]interface{}, len(opts))
|
_va := make([]interface{}, len(opts))
|
||||||
|
|||||||
+21
-15
@@ -21,16 +21,30 @@ tasks:
|
|||||||
up:test:
|
up:test:
|
||||||
cmds:
|
cmds:
|
||||||
- docker compose -f {{.TEST_COMPOSE_FILE}} up --no-recreate -d
|
- docker compose -f {{.TEST_COMPOSE_FILE}} up --no-recreate -d
|
||||||
|
refresh:
|
||||||
|
cmds:
|
||||||
|
- task: down
|
||||||
|
- task: up
|
||||||
up:
|
up:
|
||||||
cmds:
|
cmds:
|
||||||
|
- task docker:build
|
||||||
- docker compose -f {{.LOCAL_COMPOSE_FILE}} up --no-recreate -d
|
- docker compose -f {{.LOCAL_COMPOSE_FILE}} up --no-recreate -d
|
||||||
- task: init
|
- task: init
|
||||||
init:
|
init:
|
||||||
cmds:
|
cmds:
|
||||||
- aws sqs create-queue --queue-name $QNAME_DOCUMENT_CLEAN
|
|
||||||
- aws sqs create-queue --queue-name $QNAME_DOCUMENT_INIT
|
|
||||||
- aws sqs create-queue --queue-name $QNAME_QUERY_RUNNER
|
|
||||||
- aws s3 mb s3://$BUCKET_IN
|
- aws s3 mb s3://$BUCKET_IN
|
||||||
|
- aws sqs create-queue --queue-name $QNAME_DOCUMENT_INIT
|
||||||
|
- |
|
||||||
|
aws s3api put-bucket-notification-configuration \
|
||||||
|
--bucket $BUCKET_IN \
|
||||||
|
--notification-configuration '{
|
||||||
|
"QueueConfigurations": [{
|
||||||
|
"QueueArn": "arn:aws:sqs:us-east-1:000000000000:document_init",
|
||||||
|
"Events": ["s3:ObjectCreated:*"]
|
||||||
|
}]
|
||||||
|
}'
|
||||||
|
- aws sqs create-queue --queue-name $QNAME_DOCUMENT_CLEAN
|
||||||
|
- aws sqs create-queue --queue-name $QNAME_QUERY_RUNNER
|
||||||
down:test:
|
down:test:
|
||||||
cmds:
|
cmds:
|
||||||
- task: down
|
- task: down
|
||||||
@@ -51,15 +65,7 @@ tasks:
|
|||||||
- docker volume rm deployments_db-data
|
- docker volume rm deployments_db-data
|
||||||
lint:
|
lint:
|
||||||
cmds:
|
cmds:
|
||||||
- task: lint:file
|
- docker compose -f {{.LOCAL_COMPOSE_FILE}} config -q
|
||||||
vars:
|
- |
|
||||||
COMPOSE_FILE: '{{.LOCAL_COMPOSE_FILE}}'
|
docker compose -f {{.TEST_COMPOSE_FILE}} config -q \
|
||||||
- task: lint:file
|
--resolve-image-digests
|
||||||
vars:
|
|
||||||
COMPOSE_FILE: '{{.TEST_COMPOSE_FILE}}'
|
|
||||||
lint:file:
|
|
||||||
internal: true
|
|
||||||
vars:
|
|
||||||
COMPOSE_FILE: '{{.COMPOSE_FILE | default .LOCAL_COMPOSE_FILE}}'
|
|
||||||
cmds:
|
|
||||||
- docker compose -f {{.COMPOSE_FILE}} config -q --resolve-image-digests
|
|
||||||
|
|||||||
@@ -32,4 +32,4 @@ tasks:
|
|||||||
deps:
|
deps:
|
||||||
- deps:up
|
- deps:up
|
||||||
cmds:
|
cmds:
|
||||||
- migrate -path {{.MIGRATIONS}} -database {{.DB_URI}} up
|
- migrate -path {{.MIGRATIONS}} -database {{.DB_URI_TEST}} up
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
version: "2"
|
version: "2"
|
||||||
servers:
|
servers:
|
||||||
- engine: postgresql
|
- engine: postgresql
|
||||||
uri: "${DB_URI}"
|
uri: "${DB_URI_TEST}"
|
||||||
sql:
|
sql:
|
||||||
- name: "db"
|
- name: "db"
|
||||||
engine: "postgresql"
|
engine: "postgresql"
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ package integration_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
documentinit "queryorchestration/internal/document/init"
|
|
||||||
"queryorchestration/internal/server/runner"
|
"queryorchestration/internal/server/runner"
|
||||||
"queryorchestration/internal/serviceconfig/objectstore"
|
"queryorchestration/internal/serviceconfig/objectstore"
|
||||||
"queryorchestration/internal/serviceconfig/queue"
|
|
||||||
documentcleanc "queryorchestration/internal/serviceconfig/queue/documentclean"
|
documentcleanc "queryorchestration/internal/serviceconfig/queue/documentclean"
|
||||||
"queryorchestration/internal/test"
|
"queryorchestration/internal/test"
|
||||||
queryservice "queryorchestration/pkg/queryService"
|
queryservice "queryorchestration/pkg/queryService"
|
||||||
@@ -16,6 +15,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
|
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,6 +49,21 @@ func TestDocInitRunner(t *testing.T) {
|
|||||||
doccleanurl := test.CreateQueue(t, ctx, cfg, "docclean")
|
doccleanurl := test.CreateQueue(t, ctx, cfg, "docclean")
|
||||||
bucketName := "docinitbucket"
|
bucketName := "docinitbucket"
|
||||||
test.CreateBucket(t, ctx, cfg, bucketName)
|
test.CreateBucket(t, ctx, cfg, bucketName)
|
||||||
|
arn := fmt.Sprintf("arn:aws:sqs:%s:000000000000:%s", cfg.AWSRegion, test.DocInitRunner)
|
||||||
|
_, err = cfg.StoreClient.PutBucketNotificationConfiguration(ctx, &s3.PutBucketNotificationConfigurationInput{
|
||||||
|
Bucket: &bucketName,
|
||||||
|
NotificationConfiguration: &types.NotificationConfiguration{
|
||||||
|
QueueConfigurations: []types.QueueConfiguration{
|
||||||
|
{
|
||||||
|
QueueArn: &arn,
|
||||||
|
Events: []types.Event{
|
||||||
|
types.EventS3ObjectCreated,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
net, cleanup := test.CreateRunnersAndServicesNetwork(t, ctx, &test.EcosystemNetworkConfig{
|
net, cleanup := test.CreateRunnersAndServicesNetwork(t, ctx, &test.EcosystemNetworkConfig{
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
@@ -91,7 +106,7 @@ func TestDocInitRunner(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
location := "/i/am/here"
|
location := fmt.Sprintf("%s/%s/%s", clientRes.JSON201.Id, jobRes.JSON201.Id, "object_name")
|
||||||
body := strings.NewReader("hello world")
|
body := strings.NewReader("hello world")
|
||||||
_, err = cfg.StoreClient.PutObject(ctx, &s3.PutObjectInput{
|
_, err = cfg.StoreClient.PutObject(ctx, &s3.PutObjectInput{
|
||||||
Bucket: &bucketName,
|
Bucket: &bucketName,
|
||||||
@@ -100,15 +115,6 @@ func TestDocInitRunner(t *testing.T) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = cfg.SendToQueue(ctx, &queue.SendParams{
|
|
||||||
QueueURL: net.Runners[test.DocInitRunner].URI,
|
|
||||||
Body: documentinit.Create{
|
|
||||||
JobID: jobRes.JSON201.Id,
|
|
||||||
Location: location,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
resRegex := regexp.MustCompile(`{"id": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"`)
|
resRegex := regexp.MustCompile(`{"id": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"`)
|
||||||
test.AssertMessageBody(t, ctx, cfg, doccleanurl, resRegex)
|
test.AssertMessageBody(t, ctx, cfg, doccleanurl, resRegex)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user