Compare commits

...

3 Commits

12 changed files with 192 additions and 121 deletions

@ -209,7 +209,7 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/Id"
$ref: "#/components/schemas/OperationID"
default:
description: General Error
content:
@ -520,7 +520,7 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/Id"
$ref: "#/components/schemas/OperationID"
default:
description: General Error
content:
@ -1114,6 +1114,14 @@ components:
ID:
type: integer
format: int64
OperationID:
required:
- OperationID
type: object
properties:
OperationID:
type: integer
format: int32
Roles:
required:
- Roles

@ -142,7 +142,7 @@ type Invoker interface {
// Trigger the validator to create a mapfix.
//
// POST /mapfixes
CreateMapfix(ctx context.Context, request *MapfixTriggerCreate) (*ID, error)
CreateMapfix(ctx context.Context, request *MapfixTriggerCreate) (*OperationID, error)
// CreateScript invokes createScript operation.
//
// Create a new script.
@ -160,7 +160,7 @@ type Invoker interface {
// Trigger the validator to create a new submission.
//
// POST /submissions
CreateSubmission(ctx context.Context, request *SubmissionTriggerCreate) (*ID, error)
CreateSubmission(ctx context.Context, request *SubmissionTriggerCreate) (*OperationID, error)
// DeleteScript invokes deleteScript operation.
//
// Delete the specified script by ID.
@ -2587,12 +2587,12 @@ func (c *Client) sendActionSubmissionValidated(ctx context.Context, params Actio
// Trigger the validator to create a mapfix.
//
// POST /mapfixes
func (c *Client) CreateMapfix(ctx context.Context, request *MapfixTriggerCreate) (*ID, error) {
func (c *Client) CreateMapfix(ctx context.Context, request *MapfixTriggerCreate) (*OperationID, error) {
res, err := c.sendCreateMapfix(ctx, request)
return res, err
}
func (c *Client) sendCreateMapfix(ctx context.Context, request *MapfixTriggerCreate) (res *ID, err error) {
func (c *Client) sendCreateMapfix(ctx context.Context, request *MapfixTriggerCreate) (res *OperationID, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("createMapfix"),
semconv.HTTPRequestMethodKey.String("POST"),
@ -2911,12 +2911,12 @@ func (c *Client) sendCreateScriptPolicy(ctx context.Context, request *ScriptPoli
// Trigger the validator to create a new submission.
//
// POST /submissions
func (c *Client) CreateSubmission(ctx context.Context, request *SubmissionTriggerCreate) (*ID, error) {
func (c *Client) CreateSubmission(ctx context.Context, request *SubmissionTriggerCreate) (*OperationID, error) {
res, err := c.sendCreateSubmission(ctx, request)
return res, err
}
func (c *Client) sendCreateSubmission(ctx context.Context, request *SubmissionTriggerCreate) (res *ID, err error) {
func (c *Client) sendCreateSubmission(ctx context.Context, request *SubmissionTriggerCreate) (res *OperationID, err error) {
otelAttrs := []attribute.KeyValue{
otelogen.OperationID("createSubmission"),
semconv.HTTPRequestMethodKey.String("POST"),

@ -3676,7 +3676,7 @@ func (s *Server) handleCreateMapfixRequest(args [0]string, argsEscaped bool, w h
}
}()
var response *ID
var response *OperationID
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
@ -3691,7 +3691,7 @@ func (s *Server) handleCreateMapfixRequest(args [0]string, argsEscaped bool, w h
type (
Request = *MapfixTriggerCreate
Params = struct{}
Response = *ID
Response = *OperationID
)
response, err = middleware.HookMiddleware[
Request,
@ -4261,7 +4261,7 @@ func (s *Server) handleCreateSubmissionRequest(args [0]string, argsEscaped bool,
}
}()
var response *ID
var response *OperationID
if m := s.cfg.Middleware; m != nil {
mreq := middleware.Request{
Context: ctx,
@ -4276,7 +4276,7 @@ func (s *Server) handleCreateSubmissionRequest(args [0]string, argsEscaped bool,
type (
Request = *SubmissionTriggerCreate
Params = struct{}
Response = *ID
Response = *OperationID
)
response, err = middleware.HookMiddleware[
Request,

@ -981,6 +981,102 @@ func (s *Operation) UnmarshalJSON(data []byte) error {
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *OperationID) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *OperationID) encodeFields(e *jx.Encoder) {
{
e.FieldStart("OperationID")
e.Int32(s.OperationID)
}
}
var jsonFieldsNameOfOperationID = [1]string{
0: "OperationID",
}
// Decode decodes OperationID from json.
func (s *OperationID) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode OperationID to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "OperationID":
requiredBitSet[0] |= 1 << 0
if err := func() error {
v, err := d.Int32()
s.OperationID = int32(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"OperationID\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode OperationID")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000001,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfOperationID) {
name = jsonFieldsNameOfOperationID[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *OperationID) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *OperationID) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode encodes int32 as json.
func (o OptInt32) Encode(e *jx.Encoder) {
if !o.Set {

@ -933,7 +933,7 @@ func decodeActionSubmissionValidatedResponse(resp *http.Response) (res *ActionSu
return res, errors.Wrap(defRes, "error")
}
func decodeCreateMapfixResponse(resp *http.Response) (res *ID, _ error) {
func decodeCreateMapfixResponse(resp *http.Response) (res *OperationID, _ error) {
switch resp.StatusCode {
case 201:
// Code 201.
@ -949,7 +949,7 @@ func decodeCreateMapfixResponse(resp *http.Response) (res *ID, _ error) {
}
d := jx.DecodeBytes(buf)
var response ID
var response OperationID
if err := func() error {
if err := response.Decode(d); err != nil {
return err
@ -1182,7 +1182,7 @@ func decodeCreateScriptPolicyResponse(resp *http.Response) (res *ID, _ error) {
return res, errors.Wrap(defRes, "error")
}
func decodeCreateSubmissionResponse(resp *http.Response) (res *ID, _ error) {
func decodeCreateSubmissionResponse(resp *http.Response) (res *OperationID, _ error) {
switch resp.StatusCode {
case 201:
// Code 201.
@ -1198,7 +1198,7 @@ func decodeCreateSubmissionResponse(resp *http.Response) (res *ID, _ error) {
}
d := jx.DecodeBytes(buf)
var response ID
var response OperationID
if err := func() error {
if err := response.Decode(d); err != nil {
return err

@ -139,7 +139,7 @@ func encodeActionSubmissionValidatedResponse(response *ActionSubmissionValidated
return nil
}
func encodeCreateMapfixResponse(response *ID, w http.ResponseWriter, span trace.Span) error {
func encodeCreateMapfixResponse(response *OperationID, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(201)
span.SetStatus(codes.Ok, http.StatusText(201))
@ -181,7 +181,7 @@ func encodeCreateScriptPolicyResponse(response *ID, w http.ResponseWriter, span
return nil
}
func encodeCreateSubmissionResponse(response *ID, w http.ResponseWriter, span trace.Span) error {
func encodeCreateSubmissionResponse(response *OperationID, w http.ResponseWriter, span trace.Span) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(201)
span.SetStatus(codes.Ok, http.StatusText(201))

@ -455,6 +455,21 @@ func (s *Operation) SetPath(val string) {
s.Path = val
}
// Ref: #/components/schemas/OperationID
type OperationID struct {
OperationID int32 `json:"OperationID"`
}
// GetOperationID returns the value of OperationID.
func (s *OperationID) GetOperationID() int32 {
return s.OperationID
}
// SetOperationID sets the value of OperationID.
func (s *OperationID) SetOperationID(val int32) {
s.OperationID = val
}
// NewOptInt32 returns new OptInt32 with value set to v.
func NewOptInt32(v int32) OptInt32 {
return OptInt32{

@ -121,7 +121,7 @@ type Handler interface {
// Trigger the validator to create a mapfix.
//
// POST /mapfixes
CreateMapfix(ctx context.Context, req *MapfixTriggerCreate) (*ID, error)
CreateMapfix(ctx context.Context, req *MapfixTriggerCreate) (*OperationID, error)
// CreateScript implements createScript operation.
//
// Create a new script.
@ -139,7 +139,7 @@ type Handler interface {
// Trigger the validator to create a new submission.
//
// POST /submissions
CreateSubmission(ctx context.Context, req *SubmissionTriggerCreate) (*ID, error)
CreateSubmission(ctx context.Context, req *SubmissionTriggerCreate) (*OperationID, error)
// DeleteScript implements deleteScript operation.
//
// Delete the specified script by ID.

@ -180,7 +180,7 @@ func (UnimplementedHandler) ActionSubmissionValidated(ctx context.Context, param
// Trigger the validator to create a mapfix.
//
// POST /mapfixes
func (UnimplementedHandler) CreateMapfix(ctx context.Context, req *MapfixTriggerCreate) (r *ID, _ error) {
func (UnimplementedHandler) CreateMapfix(ctx context.Context, req *MapfixTriggerCreate) (r *OperationID, _ error) {
return r, ht.ErrNotImplemented
}
@ -207,7 +207,7 @@ func (UnimplementedHandler) CreateScriptPolicy(ctx context.Context, req *ScriptP
// Trigger the validator to create a new submission.
//
// POST /submissions
func (UnimplementedHandler) CreateSubmission(ctx context.Context, req *SubmissionTriggerCreate) (r *ID, _ error) {
func (UnimplementedHandler) CreateSubmission(ctx context.Context, req *SubmissionTriggerCreate) (r *OperationID, _ error) {
return r, ht.ErrNotImplemented
}

@ -5,6 +5,18 @@ package model
// Requests are sent from maps-service to validator
type CreateSubmissionRequest struct {
// operation_id is passed back in the response message
OperationID int32
ModelID int64
}
type CreateMapfixRequest struct {
OperationID int32
ModelID int64
TargetAssetID int64
}
type ValidateSubmissionRequest struct {
// submission_id is passed back in the response message
SubmissionID int64

@ -46,7 +46,7 @@ var (
)
// POST /mapfixes
func (svc *Service) CreateMapfix(ctx context.Context, request *api.MapfixCreate) (*api.ID, error) {
func (svc *Service) CreateMapfix(ctx context.Context, request *api.MapfixTriggerCreate) (*api.OperationID, error) {
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
if !ok {
return nil, ErrUserInfo
@ -57,59 +57,29 @@ func (svc *Service) CreateMapfix(ctx context.Context, request *api.MapfixCreate)
return nil, err
}
// Check if user's mapfixes in the creation phase exceeds the limit
{
filter := datastore.Optional()
filter.Add("submitter", int64(userId))
filter.Add("status_id", CreationPhaseMapfixStatuses)
creation_mapfixes, err := svc.DB.Mapfixes().List(ctx, filter, model.Page{
Number: 1,
Size: int32(CreationPhaseMapfixesLimit),
},datastore.ListSortDisabled)
if err != nil {
return nil, err
}
if CreationPhaseMapfixesLimit <= len(creation_mapfixes) {
return nil, ErrCreationPhaseMapfixesLimit
}
}
// Check if an active mapfix with the same asset id exists
{
filter := datastore.Optional()
filter.Add("asset_id", request.AssetID)
filter.Add("asset_version", request.AssetVersion)
filter.Add("status_id", ActiveMapfixStatuses)
active_mapfixes, err := svc.DB.Mapfixes().List(ctx, filter, model.Page{
Number: 1,
Size: 1,
},datastore.ListSortDisabled)
if err != nil {
return nil, err
}
if len(active_mapfixes) != 0{
return nil, ErrActiveMapfixSameAssetID
}
}
mapfix, err := svc.DB.Mapfixes().Create(ctx, model.Mapfix{
ID: 0,
DisplayName: request.DisplayName,
Creator: request.Creator,
GameID: request.GameID,
Submitter: int64(userId),
AssetID: request.AssetID,
AssetVersion: request.AssetVersion,
Completed: false,
TargetAssetID: request.TargetAssetID,
StatusID: model.MapfixStatusUnderConstruction,
operation, err := svc.DB.Operations().Create(ctx, model.Operation{
Owner: int64(userId),
StatusID: model.OperationStatusCreated,
})
if err != nil {
return nil, err
}
return &api.ID{
ID: mapfix.ID,
create_request := model.CreateMapfixRequest{
OperationID: operation.ID,
ModelID: request.AssetID,
TargetAssetID: request.TargetAssetID,
}
j, err := json.Marshal(create_request)
if err != nil {
return nil, err
}
svc.Nats.Publish("maptest.mapfixes.create", []byte(j))
return &api.OperationID{
OperationID: operation.ID,
}, nil
}

@ -49,7 +49,7 @@ var (
)
// POST /submissions
func (svc *Service) CreateSubmission(ctx context.Context, request *api.SubmissionCreate) (*api.ID, error) {
func (svc *Service) CreateSubmission(ctx context.Context, request *api.SubmissionTriggerCreate) (*api.OperationID, error) {
userInfo, ok := ctx.Value("UserInfo").(UserInfoHandle)
if !ok {
return nil, ErrUserInfo
@ -60,58 +60,28 @@ func (svc *Service) CreateSubmission(ctx context.Context, request *api.Submissio
return nil, err
}
// Check if user's submissions in the creation phase exceeds the limit
{
filter := datastore.Optional()
filter.Add("submitter", int64(userId))
filter.Add("status_id", CreationPhaseSubmissionStatuses)
creation_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
Number: 1,
Size: int32(CreationPhaseSubmissionsLimit),
},datastore.ListSortDisabled)
if err != nil {
return nil, err
}
if CreationPhaseSubmissionsLimit <= len(creation_submissions) {
return nil, ErrCreationPhaseSubmissionsLimit
}
}
// Check if an active submission with the same asset id exists
{
filter := datastore.Optional()
filter.Add("asset_id", request.AssetID)
filter.Add("asset_version", request.AssetVersion)
filter.Add("status_id", ActiveSubmissionStatuses)
active_submissions, err := svc.DB.Submissions().List(ctx, filter, model.Page{
Number: 1,
Size: 1,
},datastore.ListSortDisabled)
if err != nil {
return nil, err
}
if len(active_submissions) != 0{
return nil, ErrActiveSubmissionSameAssetID
}
}
submission, err := svc.DB.Submissions().Create(ctx, model.Submission{
ID: 0,
DisplayName: request.DisplayName,
Creator: request.Creator,
GameID: request.GameID,
Submitter: int64(userId),
AssetID: request.AssetID,
AssetVersion: request.AssetVersion,
Completed: false,
StatusID: model.SubmissionStatusUnderConstruction,
operation, err := svc.DB.Operations().Create(ctx, model.Operation{
Owner: int64(userId),
StatusID: model.OperationStatusCreated,
})
if err != nil {
return nil, err
}
return &api.ID{
ID: submission.ID,
create_request := model.CreateSubmissionRequest{
OperationID: operation.ID,
ModelID: request.AssetID,
}
j, err := json.Marshal(create_request)
if err != nil {
return nil, err
}
svc.Nats.Publish("maptest.submissions.create", []byte(j))
return &api.OperationID{
OperationID: operation.ID,
}, nil
}