diff --git a/pkg/datastore/datastore.go b/pkg/datastore/datastore.go index f85ab47..69a848e 100644 --- a/pkg/datastore/datastore.go +++ b/pkg/datastore/datastore.go @@ -22,6 +22,7 @@ type Submissions interface { Create(ctx context.Context, smap model.Submission) (model.Submission, error) Update(ctx context.Context, id int64, values OptionalMap) error IfStatusThenUpdate(ctx context.Context, id int64, statuses []model.Status, values OptionalMap) error + IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.Status, values OptionalMap) (model.Submission, error) Delete(ctx context.Context, id int64) error List(ctx context.Context, filters OptionalMap, page model.Page) ([]model.Submission, error) } diff --git a/pkg/datastore/gormstore/submissions.go b/pkg/datastore/gormstore/submissions.go index bfcee3f..a380729 100644 --- a/pkg/datastore/gormstore/submissions.go +++ b/pkg/datastore/gormstore/submissions.go @@ -63,6 +63,20 @@ func (env *Submissions) IfStatusThenUpdate(ctx context.Context, id int64, status return nil } +// the update can only occur if the status matches one of the provided values. +// returns the updated value +func (env *Submissions) IfStatusThenUpdateAndGet(ctx context.Context, id int64, statuses []model.Status, values datastore.OptionalMap) (model.Submission, error) { + var submission model.Submission + if err := env.db.First(&submission, id).Where("status_id IN ?",statuses).Updates(values.Map()).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return submission, datastore.ErrNotExist + } + return submission, err + } + + return submission, nil +} + func (env *Submissions) Delete(ctx context.Context, id int64) error { if err := env.db.Delete(&model.Submission{}, id).Error; err != nil { if err == gorm.ErrRecordNotFound { diff --git a/pkg/model/nats.go b/pkg/model/nats.go new file mode 100644 index 0000000..3c7a257 --- /dev/null +++ b/pkg/model/nats.go @@ -0,0 +1,31 @@ +package model + +// These represent the information needed in the nats message +// to perform the operation, they are encoded to json + +// Requests are sent from maps-service to validator + +type ValidateRequest struct{ + // submission_id is passed back in the response message + SubmissionID int64 + ModelID uint64 + ModelVersion uint64 + ValidatedModelID uint64 // optional value +} + +// Create a new map +type PublishNewRequest struct{ + SubmissionID int64 + ModelID uint64 + ModelVersion uint64 + Creator string + DisplayName string + //games HashSet +} + +type PublishFixRequest struct{ + SubmissionID int64 + ModelID uint64 + ModelVersion uint64 + TargetAssetID uint64 +} diff --git a/pkg/service/submissions.go b/pkg/service/submissions.go index 160fe46..f0b382e 100644 --- a/pkg/service/submissions.go +++ b/pkg/service/submissions.go @@ -1,11 +1,13 @@ package service import ( - "errors" "context" + "encoding/json" + "errors" + "git.itzana.me/strafesnet/maps-service/pkg/api" - "git.itzana.me/strafesnet/maps-service/pkg/model" "git.itzana.me/strafesnet/maps-service/pkg/datastore" + "git.itzana.me/strafesnet/maps-service/pkg/model" ) var ( @@ -298,7 +300,46 @@ func (svc *Service) ActionSubmissionTriggerPublish(ctx context.Context, params a // transaction smap := datastore.Optional() smap.Add("status_id",model.StatusPublishing) - return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusValidated}, smap) + submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusValidated}, smap) + if err != nil{ + return err + } + + // sentinel value because we are not using rust + if submission.TargetAssetID == 0{ + // this is a new map + publish_new_request := model.PublishNewRequest{ + SubmissionID: submission.ID, + ModelID: submission.AssetID, + ModelVersion: submission.AssetVersion, + Creator: submission.Creator, + DisplayName: submission.DisplayName, + } + + j, err := json.Marshal(publish_new_request) + if err != nil{ + return err + } + + svc.Nats.Publish("publish_new", []byte(j)) + }else{ + // this is a map fix + publish_fix_request := model.PublishFixRequest{ + SubmissionID: submission.ID, + ModelID: submission.AssetID, + ModelVersion: submission.AssetVersion, + TargetAssetID: submission.TargetAssetID, + } + + j, err := json.Marshal(publish_fix_request) + if err != nil{ + return err + } + + svc.Nats.Publish("publish_fix", []byte(j)) + } + + return nil } // ActionSubmissionTriggerValidate invokes actionSubmissionTriggerValidate operation. // @@ -319,7 +360,26 @@ func (svc *Service) ActionSubmissionTriggerValidate(ctx context.Context, params // transaction smap := datastore.Optional() smap.Add("status_id",model.StatusValidating) - return svc.DB.Submissions().IfStatusThenUpdate(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted,model.StatusAccepted}, smap) + submission, err := svc.DB.Submissions().IfStatusThenUpdateAndGet(ctx, params.SubmissionID, []model.Status{model.StatusSubmitted,model.StatusAccepted}, smap) + if err != nil{ + return err + } + + validate_request := model.ValidateRequest{ + SubmissionID: submission.ID, + ModelID: submission.AssetID, + ModelVersion: submission.AssetVersion, + ValidatedModelID: 0, //TODO: reuse velidation models + } + + j, err := json.Marshal(validate_request) + if err != nil{ + return err + } + + svc.Nats.Publish("validate", []byte(j)) + + return nil } // ActionSubmissionValidate invokes actionSubmissionValidate operation. //