package docinitrunner import ( "context" "encoding/json" "log/slog" "queryorchestration/internal/document" documentinit "queryorchestration/internal/document/init" "github.com/go-playground/validator/v10" "github.com/aws/aws-sdk-go-v2/service/sqs/types" ) const Name = "docInitRunner" type Services struct { Document *documentinit.Service } type Runner struct { validator *validator.Validate svc *Services } func New(validator *validator.Validate, svc *Services) Runner { return Runner{ validator: validator, svc: svc, } } type S3Bucket struct { Name string `json:"name"` Arn string `json:"arn"` } type S3Object struct { Key string `json:"key"` Size int64 `json:"size"` ETag string `json:"eTag"` VersionId string `json:"versionId"` } type S3EventRecordDetails struct { Bucket S3Bucket `json:"bucket"` Object S3Object `json:"object"` } type S3EventRecord struct { EventVersion string `json:"eventVersion"` EventSource string `json:"eventSource"` AwsRegion string `json:"awsRegion"` EventTime string `json:"eventTime"` EventName EventS3 `json:"eventName"` S3 S3EventRecordDetails `json:"s3"` } type S3EventNotification struct { Records []S3EventRecord `json:"Records"` } type EventS3 string const ( EventS3ObjectCreatedPut = "ObjectCreated:Put" ) func (s Runner) Process(ctx context.Context, req *types.Message) bool { var body S3EventNotification err := json.Unmarshal([]byte(*req.Body), &body) if err != nil { slog.Error("parsing body", "messageId", *req.MessageId, "body", *req.Body) return true } err = s.validator.Struct(body) if err != nil { slog.Error("invalid body", "messageId", *req.MessageId, "error", err) return true } for _, record := range body.Records { err := s.processRecord(ctx, record) if err != nil { slog.Error("unable to process", "error", err) return false } } return true } func (s Runner) processRecord(ctx context.Context, record S3EventRecord) error { if !s.isSupportedEvent(record.EventName) { slog.Warn("unsupported event", "name", record.EventName) return nil } clientID, err := s.svc.Document.GetClientIDFromKey(record.S3.Object.Key) if err != nil { slog.Error("unable to find client id", "key", record.S3.Object.Key, "error", err) return nil } _, err = s.svc.Document.Create(ctx, &documentinit.Create{ ClientID: clientID, Location: document.Location{ Bucket: record.S3.Bucket.Name, Key: record.S3.Object.Key, }, Hash: record.S3.Object.ETag, }) if err != nil { return err } return nil } func (s Runner) isSupportedEvent(name EventS3) bool { return name == EventS3ObjectCreatedPut }