diff --git a/pkg/api/oas_client_gen.go b/pkg/api/oas_client_gen.go index 92d61ba..a9df2dd 100644 --- a/pkg/api/oas_client_gen.go +++ b/pkg/api/oas_client_gen.go @@ -72,12 +72,54 @@ type Invoker interface { // // PATCH /submissions/{SubmissionID}/status/validate ActionSubmissionValidate(ctx context.Context, params ActionSubmissionValidateParams) error + // CreateScript invokes createScript operation. + // + // Create a new script. + // + // POST /scripts + CreateScript(ctx context.Context, request OptScriptCreate) (*ID, error) + // CreateScriptPolicy invokes createScriptPolicy operation. + // + // Create a new script policy. + // + // POST /script-policy + CreateScriptPolicy(ctx context.Context, request OptScriptPolicyCreate) (*ID, error) // CreateSubmission invokes createSubmission operation. // // Create new submission. // // POST /submissions CreateSubmission(ctx context.Context, request OptSubmissionCreate) (*ID, error) + // DeleteScript invokes deleteScript operation. + // + // Delete the specified script by ID. + // + // DELETE /scripts/{ScriptID} + DeleteScript(ctx context.Context, params DeleteScriptParams) error + // DeleteScriptPolicy invokes deleteScriptPolicy operation. + // + // Delete the specified script policy by ID. + // + // DELETE /script-policy/id/{ScriptPolicyID} + DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error + // GetScript invokes getScript operation. + // + // Get the specified script by ID. + // + // GET /scripts/{ScriptID} + GetScript(ctx context.Context, params GetScriptParams) (*Script, error) + // GetScriptPolicy invokes getScriptPolicy operation. + // + // Get the specified script policy by ID. + // + // GET /script-policy/id/{ScriptPolicyID} + GetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (*ScriptPolicy, error) + // GetScriptPolicyFromHash invokes getScriptPolicyFromHash operation. + // + // Get the policy for the given hash of script source code. + // + // GET /script-policy/hash/{FromScriptHash} + GetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (*ScriptPolicy, error) // GetSubmission invokes getSubmission operation. // // Retrieve map with ID. @@ -102,6 +144,18 @@ type Invoker interface { // // PATCH /submissions/{SubmissionID}/model PatchSubmissionModel(ctx context.Context, params PatchSubmissionModelParams) error + // UpdateScript invokes updateScript operation. + // + // Update the specified script by ID. + // + // PATCH /scripts/{ScriptID} + UpdateScript(ctx context.Context, request OptScriptUpdate, params UpdateScriptParams) error + // UpdateScriptPolicy invokes updateScriptPolicy operation. + // + // Update the specified script policy by ID. + // + // PATCH /script-policy/id/{ScriptPolicyID} + UpdateScriptPolicy(ctx context.Context, request OptScriptPolicyUpdate, params UpdateScriptPolicyParams) error } // Client implements OAS client. @@ -180,7 +234,7 @@ func (c *Client) sendActionSubmissionPublish(ctx context.Context, params ActionS defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -304,7 +358,7 @@ func (c *Client) sendActionSubmissionReject(ctx context.Context, params ActionSu defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -428,7 +482,7 @@ func (c *Client) sendActionSubmissionRequestChanges(ctx context.Context, params defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -552,7 +606,7 @@ func (c *Client) sendActionSubmissionRevoke(ctx context.Context, params ActionSu defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -676,7 +730,7 @@ func (c *Client) sendActionSubmissionSubmit(ctx context.Context, params ActionSu defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -800,7 +854,7 @@ func (c *Client) sendActionSubmissionTriggerPublish(ctx context.Context, params defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -924,7 +978,7 @@ func (c *Client) sendActionSubmissionTriggerValidate(ctx context.Context, params defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -1048,7 +1102,7 @@ func (c *Client) sendActionSubmissionValidate(ctx context.Context, params Action defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -1150,6 +1204,222 @@ func (c *Client) sendActionSubmissionValidate(ctx context.Context, params Action return result, nil } +// CreateScript invokes createScript operation. +// +// Create a new script. +// +// POST /scripts +func (c *Client) CreateScript(ctx context.Context, request OptScriptCreate) (*ID, error) { + res, err := c.sendCreateScript(ctx, request) + return res, err +} + +func (c *Client) sendCreateScript(ctx context.Context, request OptScriptCreate) (res *ID, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("createScript"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/scripts"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, CreateScriptOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/scripts" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeCreateScriptRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, CreateScriptOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeCreateScriptResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// CreateScriptPolicy invokes createScriptPolicy operation. +// +// Create a new script policy. +// +// POST /script-policy +func (c *Client) CreateScriptPolicy(ctx context.Context, request OptScriptPolicyCreate) (*ID, error) { + res, err := c.sendCreateScriptPolicy(ctx, request) + return res, err +} + +func (c *Client) sendCreateScriptPolicy(ctx context.Context, request OptScriptPolicyCreate) (res *ID, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("createScriptPolicy"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/script-policy"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, CreateScriptPolicyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/script-policy" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeCreateScriptPolicyRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, CreateScriptPolicyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeCreateScriptPolicyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + // CreateSubmission invokes createSubmission operation. // // Create new submission. @@ -1172,7 +1442,7 @@ func (c *Client) sendCreateSubmission(ctx context.Context, request OptSubmission defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -1258,6 +1528,621 @@ func (c *Client) sendCreateSubmission(ctx context.Context, request OptSubmission return result, nil } +// DeleteScript invokes deleteScript operation. +// +// Delete the specified script by ID. +// +// DELETE /scripts/{ScriptID} +func (c *Client) DeleteScript(ctx context.Context, params DeleteScriptParams) error { + _, err := c.sendDeleteScript(ctx, params) + return err +} + +func (c *Client) sendDeleteScript(ctx context.Context, params DeleteScriptParams) (res *DeleteScriptOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("deleteScript"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.HTTPRouteKey.String("/scripts/{ScriptID}"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, DeleteScriptOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/scripts/" + { + // Encode "ScriptID" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "ScriptID", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Int64ToString(params.ScriptID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "DELETE", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, DeleteScriptOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeDeleteScriptResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// DeleteScriptPolicy invokes deleteScriptPolicy operation. +// +// Delete the specified script policy by ID. +// +// DELETE /script-policy/id/{ScriptPolicyID} +func (c *Client) DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error { + _, err := c.sendDeleteScriptPolicy(ctx, params) + return err +} + +func (c *Client) sendDeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) (res *DeleteScriptPolicyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("deleteScriptPolicy"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, DeleteScriptPolicyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/script-policy/id/" + { + // Encode "ScriptPolicyID" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "ScriptPolicyID", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Int64ToString(params.ScriptPolicyID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "DELETE", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, DeleteScriptPolicyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeDeleteScriptPolicyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// GetScript invokes getScript operation. +// +// Get the specified script by ID. +// +// GET /scripts/{ScriptID} +func (c *Client) GetScript(ctx context.Context, params GetScriptParams) (*Script, error) { + res, err := c.sendGetScript(ctx, params) + return res, err +} + +func (c *Client) sendGetScript(ctx context.Context, params GetScriptParams) (res *Script, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("getScript"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/scripts/{ScriptID}"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, GetScriptOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/scripts/" + { + // Encode "ScriptID" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "ScriptID", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Int64ToString(params.ScriptID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, GetScriptOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeGetScriptResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// GetScriptPolicy invokes getScriptPolicy operation. +// +// Get the specified script policy by ID. +// +// GET /script-policy/id/{ScriptPolicyID} +func (c *Client) GetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (*ScriptPolicy, error) { + res, err := c.sendGetScriptPolicy(ctx, params) + return res, err +} + +func (c *Client) sendGetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (res *ScriptPolicy, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("getScriptPolicy"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, GetScriptPolicyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/script-policy/id/" + { + // Encode "ScriptPolicyID" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "ScriptPolicyID", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Int64ToString(params.ScriptPolicyID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, GetScriptPolicyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeGetScriptPolicyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// GetScriptPolicyFromHash invokes getScriptPolicyFromHash operation. +// +// Get the policy for the given hash of script source code. +// +// GET /script-policy/hash/{FromScriptHash} +func (c *Client) GetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (*ScriptPolicy, error) { + res, err := c.sendGetScriptPolicyFromHash(ctx, params) + return res, err +} + +func (c *Client) sendGetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (res *ScriptPolicy, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("getScriptPolicyFromHash"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/script-policy/hash/{FromScriptHash}"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, GetScriptPolicyFromHashOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/script-policy/hash/" + { + // Encode "FromScriptHash" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "FromScriptHash", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.StringToString(params.FromScriptHash)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, GetScriptPolicyFromHashOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeGetScriptPolicyFromHashResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + // GetSubmission invokes getSubmission operation. // // Retrieve map with ID. @@ -1280,7 +2165,7 @@ func (c *Client) sendGetSubmission(ctx context.Context, params GetSubmissionPara defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -1403,7 +2288,7 @@ func (c *Client) sendListSubmissions(ctx context.Context, params ListSubmissions defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -1543,7 +2428,7 @@ func (c *Client) sendPatchSubmissionCompleted(ctx context.Context, params PatchS defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -1667,7 +2552,7 @@ func (c *Client) sendPatchSubmissionModel(ctx context.Context, params PatchSubmi defer func() { // Use floating point division here for higher precision (instead of Millisecond method). elapsedDuration := time.Since(startTime) - c.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), metric.WithAttributes(otelAttrs...)) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) }() // Increment request counter. @@ -1800,3 +2685,255 @@ func (c *Client) sendPatchSubmissionModel(ctx context.Context, params PatchSubmi return result, nil } + +// UpdateScript invokes updateScript operation. +// +// Update the specified script by ID. +// +// PATCH /scripts/{ScriptID} +func (c *Client) UpdateScript(ctx context.Context, request OptScriptUpdate, params UpdateScriptParams) error { + _, err := c.sendUpdateScript(ctx, request, params) + return err +} + +func (c *Client) sendUpdateScript(ctx context.Context, request OptScriptUpdate, params UpdateScriptParams) (res *UpdateScriptOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("updateScript"), + semconv.HTTPRequestMethodKey.String("PATCH"), + semconv.HTTPRouteKey.String("/scripts/{ScriptID}"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, UpdateScriptOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/scripts/" + { + // Encode "ScriptID" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "ScriptID", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Int64ToString(params.ScriptID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "PATCH", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeUpdateScriptRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, UpdateScriptOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeUpdateScriptResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// UpdateScriptPolicy invokes updateScriptPolicy operation. +// +// Update the specified script policy by ID. +// +// PATCH /script-policy/id/{ScriptPolicyID} +func (c *Client) UpdateScriptPolicy(ctx context.Context, request OptScriptPolicyUpdate, params UpdateScriptPolicyParams) error { + _, err := c.sendUpdateScriptPolicy(ctx, request, params) + return err +} + +func (c *Client) sendUpdateScriptPolicy(ctx context.Context, request OptScriptPolicyUpdate, params UpdateScriptPolicyParams) (res *UpdateScriptPolicyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("updateScriptPolicy"), + semconv.HTTPRequestMethodKey.String("PATCH"), + semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"), + } + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, UpdateScriptPolicyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/script-policy/id/" + { + // Encode "ScriptPolicyID" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "ScriptPolicyID", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Int64ToString(params.ScriptPolicyID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "PATCH", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeUpdateScriptPolicyRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:CookieAuth" + switch err := c.securityCookieAuth(ctx, UpdateScriptPolicyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"CookieAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + defer resp.Body.Close() + + stage = "DecodeResponse" + result, err := decodeUpdateScriptPolicyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} diff --git a/pkg/api/oas_handlers_gen.go b/pkg/api/oas_handlers_gen.go index 402bfb8..760ced5 100644 --- a/pkg/api/oas_handlers_gen.go +++ b/pkg/api/oas_handlers_gen.go @@ -20,12 +20,24 @@ import ( "github.com/ogen-go/ogen/otelogen" ) +type codeRecorder struct { + http.ResponseWriter + status int +} + +func (c *codeRecorder) WriteHeader(status int) { + c.status = status + c.ResponseWriter.WriteHeader(status) +} + // handleActionSubmissionPublishRequest handles actionSubmissionPublish operation. // // Role Validator changes status from Publishing -> Published. // // PATCH /submissions/{SubmissionID}/status/publish func (s *Server) handleActionSubmissionPublishRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionPublish"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -47,20 +59,44 @@ func (s *Server) handleActionSubmissionPublishRequest(args [1]string, argsEscape startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -195,6 +231,8 @@ func (s *Server) handleActionSubmissionPublishRequest(args [1]string, argsEscape // // PATCH /submissions/{SubmissionID}/status/reject func (s *Server) handleActionSubmissionRejectRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionReject"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -216,20 +254,44 @@ func (s *Server) handleActionSubmissionRejectRequest(args [1]string, argsEscaped startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -364,6 +426,8 @@ func (s *Server) handleActionSubmissionRejectRequest(args [1]string, argsEscaped // // PATCH /submissions/{SubmissionID}/status/request-changes func (s *Server) handleActionSubmissionRequestChangesRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionRequestChanges"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -385,20 +449,44 @@ func (s *Server) handleActionSubmissionRequestChangesRequest(args [1]string, arg startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -533,6 +621,8 @@ func (s *Server) handleActionSubmissionRequestChangesRequest(args [1]string, arg // // PATCH /submissions/{SubmissionID}/status/revoke func (s *Server) handleActionSubmissionRevokeRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionRevoke"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -554,20 +644,44 @@ func (s *Server) handleActionSubmissionRevokeRequest(args [1]string, argsEscaped startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -702,6 +816,8 @@ func (s *Server) handleActionSubmissionRevokeRequest(args [1]string, argsEscaped // // PATCH /submissions/{SubmissionID}/status/submit func (s *Server) handleActionSubmissionSubmitRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionSubmit"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -723,20 +839,44 @@ func (s *Server) handleActionSubmissionSubmitRequest(args [1]string, argsEscaped startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -871,6 +1011,8 @@ func (s *Server) handleActionSubmissionSubmitRequest(args [1]string, argsEscaped // // PATCH /submissions/{SubmissionID}/status/trigger-publish func (s *Server) handleActionSubmissionTriggerPublishRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionTriggerPublish"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -892,20 +1034,44 @@ func (s *Server) handleActionSubmissionTriggerPublishRequest(args [1]string, arg startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -1040,6 +1206,8 @@ func (s *Server) handleActionSubmissionTriggerPublishRequest(args [1]string, arg // // PATCH /submissions/{SubmissionID}/status/trigger-validate func (s *Server) handleActionSubmissionTriggerValidateRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionTriggerValidate"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -1061,20 +1229,44 @@ func (s *Server) handleActionSubmissionTriggerValidateRequest(args [1]string, ar startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -1209,6 +1401,8 @@ func (s *Server) handleActionSubmissionTriggerValidateRequest(args [1]string, ar // // PATCH /submissions/{SubmissionID}/status/validate func (s *Server) handleActionSubmissionValidateRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionValidate"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -1230,20 +1424,44 @@ func (s *Server) handleActionSubmissionValidateRequest(args [1]string, argsEscap startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -1372,12 +1590,404 @@ func (s *Server) handleActionSubmissionValidateRequest(args [1]string, argsEscap } } +// handleCreateScriptRequest handles createScript operation. +// +// Create a new script. +// +// POST /scripts +func (s *Server) handleCreateScriptRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("createScript"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/scripts"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), CreateScriptOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: CreateScriptOperation, + ID: "createScript", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, CreateScriptOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + request, close, err := s.decodeCreateScriptRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *ID + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: CreateScriptOperation, + OperationSummary: "Create a new script", + OperationID: "createScript", + Body: request, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = OptScriptCreate + Params = struct{} + Response = *ID + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.CreateScript(ctx, request) + return response, err + }, + ) + } else { + response, err = s.h.CreateScript(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeCreateScriptResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleCreateScriptPolicyRequest handles createScriptPolicy operation. +// +// Create a new script policy. +// +// POST /script-policy +func (s *Server) handleCreateScriptPolicyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("createScriptPolicy"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/script-policy"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), CreateScriptPolicyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: CreateScriptPolicyOperation, + ID: "createScriptPolicy", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, CreateScriptPolicyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + request, close, err := s.decodeCreateScriptPolicyRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *ID + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: CreateScriptPolicyOperation, + OperationSummary: "Create a new script policy", + OperationID: "createScriptPolicy", + Body: request, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = OptScriptPolicyCreate + Params = struct{} + Response = *ID + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.CreateScriptPolicy(ctx, request) + return response, err + }, + ) + } else { + response, err = s.h.CreateScriptPolicy(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeCreateScriptPolicyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + // handleCreateSubmissionRequest handles createSubmission operation. // // Create new submission. // // POST /submissions func (s *Server) handleCreateSubmissionRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("createSubmission"), semconv.HTTPRequestMethodKey.String("POST"), @@ -1399,20 +2009,44 @@ func (s *Server) handleCreateSubmissionRequest(args [0]string, argsEscaped bool, startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -1541,12 +2175,989 @@ func (s *Server) handleCreateSubmissionRequest(args [0]string, argsEscaped bool, } } +// handleDeleteScriptRequest handles deleteScript operation. +// +// Delete the specified script by ID. +// +// DELETE /scripts/{ScriptID} +func (s *Server) handleDeleteScriptRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("deleteScript"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.HTTPRouteKey.String("/scripts/{ScriptID}"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), DeleteScriptOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: DeleteScriptOperation, + ID: "deleteScript", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, DeleteScriptOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeDeleteScriptParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var response *DeleteScriptOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: DeleteScriptOperation, + OperationSummary: "Delete the specified script by ID", + OperationID: "deleteScript", + Body: nil, + Params: middleware.Parameters{ + { + Name: "ScriptID", + In: "path", + }: params.ScriptID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = DeleteScriptParams + Response = *DeleteScriptOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackDeleteScriptParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.DeleteScript(ctx, params) + return response, err + }, + ) + } else { + err = s.h.DeleteScript(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeDeleteScriptResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleDeleteScriptPolicyRequest handles deleteScriptPolicy operation. +// +// Delete the specified script policy by ID. +// +// DELETE /script-policy/id/{ScriptPolicyID} +func (s *Server) handleDeleteScriptPolicyRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("deleteScriptPolicy"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), DeleteScriptPolicyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: DeleteScriptPolicyOperation, + ID: "deleteScriptPolicy", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, DeleteScriptPolicyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeDeleteScriptPolicyParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var response *DeleteScriptPolicyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: DeleteScriptPolicyOperation, + OperationSummary: "Delete the specified script policy by ID", + OperationID: "deleteScriptPolicy", + Body: nil, + Params: middleware.Parameters{ + { + Name: "ScriptPolicyID", + In: "path", + }: params.ScriptPolicyID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = DeleteScriptPolicyParams + Response = *DeleteScriptPolicyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackDeleteScriptPolicyParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.DeleteScriptPolicy(ctx, params) + return response, err + }, + ) + } else { + err = s.h.DeleteScriptPolicy(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeDeleteScriptPolicyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleGetScriptRequest handles getScript operation. +// +// Get the specified script by ID. +// +// GET /scripts/{ScriptID} +func (s *Server) handleGetScriptRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("getScript"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/scripts/{ScriptID}"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), GetScriptOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: GetScriptOperation, + ID: "getScript", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, GetScriptOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeGetScriptParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var response *Script + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: GetScriptOperation, + OperationSummary: "Get the specified script by ID", + OperationID: "getScript", + Body: nil, + Params: middleware.Parameters{ + { + Name: "ScriptID", + In: "path", + }: params.ScriptID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = GetScriptParams + Response = *Script + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackGetScriptParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.GetScript(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.GetScript(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeGetScriptResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleGetScriptPolicyRequest handles getScriptPolicy operation. +// +// Get the specified script policy by ID. +// +// GET /script-policy/id/{ScriptPolicyID} +func (s *Server) handleGetScriptPolicyRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("getScriptPolicy"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), GetScriptPolicyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: GetScriptPolicyOperation, + ID: "getScriptPolicy", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, GetScriptPolicyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeGetScriptPolicyParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var response *ScriptPolicy + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: GetScriptPolicyOperation, + OperationSummary: "Get the specified script policy by ID", + OperationID: "getScriptPolicy", + Body: nil, + Params: middleware.Parameters{ + { + Name: "ScriptPolicyID", + In: "path", + }: params.ScriptPolicyID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = GetScriptPolicyParams + Response = *ScriptPolicy + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackGetScriptPolicyParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.GetScriptPolicy(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.GetScriptPolicy(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeGetScriptPolicyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleGetScriptPolicyFromHashRequest handles getScriptPolicyFromHash operation. +// +// Get the policy for the given hash of script source code. +// +// GET /script-policy/hash/{FromScriptHash} +func (s *Server) handleGetScriptPolicyFromHashRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("getScriptPolicyFromHash"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/script-policy/hash/{FromScriptHash}"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), GetScriptPolicyFromHashOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: GetScriptPolicyFromHashOperation, + ID: "getScriptPolicyFromHash", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, GetScriptPolicyFromHashOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeGetScriptPolicyFromHashParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var response *ScriptPolicy + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: GetScriptPolicyFromHashOperation, + OperationSummary: "Get the policy for the given hash of script source code", + OperationID: "getScriptPolicyFromHash", + Body: nil, + Params: middleware.Parameters{ + { + Name: "FromScriptHash", + In: "path", + }: params.FromScriptHash, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = GetScriptPolicyFromHashParams + Response = *ScriptPolicy + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackGetScriptPolicyFromHashParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.GetScriptPolicyFromHash(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.GetScriptPolicyFromHash(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeGetScriptPolicyFromHashResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + // handleGetSubmissionRequest handles getSubmission operation. // // Retrieve map with ID. // // GET /submissions/{SubmissionID} func (s *Server) handleGetSubmissionRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("getSubmission"), semconv.HTTPRequestMethodKey.String("GET"), @@ -1568,20 +3179,44 @@ func (s *Server) handleGetSubmissionRequest(args [1]string, argsEscaped bool, w startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -1716,6 +3351,8 @@ func (s *Server) handleGetSubmissionRequest(args [1]string, argsEscaped bool, w // // GET /submissions func (s *Server) handleListSubmissionsRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("listSubmissions"), semconv.HTTPRequestMethodKey.String("GET"), @@ -1737,20 +3374,44 @@ func (s *Server) handleListSubmissionsRequest(args [0]string, argsEscaped bool, startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -1889,6 +3550,8 @@ func (s *Server) handleListSubmissionsRequest(args [0]string, argsEscaped bool, // // PATCH /submissions/{SubmissionID}/completed func (s *Server) handlePatchSubmissionCompletedRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("patchSubmissionCompleted"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -1910,20 +3573,44 @@ func (s *Server) handlePatchSubmissionCompletedRequest(args [1]string, argsEscap startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -2058,6 +3745,8 @@ func (s *Server) handlePatchSubmissionCompletedRequest(args [1]string, argsEscap // // PATCH /submissions/{SubmissionID}/model func (s *Server) handlePatchSubmissionModelRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("patchSubmissionModel"), semconv.HTTPRequestMethodKey.String("PATCH"), @@ -2079,20 +3768,44 @@ func (s *Server) handlePatchSubmissionModelRequest(args [1]string, argsEscaped b startTime := time.Now() defer func() { elapsedDuration := time.Since(startTime) - attrOpt := metric.WithAttributeSet(labeler.AttributeSet()) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) // Increment request counter. s.requests.Add(ctx, 1, attrOpt) // Use floating point division here for higher precision (instead of Millisecond method). - s.duration.Record(ctx, float64(float64(elapsedDuration)/float64(time.Millisecond)), attrOpt) + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) }() var ( recordError = func(stage string, err error) { span.RecordError(err) - span.SetStatus(codes.Error, stage) - s.errors.Add(ctx, 1, metric.WithAttributeSet(labeler.AttributeSet())) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) } err error opErrContext = ogenerrors.OperationContext{ @@ -2228,3 +3941,423 @@ func (s *Server) handlePatchSubmissionModelRequest(args [1]string, argsEscaped b return } } + +// handleUpdateScriptRequest handles updateScript operation. +// +// Update the specified script by ID. +// +// PATCH /scripts/{ScriptID} +func (s *Server) handleUpdateScriptRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("updateScript"), + semconv.HTTPRequestMethodKey.String("PATCH"), + semconv.HTTPRouteKey.String("/scripts/{ScriptID}"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), UpdateScriptOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: UpdateScriptOperation, + ID: "updateScript", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, UpdateScriptOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeUpdateScriptParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + request, close, err := s.decodeUpdateScriptRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *UpdateScriptOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: UpdateScriptOperation, + OperationSummary: "Update the specified script by ID", + OperationID: "updateScript", + Body: request, + Params: middleware.Parameters{ + { + Name: "ScriptID", + In: "path", + }: params.ScriptID, + }, + Raw: r, + } + + type ( + Request = OptScriptUpdate + Params = UpdateScriptParams + Response = *UpdateScriptOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackUpdateScriptParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.UpdateScript(ctx, request, params) + return response, err + }, + ) + } else { + err = s.h.UpdateScript(ctx, request, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeUpdateScriptResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleUpdateScriptPolicyRequest handles updateScriptPolicy operation. +// +// Update the specified script policy by ID. +// +// PATCH /script-policy/id/{ScriptPolicyID} +func (s *Server) handleUpdateScriptPolicyRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("updateScriptPolicy"), + semconv.HTTPRequestMethodKey.String("PATCH"), + semconv.HTTPRouteKey.String("/script-policy/id/{ScriptPolicyID}"), + } + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), UpdateScriptPolicyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(codeAttr) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code >= 100 && code < 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: UpdateScriptPolicyOperation, + ID: "updateScriptPolicy", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityCookieAuth(ctx, UpdateScriptPolicyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "CookieAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:CookieAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeUpdateScriptPolicyParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + request, close, err := s.decodeUpdateScriptPolicyRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *UpdateScriptPolicyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: UpdateScriptPolicyOperation, + OperationSummary: "Update the specified script policy by ID", + OperationID: "updateScriptPolicy", + Body: request, + Params: middleware.Parameters{ + { + Name: "ScriptPolicyID", + In: "path", + }: params.ScriptPolicyID, + }, + Raw: r, + } + + type ( + Request = OptScriptPolicyUpdate + Params = UpdateScriptPolicyParams + Response = *UpdateScriptPolicyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackUpdateScriptPolicyParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.UpdateScriptPolicy(ctx, request, params) + return response, err + }, + ) + } else { + err = s.h.UpdateScriptPolicy(ctx, request, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeUpdateScriptPolicyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} diff --git a/pkg/api/oas_json_gen.go b/pkg/api/oas_json_gen.go index 67e5033..4b8cf80 100644 --- a/pkg/api/oas_json_gen.go +++ b/pkg/api/oas_json_gen.go @@ -135,10 +135,8 @@ func (s *ID) Encode(e *jx.Encoder) { // encodeFields encodes fields. func (s *ID) encodeFields(e *jx.Encoder) { { - if s.ID.Set { - e.FieldStart("ID") - s.ID.Encode(e) - } + e.FieldStart("ID") + e.Int64(s.ID) } } @@ -151,13 +149,16 @@ func (s *ID) Decode(d *jx.Decoder) error { if s == nil { return errors.New("invalid: unable to decode ID to nil") } + var requiredBitSet [1]uint8 if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { switch string(k) { case "ID": + requiredBitSet[0] |= 1 << 0 if err := func() error { - s.ID.Reset() - if err := s.ID.Decode(d); err != nil { + v, err := d.Int64() + s.ID = int64(v) + if err != nil { return err } return nil @@ -171,6 +172,38 @@ func (s *ID) Decode(d *jx.Decoder) error { }); err != nil { return errors.Wrap(err, "decode ID") } + // 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(jsonFieldsNameOfID) { + name = jsonFieldsNameOfID[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 } @@ -188,41 +221,6 @@ func (s *ID) UnmarshalJSON(data []byte) error { return s.Decode(d) } -// Encode encodes bool as json. -func (o OptBool) Encode(e *jx.Encoder) { - if !o.Set { - return - } - e.Bool(bool(o.Value)) -} - -// Decode decodes bool from json. -func (o *OptBool) Decode(d *jx.Decoder) error { - if o == nil { - return errors.New("invalid: unable to decode OptBool to nil") - } - o.Set = true - v, err := d.Bool() - if err != nil { - return err - } - o.Value = bool(v) - return nil -} - -// MarshalJSON implements stdjson.Marshaler. -func (s OptBool) MarshalJSON() ([]byte, error) { - e := jx.Encoder{} - s.Encode(&e) - return e.Bytes(), nil -} - -// UnmarshalJSON implements stdjson.Unmarshaler. -func (s *OptBool) 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 { @@ -293,6 +291,138 @@ func (s *OptInt64) UnmarshalJSON(data []byte) error { return s.Decode(d) } +// Encode encodes ScriptCreate as json. +func (o OptScriptCreate) Encode(e *jx.Encoder) { + if !o.Set { + return + } + o.Value.Encode(e) +} + +// Decode decodes ScriptCreate from json. +func (o *OptScriptCreate) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptScriptCreate to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptScriptCreate) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptScriptCreate) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes ScriptPolicyCreate as json. +func (o OptScriptPolicyCreate) Encode(e *jx.Encoder) { + if !o.Set { + return + } + o.Value.Encode(e) +} + +// Decode decodes ScriptPolicyCreate from json. +func (o *OptScriptPolicyCreate) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptScriptPolicyCreate to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptScriptPolicyCreate) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptScriptPolicyCreate) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes ScriptPolicyUpdate as json. +func (o OptScriptPolicyUpdate) Encode(e *jx.Encoder) { + if !o.Set { + return + } + o.Value.Encode(e) +} + +// Decode decodes ScriptPolicyUpdate from json. +func (o *OptScriptPolicyUpdate) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptScriptPolicyUpdate to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptScriptPolicyUpdate) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptScriptPolicyUpdate) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes ScriptUpdate as json. +func (o OptScriptUpdate) Encode(e *jx.Encoder) { + if !o.Set { + return + } + o.Value.Encode(e) +} + +// Decode decodes ScriptUpdate from json. +func (o *OptScriptUpdate) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptScriptUpdate to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptScriptUpdate) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptScriptUpdate) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + // Encode encodes string as json. func (o OptString) Encode(e *jx.Encoder) { if !o.Set { @@ -361,6 +491,820 @@ func (s *OptSubmissionCreate) UnmarshalJSON(data []byte) error { return s.Decode(d) } +// Encode implements json.Marshaler. +func (s *Script) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *Script) encodeFields(e *jx.Encoder) { + { + e.FieldStart("ID") + e.Int64(s.ID) + } + { + e.FieldStart("Hash") + e.Str(s.Hash) + } + { + e.FieldStart("Source") + e.Str(s.Source) + } + { + if s.SubmissionID.Set { + e.FieldStart("SubmissionID") + s.SubmissionID.Encode(e) + } + } +} + +var jsonFieldsNameOfScript = [4]string{ + 0: "ID", + 1: "Hash", + 2: "Source", + 3: "SubmissionID", +} + +// Decode decodes Script from json. +func (s *Script) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode Script to nil") + } + var requiredBitSet [1]uint8 + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "ID": + requiredBitSet[0] |= 1 << 0 + if err := func() error { + v, err := d.Int64() + s.ID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ID\"") + } + case "Hash": + requiredBitSet[0] |= 1 << 1 + if err := func() error { + v, err := d.Str() + s.Hash = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Hash\"") + } + case "Source": + requiredBitSet[0] |= 1 << 2 + if err := func() error { + v, err := d.Str() + s.Source = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Source\"") + } + case "SubmissionID": + if err := func() error { + s.SubmissionID.Reset() + if err := s.SubmissionID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"SubmissionID\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode Script") + } + // Validate required fields. + var failures []validate.FieldError + for i, mask := range [1]uint8{ + 0b00000111, + } { + 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(jsonFieldsNameOfScript) { + name = jsonFieldsNameOfScript[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 *Script) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *Script) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ScriptCreate) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ScriptCreate) encodeFields(e *jx.Encoder) { + { + e.FieldStart("Source") + e.Str(s.Source) + } + { + if s.SubmissionID.Set { + e.FieldStart("SubmissionID") + s.SubmissionID.Encode(e) + } + } +} + +var jsonFieldsNameOfScriptCreate = [2]string{ + 0: "Source", + 1: "SubmissionID", +} + +// Decode decodes ScriptCreate from json. +func (s *ScriptCreate) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ScriptCreate to nil") + } + var requiredBitSet [1]uint8 + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "Source": + requiredBitSet[0] |= 1 << 0 + if err := func() error { + v, err := d.Str() + s.Source = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Source\"") + } + case "SubmissionID": + if err := func() error { + s.SubmissionID.Reset() + if err := s.SubmissionID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"SubmissionID\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ScriptCreate") + } + // 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(jsonFieldsNameOfScriptCreate) { + name = jsonFieldsNameOfScriptCreate[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 *ScriptCreate) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ScriptCreate) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ScriptPolicy) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ScriptPolicy) encodeFields(e *jx.Encoder) { + { + e.FieldStart("ID") + e.Int64(s.ID) + } + { + e.FieldStart("FromScriptHash") + e.Str(s.FromScriptHash) + } + { + e.FieldStart("ToScriptID") + e.Int64(s.ToScriptID) + } + { + e.FieldStart("Policy") + e.Int32(s.Policy) + } +} + +var jsonFieldsNameOfScriptPolicy = [4]string{ + 0: "ID", + 1: "FromScriptHash", + 2: "ToScriptID", + 3: "Policy", +} + +// Decode decodes ScriptPolicy from json. +func (s *ScriptPolicy) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ScriptPolicy to nil") + } + var requiredBitSet [1]uint8 + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "ID": + requiredBitSet[0] |= 1 << 0 + if err := func() error { + v, err := d.Int64() + s.ID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ID\"") + } + case "FromScriptHash": + requiredBitSet[0] |= 1 << 1 + if err := func() error { + v, err := d.Str() + s.FromScriptHash = string(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"FromScriptHash\"") + } + case "ToScriptID": + requiredBitSet[0] |= 1 << 2 + if err := func() error { + v, err := d.Int64() + s.ToScriptID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ToScriptID\"") + } + case "Policy": + requiredBitSet[0] |= 1 << 3 + if err := func() error { + v, err := d.Int32() + s.Policy = int32(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Policy\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ScriptPolicy") + } + // Validate required fields. + var failures []validate.FieldError + for i, mask := range [1]uint8{ + 0b00001111, + } { + 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(jsonFieldsNameOfScriptPolicy) { + name = jsonFieldsNameOfScriptPolicy[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 *ScriptPolicy) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ScriptPolicy) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ScriptPolicyCreate) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ScriptPolicyCreate) encodeFields(e *jx.Encoder) { + { + e.FieldStart("FromScriptID") + e.Int64(s.FromScriptID) + } + { + e.FieldStart("ToScriptID") + e.Int64(s.ToScriptID) + } + { + e.FieldStart("Policy") + e.Int32(s.Policy) + } +} + +var jsonFieldsNameOfScriptPolicyCreate = [3]string{ + 0: "FromScriptID", + 1: "ToScriptID", + 2: "Policy", +} + +// Decode decodes ScriptPolicyCreate from json. +func (s *ScriptPolicyCreate) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ScriptPolicyCreate to nil") + } + var requiredBitSet [1]uint8 + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "FromScriptID": + requiredBitSet[0] |= 1 << 0 + if err := func() error { + v, err := d.Int64() + s.FromScriptID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"FromScriptID\"") + } + case "ToScriptID": + requiredBitSet[0] |= 1 << 1 + if err := func() error { + v, err := d.Int64() + s.ToScriptID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ToScriptID\"") + } + case "Policy": + requiredBitSet[0] |= 1 << 2 + if err := func() error { + v, err := d.Int32() + s.Policy = int32(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Policy\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ScriptPolicyCreate") + } + // Validate required fields. + var failures []validate.FieldError + for i, mask := range [1]uint8{ + 0b00000111, + } { + 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(jsonFieldsNameOfScriptPolicyCreate) { + name = jsonFieldsNameOfScriptPolicyCreate[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 *ScriptPolicyCreate) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ScriptPolicyCreate) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ScriptPolicyUpdate) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ScriptPolicyUpdate) encodeFields(e *jx.Encoder) { + { + e.FieldStart("ID") + e.Int64(s.ID) + } + { + if s.FromScriptID.Set { + e.FieldStart("FromScriptID") + s.FromScriptID.Encode(e) + } + } + { + if s.ToScriptID.Set { + e.FieldStart("ToScriptID") + s.ToScriptID.Encode(e) + } + } + { + if s.Policy.Set { + e.FieldStart("Policy") + s.Policy.Encode(e) + } + } +} + +var jsonFieldsNameOfScriptPolicyUpdate = [4]string{ + 0: "ID", + 1: "FromScriptID", + 2: "ToScriptID", + 3: "Policy", +} + +// Decode decodes ScriptPolicyUpdate from json. +func (s *ScriptPolicyUpdate) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ScriptPolicyUpdate to nil") + } + var requiredBitSet [1]uint8 + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "ID": + requiredBitSet[0] |= 1 << 0 + if err := func() error { + v, err := d.Int64() + s.ID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ID\"") + } + case "FromScriptID": + if err := func() error { + s.FromScriptID.Reset() + if err := s.FromScriptID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"FromScriptID\"") + } + case "ToScriptID": + if err := func() error { + s.ToScriptID.Reset() + if err := s.ToScriptID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ToScriptID\"") + } + case "Policy": + if err := func() error { + s.Policy.Reset() + if err := s.Policy.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Policy\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ScriptPolicyUpdate") + } + // 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(jsonFieldsNameOfScriptPolicyUpdate) { + name = jsonFieldsNameOfScriptPolicyUpdate[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 *ScriptPolicyUpdate) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ScriptPolicyUpdate) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ScriptUpdate) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ScriptUpdate) encodeFields(e *jx.Encoder) { + { + e.FieldStart("ID") + e.Int64(s.ID) + } + { + if s.Source.Set { + e.FieldStart("Source") + s.Source.Encode(e) + } + } + { + if s.SubmissionID.Set { + e.FieldStart("SubmissionID") + s.SubmissionID.Encode(e) + } + } +} + +var jsonFieldsNameOfScriptUpdate = [3]string{ + 0: "ID", + 1: "Source", + 2: "SubmissionID", +} + +// Decode decodes ScriptUpdate from json. +func (s *ScriptUpdate) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ScriptUpdate to nil") + } + var requiredBitSet [1]uint8 + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "ID": + requiredBitSet[0] |= 1 << 0 + if err := func() error { + v, err := d.Int64() + s.ID = int64(v) + if err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ID\"") + } + case "Source": + if err := func() error { + s.Source.Reset() + if err := s.Source.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"Source\"") + } + case "SubmissionID": + if err := func() error { + s.SubmissionID.Reset() + if err := s.SubmissionID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"SubmissionID\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ScriptUpdate") + } + // 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(jsonFieldsNameOfScriptUpdate) { + name = jsonFieldsNameOfScriptUpdate[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 *ScriptUpdate) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ScriptUpdate) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + // Encode implements json.Marshaler. func (s *Submission) Encode(e *jx.Encoder) { e.ObjStart() @@ -371,64 +1315,44 @@ func (s *Submission) Encode(e *jx.Encoder) { // encodeFields encodes fields. func (s *Submission) encodeFields(e *jx.Encoder) { { - if s.ID.Set { - e.FieldStart("ID") - s.ID.Encode(e) - } + e.FieldStart("ID") + e.Int64(s.ID) } { - if s.DisplayName.Set { - e.FieldStart("DisplayName") - s.DisplayName.Encode(e) - } + e.FieldStart("DisplayName") + e.Str(s.DisplayName) } { - if s.Creator.Set { - e.FieldStart("Creator") - s.Creator.Encode(e) - } + e.FieldStart("Creator") + e.Str(s.Creator) } { - if s.GameID.Set { - e.FieldStart("GameID") - s.GameID.Encode(e) - } + e.FieldStart("GameID") + e.Int32(s.GameID) } { - if s.Date.Set { - e.FieldStart("Date") - s.Date.Encode(e) - } + e.FieldStart("Date") + e.Int64(s.Date) } { - if s.Submitter.Set { - e.FieldStart("Submitter") - s.Submitter.Encode(e) - } + e.FieldStart("Submitter") + e.Int64(s.Submitter) } { - if s.AssetID.Set { - e.FieldStart("AssetID") - s.AssetID.Encode(e) - } + e.FieldStart("AssetID") + e.Int64(s.AssetID) } { - if s.AssetVersion.Set { - e.FieldStart("AssetVersion") - s.AssetVersion.Encode(e) - } + e.FieldStart("AssetVersion") + e.Int64(s.AssetVersion) } { - if s.Completed.Set { - e.FieldStart("Completed") - s.Completed.Encode(e) - } + e.FieldStart("Completed") + e.Bool(s.Completed) } { - if s.SubmissionType.Set { - e.FieldStart("SubmissionType") - s.SubmissionType.Encode(e) - } + e.FieldStart("SubmissionType") + e.Int32(s.SubmissionType) } { if s.TargetAssetID.Set { @@ -437,10 +1361,8 @@ func (s *Submission) encodeFields(e *jx.Encoder) { } } { - if s.StatusID.Set { - e.FieldStart("StatusID") - s.StatusID.Encode(e) - } + e.FieldStart("StatusID") + e.Int32(s.StatusID) } } @@ -464,13 +1386,16 @@ func (s *Submission) Decode(d *jx.Decoder) error { if s == nil { return errors.New("invalid: unable to decode Submission to nil") } + var requiredBitSet [2]uint8 if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { switch string(k) { case "ID": + requiredBitSet[0] |= 1 << 0 if err := func() error { - s.ID.Reset() - if err := s.ID.Decode(d); err != nil { + v, err := d.Int64() + s.ID = int64(v) + if err != nil { return err } return nil @@ -478,9 +1403,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"ID\"") } case "DisplayName": + requiredBitSet[0] |= 1 << 1 if err := func() error { - s.DisplayName.Reset() - if err := s.DisplayName.Decode(d); err != nil { + v, err := d.Str() + s.DisplayName = string(v) + if err != nil { return err } return nil @@ -488,9 +1415,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"DisplayName\"") } case "Creator": + requiredBitSet[0] |= 1 << 2 if err := func() error { - s.Creator.Reset() - if err := s.Creator.Decode(d); err != nil { + v, err := d.Str() + s.Creator = string(v) + if err != nil { return err } return nil @@ -498,9 +1427,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"Creator\"") } case "GameID": + requiredBitSet[0] |= 1 << 3 if err := func() error { - s.GameID.Reset() - if err := s.GameID.Decode(d); err != nil { + v, err := d.Int32() + s.GameID = int32(v) + if err != nil { return err } return nil @@ -508,9 +1439,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"GameID\"") } case "Date": + requiredBitSet[0] |= 1 << 4 if err := func() error { - s.Date.Reset() - if err := s.Date.Decode(d); err != nil { + v, err := d.Int64() + s.Date = int64(v) + if err != nil { return err } return nil @@ -518,9 +1451,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"Date\"") } case "Submitter": + requiredBitSet[0] |= 1 << 5 if err := func() error { - s.Submitter.Reset() - if err := s.Submitter.Decode(d); err != nil { + v, err := d.Int64() + s.Submitter = int64(v) + if err != nil { return err } return nil @@ -528,9 +1463,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"Submitter\"") } case "AssetID": + requiredBitSet[0] |= 1 << 6 if err := func() error { - s.AssetID.Reset() - if err := s.AssetID.Decode(d); err != nil { + v, err := d.Int64() + s.AssetID = int64(v) + if err != nil { return err } return nil @@ -538,9 +1475,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"AssetID\"") } case "AssetVersion": + requiredBitSet[0] |= 1 << 7 if err := func() error { - s.AssetVersion.Reset() - if err := s.AssetVersion.Decode(d); err != nil { + v, err := d.Int64() + s.AssetVersion = int64(v) + if err != nil { return err } return nil @@ -548,9 +1487,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"AssetVersion\"") } case "Completed": + requiredBitSet[1] |= 1 << 0 if err := func() error { - s.Completed.Reset() - if err := s.Completed.Decode(d); err != nil { + v, err := d.Bool() + s.Completed = bool(v) + if err != nil { return err } return nil @@ -558,9 +1499,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"Completed\"") } case "SubmissionType": + requiredBitSet[1] |= 1 << 1 if err := func() error { - s.SubmissionType.Reset() - if err := s.SubmissionType.Decode(d); err != nil { + v, err := d.Int32() + s.SubmissionType = int32(v) + if err != nil { return err } return nil @@ -578,9 +1521,11 @@ func (s *Submission) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"TargetAssetID\"") } case "StatusID": + requiredBitSet[1] |= 1 << 3 if err := func() error { - s.StatusID.Reset() - if err := s.StatusID.Decode(d); err != nil { + v, err := d.Int32() + s.StatusID = int32(v) + if err != nil { return err } return nil @@ -594,6 +1539,39 @@ func (s *Submission) Decode(d *jx.Decoder) error { }); err != nil { return errors.Wrap(err, "decode Submission") } + // Validate required fields. + var failures []validate.FieldError + for i, mask := range [2]uint8{ + 0b11111111, + 0b00001011, + } { + 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(jsonFieldsNameOfSubmission) { + name = jsonFieldsNameOfSubmission[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 } @@ -621,46 +1599,32 @@ func (s *SubmissionCreate) Encode(e *jx.Encoder) { // encodeFields encodes fields. func (s *SubmissionCreate) encodeFields(e *jx.Encoder) { { - if s.DisplayName.Set { - e.FieldStart("DisplayName") - s.DisplayName.Encode(e) - } + e.FieldStart("DisplayName") + e.Str(s.DisplayName) } { - if s.Creator.Set { - e.FieldStart("Creator") - s.Creator.Encode(e) - } + e.FieldStart("Creator") + e.Str(s.Creator) } { - if s.GameID.Set { - e.FieldStart("GameID") - s.GameID.Encode(e) - } + e.FieldStart("GameID") + e.Int32(s.GameID) } { - if s.Submitter.Set { - e.FieldStart("Submitter") - s.Submitter.Encode(e) - } + e.FieldStart("Submitter") + e.Int64(s.Submitter) } { - if s.AssetID.Set { - e.FieldStart("AssetID") - s.AssetID.Encode(e) - } + e.FieldStart("AssetID") + e.Int64(s.AssetID) } { - if s.AssetVersion.Set { - e.FieldStart("AssetVersion") - s.AssetVersion.Encode(e) - } + e.FieldStart("AssetVersion") + e.Int64(s.AssetVersion) } { - if s.SubmissionType.Set { - e.FieldStart("SubmissionType") - s.SubmissionType.Encode(e) - } + e.FieldStart("SubmissionType") + e.Int32(s.SubmissionType) } { if s.TargetAssetID.Set { @@ -686,13 +1650,16 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error { if s == nil { return errors.New("invalid: unable to decode SubmissionCreate to nil") } + var requiredBitSet [1]uint8 if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { switch string(k) { case "DisplayName": + requiredBitSet[0] |= 1 << 0 if err := func() error { - s.DisplayName.Reset() - if err := s.DisplayName.Decode(d); err != nil { + v, err := d.Str() + s.DisplayName = string(v) + if err != nil { return err } return nil @@ -700,9 +1667,11 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"DisplayName\"") } case "Creator": + requiredBitSet[0] |= 1 << 1 if err := func() error { - s.Creator.Reset() - if err := s.Creator.Decode(d); err != nil { + v, err := d.Str() + s.Creator = string(v) + if err != nil { return err } return nil @@ -710,9 +1679,11 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"Creator\"") } case "GameID": + requiredBitSet[0] |= 1 << 2 if err := func() error { - s.GameID.Reset() - if err := s.GameID.Decode(d); err != nil { + v, err := d.Int32() + s.GameID = int32(v) + if err != nil { return err } return nil @@ -720,9 +1691,11 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"GameID\"") } case "Submitter": + requiredBitSet[0] |= 1 << 3 if err := func() error { - s.Submitter.Reset() - if err := s.Submitter.Decode(d); err != nil { + v, err := d.Int64() + s.Submitter = int64(v) + if err != nil { return err } return nil @@ -730,9 +1703,11 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"Submitter\"") } case "AssetID": + requiredBitSet[0] |= 1 << 4 if err := func() error { - s.AssetID.Reset() - if err := s.AssetID.Decode(d); err != nil { + v, err := d.Int64() + s.AssetID = int64(v) + if err != nil { return err } return nil @@ -740,9 +1715,11 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"AssetID\"") } case "AssetVersion": + requiredBitSet[0] |= 1 << 5 if err := func() error { - s.AssetVersion.Reset() - if err := s.AssetVersion.Decode(d); err != nil { + v, err := d.Int64() + s.AssetVersion = int64(v) + if err != nil { return err } return nil @@ -750,9 +1727,11 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"AssetVersion\"") } case "SubmissionType": + requiredBitSet[0] |= 1 << 6 if err := func() error { - s.SubmissionType.Reset() - if err := s.SubmissionType.Decode(d); err != nil { + v, err := d.Int32() + s.SubmissionType = int32(v) + if err != nil { return err } return nil @@ -776,6 +1755,38 @@ func (s *SubmissionCreate) Decode(d *jx.Decoder) error { }); err != nil { return errors.Wrap(err, "decode SubmissionCreate") } + // Validate required fields. + var failures []validate.FieldError + for i, mask := range [1]uint8{ + 0b01111111, + } { + 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(jsonFieldsNameOfSubmissionCreate) { + name = jsonFieldsNameOfSubmissionCreate[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 } diff --git a/pkg/api/oas_operations_gen.go b/pkg/api/oas_operations_gen.go index ba2a2bc..acf69ec 100644 --- a/pkg/api/oas_operations_gen.go +++ b/pkg/api/oas_operations_gen.go @@ -14,9 +14,18 @@ const ( ActionSubmissionTriggerPublishOperation OperationName = "ActionSubmissionTriggerPublish" ActionSubmissionTriggerValidateOperation OperationName = "ActionSubmissionTriggerValidate" ActionSubmissionValidateOperation OperationName = "ActionSubmissionValidate" + CreateScriptOperation OperationName = "CreateScript" + CreateScriptPolicyOperation OperationName = "CreateScriptPolicy" CreateSubmissionOperation OperationName = "CreateSubmission" + DeleteScriptOperation OperationName = "DeleteScript" + DeleteScriptPolicyOperation OperationName = "DeleteScriptPolicy" + GetScriptOperation OperationName = "GetScript" + GetScriptPolicyOperation OperationName = "GetScriptPolicy" + GetScriptPolicyFromHashOperation OperationName = "GetScriptPolicyFromHash" GetSubmissionOperation OperationName = "GetSubmission" ListSubmissionsOperation OperationName = "ListSubmissions" PatchSubmissionCompletedOperation OperationName = "PatchSubmissionCompleted" PatchSubmissionModelOperation OperationName = "PatchSubmissionModel" + UpdateScriptOperation OperationName = "UpdateScript" + UpdateScriptPolicyOperation OperationName = "UpdateScriptPolicy" ) diff --git a/pkg/api/oas_parameters_gen.go b/pkg/api/oas_parameters_gen.go index ae4cf96..5009cf7 100644 --- a/pkg/api/oas_parameters_gen.go +++ b/pkg/api/oas_parameters_gen.go @@ -535,6 +535,331 @@ func decodeActionSubmissionValidateParams(args [1]string, argsEscaped bool, r *h return params, nil } +// DeleteScriptParams is parameters of deleteScript operation. +type DeleteScriptParams struct { + ScriptID int64 +} + +func unpackDeleteScriptParams(packed middleware.Parameters) (params DeleteScriptParams) { + { + key := middleware.ParameterKey{ + Name: "ScriptID", + In: "path", + } + params.ScriptID = packed[key].(int64) + } + return params +} + +func decodeDeleteScriptParams(args [1]string, argsEscaped bool, r *http.Request) (params DeleteScriptParams, _ error) { + // Decode path: ScriptID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "ScriptID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.ScriptID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "ScriptID", + In: "path", + Err: err, + } + } + return params, nil +} + +// DeleteScriptPolicyParams is parameters of deleteScriptPolicy operation. +type DeleteScriptPolicyParams struct { + ScriptPolicyID int64 +} + +func unpackDeleteScriptPolicyParams(packed middleware.Parameters) (params DeleteScriptPolicyParams) { + { + key := middleware.ParameterKey{ + Name: "ScriptPolicyID", + In: "path", + } + params.ScriptPolicyID = packed[key].(int64) + } + return params +} + +func decodeDeleteScriptPolicyParams(args [1]string, argsEscaped bool, r *http.Request) (params DeleteScriptPolicyParams, _ error) { + // Decode path: ScriptPolicyID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "ScriptPolicyID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.ScriptPolicyID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "ScriptPolicyID", + In: "path", + Err: err, + } + } + return params, nil +} + +// GetScriptParams is parameters of getScript operation. +type GetScriptParams struct { + ScriptID int64 +} + +func unpackGetScriptParams(packed middleware.Parameters) (params GetScriptParams) { + { + key := middleware.ParameterKey{ + Name: "ScriptID", + In: "path", + } + params.ScriptID = packed[key].(int64) + } + return params +} + +func decodeGetScriptParams(args [1]string, argsEscaped bool, r *http.Request) (params GetScriptParams, _ error) { + // Decode path: ScriptID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "ScriptID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.ScriptID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "ScriptID", + In: "path", + Err: err, + } + } + return params, nil +} + +// GetScriptPolicyParams is parameters of getScriptPolicy operation. +type GetScriptPolicyParams struct { + ScriptPolicyID int64 +} + +func unpackGetScriptPolicyParams(packed middleware.Parameters) (params GetScriptPolicyParams) { + { + key := middleware.ParameterKey{ + Name: "ScriptPolicyID", + In: "path", + } + params.ScriptPolicyID = packed[key].(int64) + } + return params +} + +func decodeGetScriptPolicyParams(args [1]string, argsEscaped bool, r *http.Request) (params GetScriptPolicyParams, _ error) { + // Decode path: ScriptPolicyID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "ScriptPolicyID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.ScriptPolicyID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "ScriptPolicyID", + In: "path", + Err: err, + } + } + return params, nil +} + +// GetScriptPolicyFromHashParams is parameters of getScriptPolicyFromHash operation. +type GetScriptPolicyFromHashParams struct { + FromScriptHash string +} + +func unpackGetScriptPolicyFromHashParams(packed middleware.Parameters) (params GetScriptPolicyFromHashParams) { + { + key := middleware.ParameterKey{ + Name: "FromScriptHash", + In: "path", + } + params.FromScriptHash = packed[key].(string) + } + return params +} + +func decodeGetScriptPolicyFromHashParams(args [1]string, argsEscaped bool, r *http.Request) (params GetScriptPolicyFromHashParams, _ error) { + // Decode path: FromScriptHash. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "FromScriptHash", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + params.FromScriptHash = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "FromScriptHash", + In: "path", + Err: err, + } + } + return params, nil +} + // GetSubmissionParams is parameters of getSubmission operation. type GetSubmissionParams struct { SubmissionID int64 @@ -668,7 +993,7 @@ func decodeListSubmissionsParams(args [0]string, argsEscaped bool, r *http.Reque Name: "filter", Style: uri.QueryStyleForm, Explode: true, - Fields: []uri.QueryParameterObjectField{{Name: "ID", Required: false}, {Name: "DisplayName", Required: false}, {Name: "Creator", Required: false}, {Name: "GameID", Required: false}, {Name: "Date", Required: false}}, + Fields: []uri.QueryParameterObjectField{{Name: "ID", Required: true}, {Name: "DisplayName", Required: false}, {Name: "Creator", Required: false}, {Name: "GameID", Required: false}, {Name: "Date", Required: false}}, } if err := q.HasParam(cfg); err == nil { @@ -914,3 +1239,133 @@ func decodePatchSubmissionModelParams(args [1]string, argsEscaped bool, r *http. } return params, nil } + +// UpdateScriptParams is parameters of updateScript operation. +type UpdateScriptParams struct { + ScriptID int64 +} + +func unpackUpdateScriptParams(packed middleware.Parameters) (params UpdateScriptParams) { + { + key := middleware.ParameterKey{ + Name: "ScriptID", + In: "path", + } + params.ScriptID = packed[key].(int64) + } + return params +} + +func decodeUpdateScriptParams(args [1]string, argsEscaped bool, r *http.Request) (params UpdateScriptParams, _ error) { + // Decode path: ScriptID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "ScriptID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.ScriptID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "ScriptID", + In: "path", + Err: err, + } + } + return params, nil +} + +// UpdateScriptPolicyParams is parameters of updateScriptPolicy operation. +type UpdateScriptPolicyParams struct { + ScriptPolicyID int64 +} + +func unpackUpdateScriptPolicyParams(packed middleware.Parameters) (params UpdateScriptPolicyParams) { + { + key := middleware.ParameterKey{ + Name: "ScriptPolicyID", + In: "path", + } + params.ScriptPolicyID = packed[key].(int64) + } + return params +} + +func decodeUpdateScriptPolicyParams(args [1]string, argsEscaped bool, r *http.Request) (params UpdateScriptPolicyParams, _ error) { + // Decode path: ScriptPolicyID. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "ScriptPolicyID", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + params.ScriptPolicyID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "ScriptPolicyID", + In: "path", + Err: err, + } + } + return params, nil +} diff --git a/pkg/api/oas_request_decoders_gen.go b/pkg/api/oas_request_decoders_gen.go index 5a3d275..e558b87 100644 --- a/pkg/api/oas_request_decoders_gen.go +++ b/pkg/api/oas_request_decoders_gen.go @@ -15,6 +15,140 @@ import ( "github.com/ogen-go/ogen/validate" ) +func (s *Server) decodeCreateScriptRequest(r *http.Request) ( + req OptScriptCreate, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = multierr.Append(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = multierr.Append(rerr, close()) + } + }() + if _, ok := r.Header["Content-Type"]; !ok && r.ContentLength == 0 { + return req, close, nil + } + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, close, nil + } + buf, err := io.ReadAll(r.Body) + if err != nil { + return req, close, err + } + + if len(buf) == 0 { + return req, close, nil + } + + d := jx.DecodeBytes(buf) + + var request OptScriptCreate + if err := func() error { + request.Reset() + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, close, err + } + return request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeCreateScriptPolicyRequest(r *http.Request) ( + req OptScriptPolicyCreate, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = multierr.Append(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = multierr.Append(rerr, close()) + } + }() + if _, ok := r.Header["Content-Type"]; !ok && r.ContentLength == 0 { + return req, close, nil + } + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, close, nil + } + buf, err := io.ReadAll(r.Body) + if err != nil { + return req, close, err + } + + if len(buf) == 0 { + return req, close, nil + } + + d := jx.DecodeBytes(buf) + + var request OptScriptPolicyCreate + if err := func() error { + request.Reset() + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, close, err + } + return request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} + func (s *Server) decodeCreateSubmissionRequest(r *http.Request) ( req OptSubmissionCreate, close func() error, @@ -81,3 +215,137 @@ func (s *Server) decodeCreateSubmissionRequest(r *http.Request) ( return req, close, validate.InvalidContentType(ct) } } + +func (s *Server) decodeUpdateScriptRequest(r *http.Request) ( + req OptScriptUpdate, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = multierr.Append(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = multierr.Append(rerr, close()) + } + }() + if _, ok := r.Header["Content-Type"]; !ok && r.ContentLength == 0 { + return req, close, nil + } + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, close, nil + } + buf, err := io.ReadAll(r.Body) + if err != nil { + return req, close, err + } + + if len(buf) == 0 { + return req, close, nil + } + + d := jx.DecodeBytes(buf) + + var request OptScriptUpdate + if err := func() error { + request.Reset() + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, close, err + } + return request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeUpdateScriptPolicyRequest(r *http.Request) ( + req OptScriptPolicyUpdate, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = multierr.Append(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = multierr.Append(rerr, close()) + } + }() + if _, ok := r.Header["Content-Type"]; !ok && r.ContentLength == 0 { + return req, close, nil + } + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, close, nil + } + buf, err := io.ReadAll(r.Body) + if err != nil { + return req, close, err + } + + if len(buf) == 0 { + return req, close, nil + } + + d := jx.DecodeBytes(buf) + + var request OptScriptPolicyUpdate + if err := func() error { + request.Reset() + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, close, err + } + return request, close, nil + default: + return req, close, validate.InvalidContentType(ct) + } +} diff --git a/pkg/api/oas_request_encoders_gen.go b/pkg/api/oas_request_encoders_gen.go index ab746dc..11b0fae 100644 --- a/pkg/api/oas_request_encoders_gen.go +++ b/pkg/api/oas_request_encoders_gen.go @@ -11,6 +11,46 @@ import ( ht "github.com/ogen-go/ogen/http" ) +func encodeCreateScriptRequest( + req OptScriptCreate, + r *http.Request, +) error { + const contentType = "application/json" + if !req.Set { + // Keep request with empty body if value is not set. + return nil + } + e := new(jx.Encoder) + { + if req.Set { + req.Encode(e) + } + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeCreateScriptPolicyRequest( + req OptScriptPolicyCreate, + r *http.Request, +) error { + const contentType = "application/json" + if !req.Set { + // Keep request with empty body if value is not set. + return nil + } + e := new(jx.Encoder) + { + if req.Set { + req.Encode(e) + } + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + func encodeCreateSubmissionRequest( req OptSubmissionCreate, r *http.Request, @@ -30,3 +70,43 @@ func encodeCreateSubmissionRequest( ht.SetBody(r, bytes.NewReader(encoded), contentType) return nil } + +func encodeUpdateScriptRequest( + req OptScriptUpdate, + r *http.Request, +) error { + const contentType = "application/json" + if !req.Set { + // Keep request with empty body if value is not set. + return nil + } + e := new(jx.Encoder) + { + if req.Set { + req.Encode(e) + } + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeUpdateScriptPolicyRequest( + req OptScriptPolicyUpdate, + r *http.Request, +) error { + const contentType = "application/json" + if !req.Set { + // Keep request with empty body if value is not set. + return nil + } + e := new(jx.Encoder) + { + if req.Set { + req.Encode(e) + } + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} diff --git a/pkg/api/oas_response_decoders_gen.go b/pkg/api/oas_response_decoders_gen.go index 8f4dea2..11be8ed 100644 --- a/pkg/api/oas_response_decoders_gen.go +++ b/pkg/api/oas_response_decoders_gen.go @@ -422,6 +422,172 @@ func decodeActionSubmissionValidateResponse(resp *http.Response) (res *ActionSub return res, errors.Wrap(defRes, "error") } +func decodeCreateScriptResponse(resp *http.Response) (res *ID, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ID + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeCreateScriptPolicyResponse(resp *http.Response) (res *ID, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ID + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + func decodeCreateSubmissionResponse(resp *http.Response) (res *ID, _ error) { switch resp.StatusCode { case 200: @@ -505,6 +671,357 @@ func decodeCreateSubmissionResponse(resp *http.Response) (res *ID, _ error) { return res, errors.Wrap(defRes, "error") } +func decodeDeleteScriptResponse(resp *http.Response) (res *DeleteScriptOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + return &DeleteScriptOK{}, nil + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeDeleteScriptPolicyResponse(resp *http.Response) (res *DeleteScriptPolicyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + return &DeleteScriptPolicyOK{}, nil + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeGetScriptResponse(resp *http.Response) (res *Script, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Script + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeGetScriptPolicyResponse(resp *http.Response) (res *ScriptPolicy, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ScriptPolicy + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeGetScriptPolicyFromHashResponse(resp *http.Response) (res *ScriptPolicy, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ScriptPolicy + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + func decodeGetSubmissionResponse(resp *http.Response) (res *Submission, _ error) { switch resp.StatusCode { case 200: @@ -789,3 +1306,105 @@ func decodePatchSubmissionModelResponse(resp *http.Response) (res *PatchSubmissi } return res, errors.Wrap(defRes, "error") } + +func decodeUpdateScriptResponse(resp *http.Response) (res *UpdateScriptOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + return &UpdateScriptOK{}, nil + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeUpdateScriptPolicyResponse(resp *http.Response) (res *UpdateScriptPolicyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + return &UpdateScriptPolicyOK{}, nil + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Error + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} diff --git a/pkg/api/oas_response_encoders_gen.go b/pkg/api/oas_response_encoders_gen.go index 6e265a5..98eca0e 100644 --- a/pkg/api/oas_response_encoders_gen.go +++ b/pkg/api/oas_response_encoders_gen.go @@ -69,6 +69,34 @@ func encodeActionSubmissionValidateResponse(response *ActionSubmissionValidateOK return nil } +func encodeCreateScriptResponse(response *ID, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeCreateScriptPolicyResponse(response *ID, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + func encodeCreateSubmissionResponse(response *ID, w http.ResponseWriter, span trace.Span) error { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(200) @@ -83,6 +111,62 @@ func encodeCreateSubmissionResponse(response *ID, w http.ResponseWriter, span tr return nil } +func encodeDeleteScriptResponse(response *DeleteScriptOK, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + return nil +} + +func encodeDeleteScriptPolicyResponse(response *DeleteScriptPolicyOK, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + return nil +} + +func encodeGetScriptResponse(response *Script, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeGetScriptPolicyResponse(response *ScriptPolicy, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeGetScriptPolicyFromHashResponse(response *ScriptPolicy, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + func encodeGetSubmissionResponse(response *Submission, w http.ResponseWriter, span trace.Span) error { w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(200) @@ -129,6 +213,20 @@ func encodePatchSubmissionModelResponse(response *PatchSubmissionModelOK, w http return nil } +func encodeUpdateScriptResponse(response *UpdateScriptOK, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + return nil +} + +func encodeUpdateScriptPolicyResponse(response *UpdateScriptPolicyOK, w http.ResponseWriter, span trace.Span) error { + w.WriteHeader(200) + span.SetStatus(codes.Ok, http.StatusText(200)) + + return nil +} + func encodeErrorResponse(response *ErrorStatusCode, w http.ResponseWriter, span trace.Span) error { w.Header().Set("Content-Type", "application/json; charset=utf-8") code := response.StatusCode diff --git a/pkg/api/oas_router_gen.go b/pkg/api/oas_router_gen.go index 03a49f5..cfabb5c 100644 --- a/pkg/api/oas_router_gen.go +++ b/pkg/api/oas_router_gen.go @@ -49,52 +49,208 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { break } switch elem[0] { - case '/': // Prefix: "/submissions" + case '/': // Prefix: "/s" origElem := elem - if l := len("/submissions"); len(elem) >= l && elem[0:l] == "/submissions" { + if l := len("/s"); len(elem) >= l && elem[0:l] == "/s" { elem = elem[l:] } else { break } if len(elem) == 0 { - switch r.Method { - case "GET": - s.handleListSubmissionsRequest([0]string{}, elemIsEscaped, w, r) - case "POST": - s.handleCreateSubmissionRequest([0]string{}, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "GET,POST") - } - - return + break } switch elem[0] { - case '/': // Prefix: "/" + case 'c': // Prefix: "cript" origElem := elem - if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + if l := len("cript"); len(elem) >= l && elem[0:l] == "cript" { elem = elem[l:] } else { break } - // Param: "SubmissionID" - // Match until "/" - idx := strings.IndexByte(elem, '/') - if idx < 0 { - idx = len(elem) + if len(elem) == 0 { + break + } + switch elem[0] { + case '-': // Prefix: "-policy" + origElem := elem + if l := len("-policy"); len(elem) >= l && elem[0:l] == "-policy" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch r.Method { + case "POST": + s.handleCreateScriptPolicyRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + switch elem[0] { + case '/': // Prefix: "/" + origElem := elem + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'h': // Prefix: "hash/" + origElem := elem + if l := len("hash/"); len(elem) >= l && elem[0:l] == "hash/" { + elem = elem[l:] + } else { + break + } + + // Param: "FromScriptHash" + // Leaf parameter + args[0] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "GET": + s.handleGetScriptPolicyFromHashRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "GET") + } + + return + } + + elem = origElem + case 'i': // Prefix: "id/" + origElem := elem + if l := len("id/"); len(elem) >= l && elem[0:l] == "id/" { + elem = elem[l:] + } else { + break + } + + // Param: "ScriptPolicyID" + // Leaf parameter + args[0] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "DELETE": + s.handleDeleteScriptPolicyRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + case "GET": + s.handleGetScriptPolicyRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + case "PATCH": + s.handleUpdateScriptPolicyRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "DELETE,GET,PATCH") + } + + return + } + + elem = origElem + } + + elem = origElem + } + + elem = origElem + case 's': // Prefix: "s" + origElem := elem + if l := len("s"); len(elem) >= l && elem[0:l] == "s" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch r.Method { + case "POST": + s.handleCreateScriptRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "POST") + } + + return + } + switch elem[0] { + case '/': // Prefix: "/" + origElem := elem + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + // Param: "ScriptID" + // Leaf parameter + args[0] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "DELETE": + s.handleDeleteScriptRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + case "GET": + s.handleGetScriptRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + case "PATCH": + s.handleUpdateScriptRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "DELETE,GET,PATCH") + } + + return + } + + elem = origElem + } + + elem = origElem + } + + elem = origElem + case 'u': // Prefix: "ubmissions" + origElem := elem + if l := len("ubmissions"); len(elem) >= l && elem[0:l] == "ubmissions" { + elem = elem[l:] + } else { + break } - args[0] = elem[:idx] - elem = elem[idx:] if len(elem) == 0 { switch r.Method { case "GET": - s.handleGetSubmissionRequest([1]string{ - args[0], - }, elemIsEscaped, w, r) + s.handleListSubmissionsRequest([0]string{}, elemIsEscaped, w, r) + case "POST": + s.handleCreateSubmissionRequest([0]string{}, elemIsEscaped, w, r) default: - s.notAllowed(w, r, "GET") + s.notAllowed(w, r, "GET,POST") } return @@ -108,59 +264,31 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { break } + // Param: "SubmissionID" + // Match until "/" + idx := strings.IndexByte(elem, '/') + if idx < 0 { + idx = len(elem) + } + args[0] = elem[:idx] + elem = elem[idx:] + if len(elem) == 0 { - break + switch r.Method { + case "GET": + s.handleGetSubmissionRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "GET") + } + + return } switch elem[0] { - case 'c': // Prefix: "completed" + case '/': // Prefix: "/" origElem := elem - if l := len("completed"); len(elem) >= l && elem[0:l] == "completed" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "PATCH": - s.handlePatchSubmissionCompletedRequest([1]string{ - args[0], - }, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "PATCH") - } - - return - } - - elem = origElem - case 'm': // Prefix: "model" - origElem := elem - if l := len("model"); len(elem) >= l && elem[0:l] == "model" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "PATCH": - s.handlePatchSubmissionModelRequest([1]string{ - args[0], - }, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "PATCH") - } - - return - } - - elem = origElem - case 's': // Prefix: "status/" - origElem := elem - if l := len("status/"); len(elem) >= l && elem[0:l] == "status/" { + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { elem = elem[l:] } else { break @@ -170,9 +298,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { break } switch elem[0] { - case 'p': // Prefix: "publish" + case 'c': // Prefix: "completed" origElem := elem - if l := len("publish"); len(elem) >= l && elem[0:l] == "publish" { + if l := len("completed"); len(elem) >= l && elem[0:l] == "completed" { elem = elem[l:] } else { break @@ -182,7 +310,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Leaf node. switch r.Method { case "PATCH": - s.handleActionSubmissionPublishRequest([1]string{ + s.handlePatchSubmissionCompletedRequest([1]string{ args[0], }, elemIsEscaped, w, r) default: @@ -193,93 +321,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } elem = origElem - case 'r': // Prefix: "re" + case 'm': // Prefix: "model" origElem := elem - if l := len("re"); len(elem) >= l && elem[0:l] == "re" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - break - } - switch elem[0] { - case 'j': // Prefix: "ject" - origElem := elem - if l := len("ject"); len(elem) >= l && elem[0:l] == "ject" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "PATCH": - s.handleActionSubmissionRejectRequest([1]string{ - args[0], - }, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "PATCH") - } - - return - } - - elem = origElem - case 'q': // Prefix: "quest-changes" - origElem := elem - if l := len("quest-changes"); len(elem) >= l && elem[0:l] == "quest-changes" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "PATCH": - s.handleActionSubmissionRequestChangesRequest([1]string{ - args[0], - }, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "PATCH") - } - - return - } - - elem = origElem - case 'v': // Prefix: "voke" - origElem := elem - if l := len("voke"); len(elem) >= l && elem[0:l] == "voke" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "PATCH": - s.handleActionSubmissionRevokeRequest([1]string{ - args[0], - }, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "PATCH") - } - - return - } - - elem = origElem - } - - elem = origElem - case 's': // Prefix: "submit" - origElem := elem - if l := len("submit"); len(elem) >= l && elem[0:l] == "submit" { + if l := len("model"); len(elem) >= l && elem[0:l] == "model" { elem = elem[l:] } else { break @@ -289,7 +333,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Leaf node. switch r.Method { case "PATCH": - s.handleActionSubmissionSubmitRequest([1]string{ + s.handlePatchSubmissionModelRequest([1]string{ args[0], }, elemIsEscaped, w, r) default: @@ -300,9 +344,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } elem = origElem - case 't': // Prefix: "trigger-" + case 's': // Prefix: "status/" origElem := elem - if l := len("trigger-"); len(elem) >= l && elem[0:l] == "trigger-" { + if l := len("status/"); len(elem) >= l && elem[0:l] == "status/" { elem = elem[l:] } else { break @@ -324,7 +368,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Leaf node. switch r.Method { case "PATCH": - s.handleActionSubmissionTriggerPublishRequest([1]string{ + s.handleActionSubmissionPublishRequest([1]string{ args[0], }, elemIsEscaped, w, r) default: @@ -334,6 +378,174 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + elem = origElem + case 'r': // Prefix: "re" + origElem := elem + if l := len("re"); len(elem) >= l && elem[0:l] == "re" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'j': // Prefix: "ject" + origElem := elem + if l := len("ject"); len(elem) >= l && elem[0:l] == "ject" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "PATCH": + s.handleActionSubmissionRejectRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "PATCH") + } + + return + } + + elem = origElem + case 'q': // Prefix: "quest-changes" + origElem := elem + if l := len("quest-changes"); len(elem) >= l && elem[0:l] == "quest-changes" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "PATCH": + s.handleActionSubmissionRequestChangesRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "PATCH") + } + + return + } + + elem = origElem + case 'v': // Prefix: "voke" + origElem := elem + if l := len("voke"); len(elem) >= l && elem[0:l] == "voke" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "PATCH": + s.handleActionSubmissionRevokeRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "PATCH") + } + + return + } + + elem = origElem + } + + elem = origElem + case 's': // Prefix: "submit" + origElem := elem + if l := len("submit"); len(elem) >= l && elem[0:l] == "submit" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "PATCH": + s.handleActionSubmissionSubmitRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "PATCH") + } + + return + } + + elem = origElem + case 't': // Prefix: "trigger-" + origElem := elem + if l := len("trigger-"); len(elem) >= l && elem[0:l] == "trigger-" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'p': // Prefix: "publish" + origElem := elem + if l := len("publish"); len(elem) >= l && elem[0:l] == "publish" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "PATCH": + s.handleActionSubmissionTriggerPublishRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "PATCH") + } + + return + } + + elem = origElem + case 'v': // Prefix: "validate" + origElem := elem + if l := len("validate"); len(elem) >= l && elem[0:l] == "validate" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "PATCH": + s.handleActionSubmissionTriggerValidateRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, "PATCH") + } + + return + } + + elem = origElem + } + elem = origElem case 'v': // Prefix: "validate" origElem := elem @@ -347,7 +559,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Leaf node. switch r.Method { case "PATCH": - s.handleActionSubmissionTriggerValidateRequest([1]string{ + s.handleActionSubmissionValidateRequest([1]string{ args[0], }, elemIsEscaped, w, r) default: @@ -360,29 +572,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { elem = origElem } - elem = origElem - case 'v': // Prefix: "validate" - origElem := elem - if l := len("validate"); len(elem) >= l && elem[0:l] == "validate" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch r.Method { - case "PATCH": - s.handleActionSubmissionValidateRequest([1]string{ - args[0], - }, elemIsEscaped, w, r) - default: - s.notAllowed(w, r, "PATCH") - } - - return - } - elem = origElem } @@ -476,63 +665,247 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { break } switch elem[0] { - case '/': // Prefix: "/submissions" + case '/': // Prefix: "/s" origElem := elem - if l := len("/submissions"); len(elem) >= l && elem[0:l] == "/submissions" { + if l := len("/s"); len(elem) >= l && elem[0:l] == "/s" { elem = elem[l:] } else { break } if len(elem) == 0 { - switch method { - case "GET": - r.name = ListSubmissionsOperation - r.summary = "Get list of submissions" - r.operationID = "listSubmissions" - r.pathPattern = "/submissions" - r.args = args - r.count = 0 - return r, true - case "POST": - r.name = CreateSubmissionOperation - r.summary = "Create new submission" - r.operationID = "createSubmission" - r.pathPattern = "/submissions" - r.args = args - r.count = 0 - return r, true - default: - return - } + break } switch elem[0] { - case '/': // Prefix: "/" + case 'c': // Prefix: "cript" origElem := elem - if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + if l := len("cript"); len(elem) >= l && elem[0:l] == "cript" { elem = elem[l:] } else { break } - // Param: "SubmissionID" - // Match until "/" - idx := strings.IndexByte(elem, '/') - if idx < 0 { - idx = len(elem) + if len(elem) == 0 { + break + } + switch elem[0] { + case '-': // Prefix: "-policy" + origElem := elem + if l := len("-policy"); len(elem) >= l && elem[0:l] == "-policy" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "POST": + r.name = CreateScriptPolicyOperation + r.summary = "Create a new script policy" + r.operationID = "createScriptPolicy" + r.pathPattern = "/script-policy" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/" + origElem := elem + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'h': // Prefix: "hash/" + origElem := elem + if l := len("hash/"); len(elem) >= l && elem[0:l] == "hash/" { + elem = elem[l:] + } else { + break + } + + // Param: "FromScriptHash" + // Leaf parameter + args[0] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch method { + case "GET": + r.name = GetScriptPolicyFromHashOperation + r.summary = "Get the policy for the given hash of script source code" + r.operationID = "getScriptPolicyFromHash" + r.pathPattern = "/script-policy/hash/{FromScriptHash}" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + case 'i': // Prefix: "id/" + origElem := elem + if l := len("id/"); len(elem) >= l && elem[0:l] == "id/" { + elem = elem[l:] + } else { + break + } + + // Param: "ScriptPolicyID" + // Leaf parameter + args[0] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch method { + case "DELETE": + r.name = DeleteScriptPolicyOperation + r.summary = "Delete the specified script policy by ID" + r.operationID = "deleteScriptPolicy" + r.pathPattern = "/script-policy/id/{ScriptPolicyID}" + r.args = args + r.count = 1 + return r, true + case "GET": + r.name = GetScriptPolicyOperation + r.summary = "Get the specified script policy by ID" + r.operationID = "getScriptPolicy" + r.pathPattern = "/script-policy/id/{ScriptPolicyID}" + r.args = args + r.count = 1 + return r, true + case "PATCH": + r.name = UpdateScriptPolicyOperation + r.summary = "Update the specified script policy by ID" + r.operationID = "updateScriptPolicy" + r.pathPattern = "/script-policy/id/{ScriptPolicyID}" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + } + + elem = origElem + } + + elem = origElem + case 's': // Prefix: "s" + origElem := elem + if l := len("s"); len(elem) >= l && elem[0:l] == "s" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "POST": + r.name = CreateScriptOperation + r.summary = "Create a new script" + r.operationID = "createScript" + r.pathPattern = "/scripts" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/" + origElem := elem + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + // Param: "ScriptID" + // Leaf parameter + args[0] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch method { + case "DELETE": + r.name = DeleteScriptOperation + r.summary = "Delete the specified script by ID" + r.operationID = "deleteScript" + r.pathPattern = "/scripts/{ScriptID}" + r.args = args + r.count = 1 + return r, true + case "GET": + r.name = GetScriptOperation + r.summary = "Get the specified script by ID" + r.operationID = "getScript" + r.pathPattern = "/scripts/{ScriptID}" + r.args = args + r.count = 1 + return r, true + case "PATCH": + r.name = UpdateScriptOperation + r.summary = "Update the specified script by ID" + r.operationID = "updateScript" + r.pathPattern = "/scripts/{ScriptID}" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + } + + elem = origElem + } + + elem = origElem + case 'u': // Prefix: "ubmissions" + origElem := elem + if l := len("ubmissions"); len(elem) >= l && elem[0:l] == "ubmissions" { + elem = elem[l:] + } else { + break } - args[0] = elem[:idx] - elem = elem[idx:] if len(elem) == 0 { switch method { case "GET": - r.name = GetSubmissionOperation - r.summary = "Retrieve map with ID" - r.operationID = "getSubmission" - r.pathPattern = "/submissions/{SubmissionID}" + r.name = ListSubmissionsOperation + r.summary = "Get list of submissions" + r.operationID = "listSubmissions" + r.pathPattern = "/submissions" r.args = args - r.count = 1 + r.count = 0 + return r, true + case "POST": + r.name = CreateSubmissionOperation + r.summary = "Create new submission" + r.operationID = "createSubmission" + r.pathPattern = "/submissions" + r.args = args + r.count = 0 return r, true default: return @@ -547,63 +920,33 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { break } + // Param: "SubmissionID" + // Match until "/" + idx := strings.IndexByte(elem, '/') + if idx < 0 { + idx = len(elem) + } + args[0] = elem[:idx] + elem = elem[idx:] + if len(elem) == 0 { - break + switch method { + case "GET": + r.name = GetSubmissionOperation + r.summary = "Retrieve map with ID" + r.operationID = "getSubmission" + r.pathPattern = "/submissions/{SubmissionID}" + r.args = args + r.count = 1 + return r, true + default: + return + } } switch elem[0] { - case 'c': // Prefix: "completed" + case '/': // Prefix: "/" origElem := elem - if l := len("completed"); len(elem) >= l && elem[0:l] == "completed" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch method { - case "PATCH": - r.name = PatchSubmissionCompletedOperation - r.summary = "Retrieve map with ID" - r.operationID = "patchSubmissionCompleted" - r.pathPattern = "/submissions/{SubmissionID}/completed" - r.args = args - r.count = 1 - return r, true - default: - return - } - } - - elem = origElem - case 'm': // Prefix: "model" - origElem := elem - if l := len("model"); len(elem) >= l && elem[0:l] == "model" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch method { - case "PATCH": - r.name = PatchSubmissionModelOperation - r.summary = "Update model following role restrictions" - r.operationID = "patchSubmissionModel" - r.pathPattern = "/submissions/{SubmissionID}/model" - r.args = args - r.count = 1 - return r, true - default: - return - } - } - - elem = origElem - case 's': // Prefix: "status/" - origElem := elem - if l := len("status/"); len(elem) >= l && elem[0:l] == "status/" { + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { elem = elem[l:] } else { break @@ -613,9 +956,9 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { break } switch elem[0] { - case 'p': // Prefix: "publish" + case 'c': // Prefix: "completed" origElem := elem - if l := len("publish"); len(elem) >= l && elem[0:l] == "publish" { + if l := len("completed"); len(elem) >= l && elem[0:l] == "completed" { elem = elem[l:] } else { break @@ -625,10 +968,10 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { // Leaf node. switch method { case "PATCH": - r.name = ActionSubmissionPublishOperation - r.summary = "Role Validator changes status from Publishing -> Published" - r.operationID = "actionSubmissionPublish" - r.pathPattern = "/submissions/{SubmissionID}/status/publish" + r.name = PatchSubmissionCompletedOperation + r.summary = "Retrieve map with ID" + r.operationID = "patchSubmissionCompleted" + r.pathPattern = "/submissions/{SubmissionID}/completed" r.args = args r.count = 1 return r, true @@ -638,99 +981,9 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { } elem = origElem - case 'r': // Prefix: "re" + case 'm': // Prefix: "model" origElem := elem - if l := len("re"); len(elem) >= l && elem[0:l] == "re" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - break - } - switch elem[0] { - case 'j': // Prefix: "ject" - origElem := elem - if l := len("ject"); len(elem) >= l && elem[0:l] == "ject" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch method { - case "PATCH": - r.name = ActionSubmissionRejectOperation - r.summary = "Role Reviewer changes status from Submitted -> Rejected" - r.operationID = "actionSubmissionReject" - r.pathPattern = "/submissions/{SubmissionID}/status/reject" - r.args = args - r.count = 1 - return r, true - default: - return - } - } - - elem = origElem - case 'q': // Prefix: "quest-changes" - origElem := elem - if l := len("quest-changes"); len(elem) >= l && elem[0:l] == "quest-changes" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch method { - case "PATCH": - r.name = ActionSubmissionRequestChangesOperation - r.summary = "Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested" - r.operationID = "actionSubmissionRequestChanges" - r.pathPattern = "/submissions/{SubmissionID}/status/request-changes" - r.args = args - r.count = 1 - return r, true - default: - return - } - } - - elem = origElem - case 'v': // Prefix: "voke" - origElem := elem - if l := len("voke"); len(elem) >= l && elem[0:l] == "voke" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch method { - case "PATCH": - r.name = ActionSubmissionRevokeOperation - r.summary = "Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction" - r.operationID = "actionSubmissionRevoke" - r.pathPattern = "/submissions/{SubmissionID}/status/revoke" - r.args = args - r.count = 1 - return r, true - default: - return - } - } - - elem = origElem - } - - elem = origElem - case 's': // Prefix: "submit" - origElem := elem - if l := len("submit"); len(elem) >= l && elem[0:l] == "submit" { + if l := len("model"); len(elem) >= l && elem[0:l] == "model" { elem = elem[l:] } else { break @@ -740,10 +993,10 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { // Leaf node. switch method { case "PATCH": - r.name = ActionSubmissionSubmitOperation - r.summary = "Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted" - r.operationID = "actionSubmissionSubmit" - r.pathPattern = "/submissions/{SubmissionID}/status/submit" + r.name = PatchSubmissionModelOperation + r.summary = "Update model following role restrictions" + r.operationID = "patchSubmissionModel" + r.pathPattern = "/submissions/{SubmissionID}/model" r.args = args r.count = 1 return r, true @@ -753,9 +1006,9 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { } elem = origElem - case 't': // Prefix: "trigger-" + case 's': // Prefix: "status/" origElem := elem - if l := len("trigger-"); len(elem) >= l && elem[0:l] == "trigger-" { + if l := len("status/"); len(elem) >= l && elem[0:l] == "status/" { elem = elem[l:] } else { break @@ -777,10 +1030,10 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { // Leaf node. switch method { case "PATCH": - r.name = ActionSubmissionTriggerPublishOperation - r.summary = "Role Admin changes status from Validated -> Publishing" - r.operationID = "actionSubmissionTriggerPublish" - r.pathPattern = "/submissions/{SubmissionID}/status/trigger-publish" + r.name = ActionSubmissionPublishOperation + r.summary = "Role Validator changes status from Publishing -> Published" + r.operationID = "actionSubmissionPublish" + r.pathPattern = "/submissions/{SubmissionID}/status/publish" r.args = args r.count = 1 return r, true @@ -789,6 +1042,186 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { } } + elem = origElem + case 'r': // Prefix: "re" + origElem := elem + if l := len("re"); len(elem) >= l && elem[0:l] == "re" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'j': // Prefix: "ject" + origElem := elem + if l := len("ject"); len(elem) >= l && elem[0:l] == "ject" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "PATCH": + r.name = ActionSubmissionRejectOperation + r.summary = "Role Reviewer changes status from Submitted -> Rejected" + r.operationID = "actionSubmissionReject" + r.pathPattern = "/submissions/{SubmissionID}/status/reject" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + case 'q': // Prefix: "quest-changes" + origElem := elem + if l := len("quest-changes"); len(elem) >= l && elem[0:l] == "quest-changes" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "PATCH": + r.name = ActionSubmissionRequestChangesOperation + r.summary = "Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested" + r.operationID = "actionSubmissionRequestChanges" + r.pathPattern = "/submissions/{SubmissionID}/status/request-changes" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + case 'v': // Prefix: "voke" + origElem := elem + if l := len("voke"); len(elem) >= l && elem[0:l] == "voke" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "PATCH": + r.name = ActionSubmissionRevokeOperation + r.summary = "Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction" + r.operationID = "actionSubmissionRevoke" + r.pathPattern = "/submissions/{SubmissionID}/status/revoke" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + } + + elem = origElem + case 's': // Prefix: "submit" + origElem := elem + if l := len("submit"); len(elem) >= l && elem[0:l] == "submit" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "PATCH": + r.name = ActionSubmissionSubmitOperation + r.summary = "Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted" + r.operationID = "actionSubmissionSubmit" + r.pathPattern = "/submissions/{SubmissionID}/status/submit" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + case 't': // Prefix: "trigger-" + origElem := elem + if l := len("trigger-"); len(elem) >= l && elem[0:l] == "trigger-" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'p': // Prefix: "publish" + origElem := elem + if l := len("publish"); len(elem) >= l && elem[0:l] == "publish" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "PATCH": + r.name = ActionSubmissionTriggerPublishOperation + r.summary = "Role Admin changes status from Validated -> Publishing" + r.operationID = "actionSubmissionTriggerPublish" + r.pathPattern = "/submissions/{SubmissionID}/status/trigger-publish" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + case 'v': // Prefix: "validate" + origElem := elem + if l := len("validate"); len(elem) >= l && elem[0:l] == "validate" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "PATCH": + r.name = ActionSubmissionTriggerValidateOperation + r.summary = "Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating" + r.operationID = "actionSubmissionTriggerValidate" + r.pathPattern = "/submissions/{SubmissionID}/status/trigger-validate" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + elem = origElem + } + elem = origElem case 'v': // Prefix: "validate" origElem := elem @@ -802,10 +1235,10 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { // Leaf node. switch method { case "PATCH": - r.name = ActionSubmissionTriggerValidateOperation - r.summary = "Role Reviewer triggers validation and changes status from Submitted|Accepted -> Validating" - r.operationID = "actionSubmissionTriggerValidate" - r.pathPattern = "/submissions/{SubmissionID}/status/trigger-validate" + r.name = ActionSubmissionValidateOperation + r.summary = "Role Validator changes status from Validating -> Validated" + r.operationID = "actionSubmissionValidate" + r.pathPattern = "/submissions/{SubmissionID}/status/validate" r.args = args r.count = 1 return r, true @@ -817,31 +1250,6 @@ func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { elem = origElem } - elem = origElem - case 'v': // Prefix: "validate" - origElem := elem - if l := len("validate"); len(elem) >= l && elem[0:l] == "validate" { - elem = elem[l:] - } else { - break - } - - if len(elem) == 0 { - // Leaf node. - switch method { - case "PATCH": - r.name = ActionSubmissionValidateOperation - r.summary = "Role Validator changes status from Validating -> Validated" - r.operationID = "actionSubmissionValidate" - r.pathPattern = "/submissions/{SubmissionID}/status/validate" - r.args = args - r.count = 1 - return r, true - default: - return - } - } - elem = origElem } diff --git a/pkg/api/oas_schemas_gen.go b/pkg/api/oas_schemas_gen.go index 34f451e..9fe955c 100644 --- a/pkg/api/oas_schemas_gen.go +++ b/pkg/api/oas_schemas_gen.go @@ -48,6 +48,12 @@ func (s *CookieAuth) SetAPIKey(val string) { s.APIKey = val } +// DeleteScriptOK is response for DeleteScript operation. +type DeleteScriptOK struct{} + +// DeleteScriptPolicyOK is response for DeleteScriptPolicy operation. +type DeleteScriptPolicyOK struct{} + // Represents error object. // Ref: #/components/schemas/Error type Error struct { @@ -103,65 +109,19 @@ func (s *ErrorStatusCode) SetResponse(val Error) { // Ref: #/components/schemas/Id type ID struct { - ID OptInt64 `json:"ID"` + ID int64 `json:"ID"` } // GetID returns the value of ID. -func (s *ID) GetID() OptInt64 { +func (s *ID) GetID() int64 { return s.ID } // SetID sets the value of ID. -func (s *ID) SetID(val OptInt64) { +func (s *ID) SetID(val int64) { s.ID = val } -// NewOptBool returns new OptBool with value set to v. -func NewOptBool(v bool) OptBool { - return OptBool{ - Value: v, - Set: true, - } -} - -// OptBool is optional bool. -type OptBool struct { - Value bool - Set bool -} - -// IsSet returns true if OptBool was set. -func (o OptBool) IsSet() bool { return o.Set } - -// Reset unsets value. -func (o *OptBool) Reset() { - var v bool - o.Value = v - o.Set = false -} - -// SetTo sets value to v. -func (o *OptBool) SetTo(v bool) { - o.Set = true - o.Value = v -} - -// Get returns value and boolean that denotes whether value was set. -func (o OptBool) Get() (v bool, ok bool) { - if !o.Set { - return v, false - } - return o.Value, true -} - -// Or returns value if set, or given parameter if does not. -func (o OptBool) Or(d bool) bool { - if v, ok := o.Get(); ok { - return v - } - return d -} - // NewOptInt32 returns new OptInt32 with value set to v. func NewOptInt32(v int32) OptInt32 { return OptInt32{ @@ -254,6 +214,190 @@ func (o OptInt64) Or(d int64) int64 { return d } +// NewOptScriptCreate returns new OptScriptCreate with value set to v. +func NewOptScriptCreate(v ScriptCreate) OptScriptCreate { + return OptScriptCreate{ + Value: v, + Set: true, + } +} + +// OptScriptCreate is optional ScriptCreate. +type OptScriptCreate struct { + Value ScriptCreate + Set bool +} + +// IsSet returns true if OptScriptCreate was set. +func (o OptScriptCreate) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptScriptCreate) Reset() { + var v ScriptCreate + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptScriptCreate) SetTo(v ScriptCreate) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptScriptCreate) Get() (v ScriptCreate, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptScriptCreate) Or(d ScriptCreate) ScriptCreate { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptScriptPolicyCreate returns new OptScriptPolicyCreate with value set to v. +func NewOptScriptPolicyCreate(v ScriptPolicyCreate) OptScriptPolicyCreate { + return OptScriptPolicyCreate{ + Value: v, + Set: true, + } +} + +// OptScriptPolicyCreate is optional ScriptPolicyCreate. +type OptScriptPolicyCreate struct { + Value ScriptPolicyCreate + Set bool +} + +// IsSet returns true if OptScriptPolicyCreate was set. +func (o OptScriptPolicyCreate) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptScriptPolicyCreate) Reset() { + var v ScriptPolicyCreate + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptScriptPolicyCreate) SetTo(v ScriptPolicyCreate) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptScriptPolicyCreate) Get() (v ScriptPolicyCreate, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptScriptPolicyCreate) Or(d ScriptPolicyCreate) ScriptPolicyCreate { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptScriptPolicyUpdate returns new OptScriptPolicyUpdate with value set to v. +func NewOptScriptPolicyUpdate(v ScriptPolicyUpdate) OptScriptPolicyUpdate { + return OptScriptPolicyUpdate{ + Value: v, + Set: true, + } +} + +// OptScriptPolicyUpdate is optional ScriptPolicyUpdate. +type OptScriptPolicyUpdate struct { + Value ScriptPolicyUpdate + Set bool +} + +// IsSet returns true if OptScriptPolicyUpdate was set. +func (o OptScriptPolicyUpdate) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptScriptPolicyUpdate) Reset() { + var v ScriptPolicyUpdate + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptScriptPolicyUpdate) SetTo(v ScriptPolicyUpdate) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptScriptPolicyUpdate) Get() (v ScriptPolicyUpdate, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptScriptPolicyUpdate) Or(d ScriptPolicyUpdate) ScriptPolicyUpdate { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptScriptUpdate returns new OptScriptUpdate with value set to v. +func NewOptScriptUpdate(v ScriptUpdate) OptScriptUpdate { + return OptScriptUpdate{ + Value: v, + Set: true, + } +} + +// OptScriptUpdate is optional ScriptUpdate. +type OptScriptUpdate struct { + Value ScriptUpdate + Set bool +} + +// IsSet returns true if OptScriptUpdate was set. +func (o OptScriptUpdate) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptScriptUpdate) Reset() { + var v ScriptUpdate + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptScriptUpdate) SetTo(v ScriptUpdate) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptScriptUpdate) Get() (v ScriptUpdate, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptScriptUpdate) Or(d ScriptUpdate) ScriptUpdate { + if v, ok := o.Get(); ok { + return v + } + return d +} + // NewOptString returns new OptString with value set to v. func NewOptString(v string) OptString { return OptString{ @@ -424,69 +568,313 @@ type PatchSubmissionCompletedOK struct{} // PatchSubmissionModelOK is response for PatchSubmissionModel operation. type PatchSubmissionModelOK struct{} -// Ref: #/components/schemas/Submission -type Submission struct { - ID OptInt64 `json:"ID"` - DisplayName OptString `json:"DisplayName"` - Creator OptString `json:"Creator"` - GameID OptInt32 `json:"GameID"` - Date OptInt64 `json:"Date"` - Submitter OptInt64 `json:"Submitter"` - AssetID OptInt64 `json:"AssetID"` - AssetVersion OptInt64 `json:"AssetVersion"` - Completed OptBool `json:"Completed"` - SubmissionType OptInt32 `json:"SubmissionType"` - TargetAssetID OptInt64 `json:"TargetAssetID"` - StatusID OptInt32 `json:"StatusID"` +// Ref: #/components/schemas/Script +type Script struct { + ID int64 `json:"ID"` + Hash string `json:"Hash"` + Source string `json:"Source"` + SubmissionID OptInt64 `json:"SubmissionID"` } // GetID returns the value of ID. -func (s *Submission) GetID() OptInt64 { +func (s *Script) GetID() int64 { + return s.ID +} + +// GetHash returns the value of Hash. +func (s *Script) GetHash() string { + return s.Hash +} + +// GetSource returns the value of Source. +func (s *Script) GetSource() string { + return s.Source +} + +// GetSubmissionID returns the value of SubmissionID. +func (s *Script) GetSubmissionID() OptInt64 { + return s.SubmissionID +} + +// SetID sets the value of ID. +func (s *Script) SetID(val int64) { + s.ID = val +} + +// SetHash sets the value of Hash. +func (s *Script) SetHash(val string) { + s.Hash = val +} + +// SetSource sets the value of Source. +func (s *Script) SetSource(val string) { + s.Source = val +} + +// SetSubmissionID sets the value of SubmissionID. +func (s *Script) SetSubmissionID(val OptInt64) { + s.SubmissionID = val +} + +// Ref: #/components/schemas/ScriptCreate +type ScriptCreate struct { + Source string `json:"Source"` + SubmissionID OptInt64 `json:"SubmissionID"` +} + +// GetSource returns the value of Source. +func (s *ScriptCreate) GetSource() string { + return s.Source +} + +// GetSubmissionID returns the value of SubmissionID. +func (s *ScriptCreate) GetSubmissionID() OptInt64 { + return s.SubmissionID +} + +// SetSource sets the value of Source. +func (s *ScriptCreate) SetSource(val string) { + s.Source = val +} + +// SetSubmissionID sets the value of SubmissionID. +func (s *ScriptCreate) SetSubmissionID(val OptInt64) { + s.SubmissionID = val +} + +// Ref: #/components/schemas/ScriptPolicy +type ScriptPolicy struct { + ID int64 `json:"ID"` + FromScriptHash string `json:"FromScriptHash"` + ToScriptID int64 `json:"ToScriptID"` + Policy int32 `json:"Policy"` +} + +// GetID returns the value of ID. +func (s *ScriptPolicy) GetID() int64 { + return s.ID +} + +// GetFromScriptHash returns the value of FromScriptHash. +func (s *ScriptPolicy) GetFromScriptHash() string { + return s.FromScriptHash +} + +// GetToScriptID returns the value of ToScriptID. +func (s *ScriptPolicy) GetToScriptID() int64 { + return s.ToScriptID +} + +// GetPolicy returns the value of Policy. +func (s *ScriptPolicy) GetPolicy() int32 { + return s.Policy +} + +// SetID sets the value of ID. +func (s *ScriptPolicy) SetID(val int64) { + s.ID = val +} + +// SetFromScriptHash sets the value of FromScriptHash. +func (s *ScriptPolicy) SetFromScriptHash(val string) { + s.FromScriptHash = val +} + +// SetToScriptID sets the value of ToScriptID. +func (s *ScriptPolicy) SetToScriptID(val int64) { + s.ToScriptID = val +} + +// SetPolicy sets the value of Policy. +func (s *ScriptPolicy) SetPolicy(val int32) { + s.Policy = val +} + +// Ref: #/components/schemas/ScriptPolicyCreate +type ScriptPolicyCreate struct { + FromScriptID int64 `json:"FromScriptID"` + ToScriptID int64 `json:"ToScriptID"` + Policy int32 `json:"Policy"` +} + +// GetFromScriptID returns the value of FromScriptID. +func (s *ScriptPolicyCreate) GetFromScriptID() int64 { + return s.FromScriptID +} + +// GetToScriptID returns the value of ToScriptID. +func (s *ScriptPolicyCreate) GetToScriptID() int64 { + return s.ToScriptID +} + +// GetPolicy returns the value of Policy. +func (s *ScriptPolicyCreate) GetPolicy() int32 { + return s.Policy +} + +// SetFromScriptID sets the value of FromScriptID. +func (s *ScriptPolicyCreate) SetFromScriptID(val int64) { + s.FromScriptID = val +} + +// SetToScriptID sets the value of ToScriptID. +func (s *ScriptPolicyCreate) SetToScriptID(val int64) { + s.ToScriptID = val +} + +// SetPolicy sets the value of Policy. +func (s *ScriptPolicyCreate) SetPolicy(val int32) { + s.Policy = val +} + +// Ref: #/components/schemas/ScriptPolicyUpdate +type ScriptPolicyUpdate struct { + ID int64 `json:"ID"` + FromScriptID OptInt64 `json:"FromScriptID"` + ToScriptID OptInt64 `json:"ToScriptID"` + Policy OptInt32 `json:"Policy"` +} + +// GetID returns the value of ID. +func (s *ScriptPolicyUpdate) GetID() int64 { + return s.ID +} + +// GetFromScriptID returns the value of FromScriptID. +func (s *ScriptPolicyUpdate) GetFromScriptID() OptInt64 { + return s.FromScriptID +} + +// GetToScriptID returns the value of ToScriptID. +func (s *ScriptPolicyUpdate) GetToScriptID() OptInt64 { + return s.ToScriptID +} + +// GetPolicy returns the value of Policy. +func (s *ScriptPolicyUpdate) GetPolicy() OptInt32 { + return s.Policy +} + +// SetID sets the value of ID. +func (s *ScriptPolicyUpdate) SetID(val int64) { + s.ID = val +} + +// SetFromScriptID sets the value of FromScriptID. +func (s *ScriptPolicyUpdate) SetFromScriptID(val OptInt64) { + s.FromScriptID = val +} + +// SetToScriptID sets the value of ToScriptID. +func (s *ScriptPolicyUpdate) SetToScriptID(val OptInt64) { + s.ToScriptID = val +} + +// SetPolicy sets the value of Policy. +func (s *ScriptPolicyUpdate) SetPolicy(val OptInt32) { + s.Policy = val +} + +// Ref: #/components/schemas/ScriptUpdate +type ScriptUpdate struct { + ID int64 `json:"ID"` + Source OptString `json:"Source"` + SubmissionID OptInt64 `json:"SubmissionID"` +} + +// GetID returns the value of ID. +func (s *ScriptUpdate) GetID() int64 { + return s.ID +} + +// GetSource returns the value of Source. +func (s *ScriptUpdate) GetSource() OptString { + return s.Source +} + +// GetSubmissionID returns the value of SubmissionID. +func (s *ScriptUpdate) GetSubmissionID() OptInt64 { + return s.SubmissionID +} + +// SetID sets the value of ID. +func (s *ScriptUpdate) SetID(val int64) { + s.ID = val +} + +// SetSource sets the value of Source. +func (s *ScriptUpdate) SetSource(val OptString) { + s.Source = val +} + +// SetSubmissionID sets the value of SubmissionID. +func (s *ScriptUpdate) SetSubmissionID(val OptInt64) { + s.SubmissionID = val +} + +// Ref: #/components/schemas/Submission +type Submission struct { + ID int64 `json:"ID"` + DisplayName string `json:"DisplayName"` + Creator string `json:"Creator"` + GameID int32 `json:"GameID"` + Date int64 `json:"Date"` + Submitter int64 `json:"Submitter"` + AssetID int64 `json:"AssetID"` + AssetVersion int64 `json:"AssetVersion"` + Completed bool `json:"Completed"` + SubmissionType int32 `json:"SubmissionType"` + TargetAssetID OptInt64 `json:"TargetAssetID"` + StatusID int32 `json:"StatusID"` +} + +// GetID returns the value of ID. +func (s *Submission) GetID() int64 { return s.ID } // GetDisplayName returns the value of DisplayName. -func (s *Submission) GetDisplayName() OptString { +func (s *Submission) GetDisplayName() string { return s.DisplayName } // GetCreator returns the value of Creator. -func (s *Submission) GetCreator() OptString { +func (s *Submission) GetCreator() string { return s.Creator } // GetGameID returns the value of GameID. -func (s *Submission) GetGameID() OptInt32 { +func (s *Submission) GetGameID() int32 { return s.GameID } // GetDate returns the value of Date. -func (s *Submission) GetDate() OptInt64 { +func (s *Submission) GetDate() int64 { return s.Date } // GetSubmitter returns the value of Submitter. -func (s *Submission) GetSubmitter() OptInt64 { +func (s *Submission) GetSubmitter() int64 { return s.Submitter } // GetAssetID returns the value of AssetID. -func (s *Submission) GetAssetID() OptInt64 { +func (s *Submission) GetAssetID() int64 { return s.AssetID } // GetAssetVersion returns the value of AssetVersion. -func (s *Submission) GetAssetVersion() OptInt64 { +func (s *Submission) GetAssetVersion() int64 { return s.AssetVersion } // GetCompleted returns the value of Completed. -func (s *Submission) GetCompleted() OptBool { +func (s *Submission) GetCompleted() bool { return s.Completed } // GetSubmissionType returns the value of SubmissionType. -func (s *Submission) GetSubmissionType() OptInt32 { +func (s *Submission) GetSubmissionType() int32 { return s.SubmissionType } @@ -496,57 +884,57 @@ func (s *Submission) GetTargetAssetID() OptInt64 { } // GetStatusID returns the value of StatusID. -func (s *Submission) GetStatusID() OptInt32 { +func (s *Submission) GetStatusID() int32 { return s.StatusID } // SetID sets the value of ID. -func (s *Submission) SetID(val OptInt64) { +func (s *Submission) SetID(val int64) { s.ID = val } // SetDisplayName sets the value of DisplayName. -func (s *Submission) SetDisplayName(val OptString) { +func (s *Submission) SetDisplayName(val string) { s.DisplayName = val } // SetCreator sets the value of Creator. -func (s *Submission) SetCreator(val OptString) { +func (s *Submission) SetCreator(val string) { s.Creator = val } // SetGameID sets the value of GameID. -func (s *Submission) SetGameID(val OptInt32) { +func (s *Submission) SetGameID(val int32) { s.GameID = val } // SetDate sets the value of Date. -func (s *Submission) SetDate(val OptInt64) { +func (s *Submission) SetDate(val int64) { s.Date = val } // SetSubmitter sets the value of Submitter. -func (s *Submission) SetSubmitter(val OptInt64) { +func (s *Submission) SetSubmitter(val int64) { s.Submitter = val } // SetAssetID sets the value of AssetID. -func (s *Submission) SetAssetID(val OptInt64) { +func (s *Submission) SetAssetID(val int64) { s.AssetID = val } // SetAssetVersion sets the value of AssetVersion. -func (s *Submission) SetAssetVersion(val OptInt64) { +func (s *Submission) SetAssetVersion(val int64) { s.AssetVersion = val } // SetCompleted sets the value of Completed. -func (s *Submission) SetCompleted(val OptBool) { +func (s *Submission) SetCompleted(val bool) { s.Completed = val } // SetSubmissionType sets the value of SubmissionType. -func (s *Submission) SetSubmissionType(val OptInt32) { +func (s *Submission) SetSubmissionType(val int32) { s.SubmissionType = val } @@ -556,54 +944,54 @@ func (s *Submission) SetTargetAssetID(val OptInt64) { } // SetStatusID sets the value of StatusID. -func (s *Submission) SetStatusID(val OptInt32) { +func (s *Submission) SetStatusID(val int32) { s.StatusID = val } // Ref: #/components/schemas/SubmissionCreate type SubmissionCreate struct { - DisplayName OptString `json:"DisplayName"` - Creator OptString `json:"Creator"` - GameID OptInt32 `json:"GameID"` - Submitter OptInt64 `json:"Submitter"` - AssetID OptInt64 `json:"AssetID"` - AssetVersion OptInt64 `json:"AssetVersion"` - SubmissionType OptInt32 `json:"SubmissionType"` - TargetAssetID OptInt64 `json:"TargetAssetID"` + DisplayName string `json:"DisplayName"` + Creator string `json:"Creator"` + GameID int32 `json:"GameID"` + Submitter int64 `json:"Submitter"` + AssetID int64 `json:"AssetID"` + AssetVersion int64 `json:"AssetVersion"` + SubmissionType int32 `json:"SubmissionType"` + TargetAssetID OptInt64 `json:"TargetAssetID"` } // GetDisplayName returns the value of DisplayName. -func (s *SubmissionCreate) GetDisplayName() OptString { +func (s *SubmissionCreate) GetDisplayName() string { return s.DisplayName } // GetCreator returns the value of Creator. -func (s *SubmissionCreate) GetCreator() OptString { +func (s *SubmissionCreate) GetCreator() string { return s.Creator } // GetGameID returns the value of GameID. -func (s *SubmissionCreate) GetGameID() OptInt32 { +func (s *SubmissionCreate) GetGameID() int32 { return s.GameID } // GetSubmitter returns the value of Submitter. -func (s *SubmissionCreate) GetSubmitter() OptInt64 { +func (s *SubmissionCreate) GetSubmitter() int64 { return s.Submitter } // GetAssetID returns the value of AssetID. -func (s *SubmissionCreate) GetAssetID() OptInt64 { +func (s *SubmissionCreate) GetAssetID() int64 { return s.AssetID } // GetAssetVersion returns the value of AssetVersion. -func (s *SubmissionCreate) GetAssetVersion() OptInt64 { +func (s *SubmissionCreate) GetAssetVersion() int64 { return s.AssetVersion } // GetSubmissionType returns the value of SubmissionType. -func (s *SubmissionCreate) GetSubmissionType() OptInt32 { +func (s *SubmissionCreate) GetSubmissionType() int32 { return s.SubmissionType } @@ -613,37 +1001,37 @@ func (s *SubmissionCreate) GetTargetAssetID() OptInt64 { } // SetDisplayName sets the value of DisplayName. -func (s *SubmissionCreate) SetDisplayName(val OptString) { +func (s *SubmissionCreate) SetDisplayName(val string) { s.DisplayName = val } // SetCreator sets the value of Creator. -func (s *SubmissionCreate) SetCreator(val OptString) { +func (s *SubmissionCreate) SetCreator(val string) { s.Creator = val } // SetGameID sets the value of GameID. -func (s *SubmissionCreate) SetGameID(val OptInt32) { +func (s *SubmissionCreate) SetGameID(val int32) { s.GameID = val } // SetSubmitter sets the value of Submitter. -func (s *SubmissionCreate) SetSubmitter(val OptInt64) { +func (s *SubmissionCreate) SetSubmitter(val int64) { s.Submitter = val } // SetAssetID sets the value of AssetID. -func (s *SubmissionCreate) SetAssetID(val OptInt64) { +func (s *SubmissionCreate) SetAssetID(val int64) { s.AssetID = val } // SetAssetVersion sets the value of AssetVersion. -func (s *SubmissionCreate) SetAssetVersion(val OptInt64) { +func (s *SubmissionCreate) SetAssetVersion(val int64) { s.AssetVersion = val } // SetSubmissionType sets the value of SubmissionType. -func (s *SubmissionCreate) SetSubmissionType(val OptInt32) { +func (s *SubmissionCreate) SetSubmissionType(val int32) { s.SubmissionType = val } @@ -654,7 +1042,7 @@ func (s *SubmissionCreate) SetTargetAssetID(val OptInt64) { // Ref: #/components/schemas/SubmissionFilter type SubmissionFilter struct { - ID OptInt64 `json:"ID"` + ID int64 `json:"ID"` DisplayName OptString `json:"DisplayName"` Creator OptString `json:"Creator"` GameID OptInt32 `json:"GameID"` @@ -662,7 +1050,7 @@ type SubmissionFilter struct { } // GetID returns the value of ID. -func (s *SubmissionFilter) GetID() OptInt64 { +func (s *SubmissionFilter) GetID() int64 { return s.ID } @@ -687,7 +1075,7 @@ func (s *SubmissionFilter) GetDate() OptInt64 { } // SetID sets the value of ID. -func (s *SubmissionFilter) SetID(val OptInt64) { +func (s *SubmissionFilter) SetID(val int64) { s.ID = val } @@ -710,3 +1098,9 @@ func (s *SubmissionFilter) SetGameID(val OptInt32) { func (s *SubmissionFilter) SetDate(val OptInt64) { s.Date = val } + +// UpdateScriptOK is response for UpdateScript operation. +type UpdateScriptOK struct{} + +// UpdateScriptPolicyOK is response for UpdateScriptPolicy operation. +type UpdateScriptPolicyOK struct{} diff --git a/pkg/api/oas_server_gen.go b/pkg/api/oas_server_gen.go index dffbfd3..1b5afa3 100644 --- a/pkg/api/oas_server_gen.go +++ b/pkg/api/oas_server_gen.go @@ -56,12 +56,54 @@ type Handler interface { // // PATCH /submissions/{SubmissionID}/status/validate ActionSubmissionValidate(ctx context.Context, params ActionSubmissionValidateParams) error + // CreateScript implements createScript operation. + // + // Create a new script. + // + // POST /scripts + CreateScript(ctx context.Context, req OptScriptCreate) (*ID, error) + // CreateScriptPolicy implements createScriptPolicy operation. + // + // Create a new script policy. + // + // POST /script-policy + CreateScriptPolicy(ctx context.Context, req OptScriptPolicyCreate) (*ID, error) // CreateSubmission implements createSubmission operation. // // Create new submission. // // POST /submissions CreateSubmission(ctx context.Context, req OptSubmissionCreate) (*ID, error) + // DeleteScript implements deleteScript operation. + // + // Delete the specified script by ID. + // + // DELETE /scripts/{ScriptID} + DeleteScript(ctx context.Context, params DeleteScriptParams) error + // DeleteScriptPolicy implements deleteScriptPolicy operation. + // + // Delete the specified script policy by ID. + // + // DELETE /script-policy/id/{ScriptPolicyID} + DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error + // GetScript implements getScript operation. + // + // Get the specified script by ID. + // + // GET /scripts/{ScriptID} + GetScript(ctx context.Context, params GetScriptParams) (*Script, error) + // GetScriptPolicy implements getScriptPolicy operation. + // + // Get the specified script policy by ID. + // + // GET /script-policy/id/{ScriptPolicyID} + GetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (*ScriptPolicy, error) + // GetScriptPolicyFromHash implements getScriptPolicyFromHash operation. + // + // Get the policy for the given hash of script source code. + // + // GET /script-policy/hash/{FromScriptHash} + GetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (*ScriptPolicy, error) // GetSubmission implements getSubmission operation. // // Retrieve map with ID. @@ -86,6 +128,18 @@ type Handler interface { // // PATCH /submissions/{SubmissionID}/model PatchSubmissionModel(ctx context.Context, params PatchSubmissionModelParams) error + // UpdateScript implements updateScript operation. + // + // Update the specified script by ID. + // + // PATCH /scripts/{ScriptID} + UpdateScript(ctx context.Context, req OptScriptUpdate, params UpdateScriptParams) error + // UpdateScriptPolicy implements updateScriptPolicy operation. + // + // Update the specified script policy by ID. + // + // PATCH /script-policy/id/{ScriptPolicyID} + UpdateScriptPolicy(ctx context.Context, req OptScriptPolicyUpdate, params UpdateScriptPolicyParams) error // NewError creates *ErrorStatusCode from error returned by handler. // // Used for common default response. diff --git a/pkg/api/oas_unimplemented_gen.go b/pkg/api/oas_unimplemented_gen.go index ee67f65..94afd3e 100644 --- a/pkg/api/oas_unimplemented_gen.go +++ b/pkg/api/oas_unimplemented_gen.go @@ -85,6 +85,24 @@ func (UnimplementedHandler) ActionSubmissionValidate(ctx context.Context, params return ht.ErrNotImplemented } +// CreateScript implements createScript operation. +// +// Create a new script. +// +// POST /scripts +func (UnimplementedHandler) CreateScript(ctx context.Context, req OptScriptCreate) (r *ID, _ error) { + return r, ht.ErrNotImplemented +} + +// CreateScriptPolicy implements createScriptPolicy operation. +// +// Create a new script policy. +// +// POST /script-policy +func (UnimplementedHandler) CreateScriptPolicy(ctx context.Context, req OptScriptPolicyCreate) (r *ID, _ error) { + return r, ht.ErrNotImplemented +} + // CreateSubmission implements createSubmission operation. // // Create new submission. @@ -94,6 +112,51 @@ func (UnimplementedHandler) CreateSubmission(ctx context.Context, req OptSubmiss return r, ht.ErrNotImplemented } +// DeleteScript implements deleteScript operation. +// +// Delete the specified script by ID. +// +// DELETE /scripts/{ScriptID} +func (UnimplementedHandler) DeleteScript(ctx context.Context, params DeleteScriptParams) error { + return ht.ErrNotImplemented +} + +// DeleteScriptPolicy implements deleteScriptPolicy operation. +// +// Delete the specified script policy by ID. +// +// DELETE /script-policy/id/{ScriptPolicyID} +func (UnimplementedHandler) DeleteScriptPolicy(ctx context.Context, params DeleteScriptPolicyParams) error { + return ht.ErrNotImplemented +} + +// GetScript implements getScript operation. +// +// Get the specified script by ID. +// +// GET /scripts/{ScriptID} +func (UnimplementedHandler) GetScript(ctx context.Context, params GetScriptParams) (r *Script, _ error) { + return r, ht.ErrNotImplemented +} + +// GetScriptPolicy implements getScriptPolicy operation. +// +// Get the specified script policy by ID. +// +// GET /script-policy/id/{ScriptPolicyID} +func (UnimplementedHandler) GetScriptPolicy(ctx context.Context, params GetScriptPolicyParams) (r *ScriptPolicy, _ error) { + return r, ht.ErrNotImplemented +} + +// GetScriptPolicyFromHash implements getScriptPolicyFromHash operation. +// +// Get the policy for the given hash of script source code. +// +// GET /script-policy/hash/{FromScriptHash} +func (UnimplementedHandler) GetScriptPolicyFromHash(ctx context.Context, params GetScriptPolicyFromHashParams) (r *ScriptPolicy, _ error) { + return r, ht.ErrNotImplemented +} + // GetSubmission implements getSubmission operation. // // Retrieve map with ID. @@ -130,6 +193,24 @@ func (UnimplementedHandler) PatchSubmissionModel(ctx context.Context, params Pat return ht.ErrNotImplemented } +// UpdateScript implements updateScript operation. +// +// Update the specified script by ID. +// +// PATCH /scripts/{ScriptID} +func (UnimplementedHandler) UpdateScript(ctx context.Context, req OptScriptUpdate, params UpdateScriptParams) error { + return ht.ErrNotImplemented +} + +// UpdateScriptPolicy implements updateScriptPolicy operation. +// +// Update the specified script policy by ID. +// +// PATCH /script-policy/id/{ScriptPolicyID} +func (UnimplementedHandler) UpdateScriptPolicy(ctx context.Context, req OptScriptPolicyUpdate, params UpdateScriptPolicyParams) error { + return ht.ErrNotImplemented +} + // NewError creates *ErrorStatusCode from error returned by handler. // // Used for common default response. diff --git a/pkg/api/oas_uri_gen.go b/pkg/api/oas_uri_gen.go index 9132613..c5ae0d3 100644 --- a/pkg/api/oas_uri_gen.go +++ b/pkg/api/oas_uri_gen.go @@ -124,10 +124,7 @@ func (s *Pagination) DecodeURI(d uri.Decoder) error { // EncodeURI encodes SubmissionFilter as URI form. func (s *SubmissionFilter) EncodeURI(e uri.Encoder) error { if err := e.EncodeField("ID", func(e uri.Encoder) error { - if val, ok := s.ID.Get(); ok { - return e.EncodeValue(conv.Int64ToString(val)) - } - return nil + return e.EncodeValue(conv.Int64ToString(s.ID)) }); err != nil { return errors.Wrap(err, "encode field \"ID\"") } @@ -179,29 +176,24 @@ func (s *SubmissionFilter) DecodeURI(d uri.Decoder) error { if s == nil { return errors.New("invalid: unable to decode SubmissionFilter to nil") } + var requiredBitSet [1]uint8 if err := d.DecodeFields(func(k string, d uri.Decoder) error { switch k { case "ID": + requiredBitSet[0] |= 1 << 0 if err := func() error { - var sDotIDVal int64 - if err := func() error { - val, err := d.DecodeValue() - if err != nil { - return err - } - - c, err := conv.ToInt64(val) - if err != nil { - return err - } - - sDotIDVal = c - return nil - }(); err != nil { + val, err := d.DecodeValue() + if err != nil { return err } - s.ID.SetTo(sDotIDVal) + + c, err := conv.ToInt64(val) + if err != nil { + return err + } + + s.ID = c return nil }(); err != nil { return errors.Wrap(err, "decode field \"ID\"") @@ -309,6 +301,38 @@ func (s *SubmissionFilter) DecodeURI(d uri.Decoder) error { }); err != nil { return errors.Wrap(err, "decode SubmissionFilter") } + // 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(uriFieldsNameOfSubmissionFilter) { + name = uriFieldsNameOfSubmissionFilter[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 }