// Code generated by ogen, DO NOT EDIT. package api import ( "context" "net/http" "time" "github.com/go-faster/errors" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" semconv "go.opentelemetry.io/otel/semconv/v1.26.0" "go.opentelemetry.io/otel/trace" ht "github.com/ogen-go/ogen/http" "github.com/ogen-go/ogen/middleware" "github.com/ogen-go/ogen/ogenerrors" "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) } // handleActionMapfixAcceptedRequest handles actionMapfixAccepted operation. // // Role Reviewer manually resets validating softlock and changes status from Validating -> Accepted. // // POST /mapfixes/{MapfixID}/status/reset-validating func (s *Server) handleActionMapfixAcceptedRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixAccepted"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/reset-validating"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixAcceptedOperation, 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: ActionMapfixAcceptedOperation, ID: "actionMapfixAccepted", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixAcceptedOperation, 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 := decodeActionMapfixAcceptedParams(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 *ActionMapfixAcceptedNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixAcceptedOperation, OperationSummary: "Role Reviewer manually resets validating softlock and changes status from Validating -> Accepted", OperationID: "actionMapfixAccepted", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixAcceptedParams Response = *ActionMapfixAcceptedNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixAcceptedParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixAccepted(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixAccepted(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 := encodeActionMapfixAcceptedResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionMapfixRejectRequest handles actionMapfixReject operation. // // Role Reviewer changes status from Submitted -> Rejected. // // POST /mapfixes/{MapfixID}/status/reject func (s *Server) handleActionMapfixRejectRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixReject"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/reject"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixRejectOperation, 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: ActionMapfixRejectOperation, ID: "actionMapfixReject", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixRejectOperation, 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 := decodeActionMapfixRejectParams(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 *ActionMapfixRejectNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixRejectOperation, OperationSummary: "Role Reviewer changes status from Submitted -> Rejected", OperationID: "actionMapfixReject", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixRejectParams Response = *ActionMapfixRejectNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixRejectParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixReject(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixReject(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 := encodeActionMapfixRejectResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionMapfixRequestChangesRequest handles actionMapfixRequestChanges operation. // // Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested. // // POST /mapfixes/{MapfixID}/status/request-changes func (s *Server) handleActionMapfixRequestChangesRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixRequestChanges"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/request-changes"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixRequestChangesOperation, 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: ActionMapfixRequestChangesOperation, ID: "actionMapfixRequestChanges", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixRequestChangesOperation, 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 := decodeActionMapfixRequestChangesParams(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 *ActionMapfixRequestChangesNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixRequestChangesOperation, OperationSummary: "Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested", OperationID: "actionMapfixRequestChanges", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixRequestChangesParams Response = *ActionMapfixRequestChangesNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixRequestChangesParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixRequestChanges(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixRequestChanges(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 := encodeActionMapfixRequestChangesResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionMapfixRetryValidateRequest handles actionMapfixRetryValidate operation. // // Role Reviewer re-runs validation and changes status from Accepted -> Validating. // // POST /mapfixes/{MapfixID}/status/retry-validate func (s *Server) handleActionMapfixRetryValidateRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixRetryValidate"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/retry-validate"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixRetryValidateOperation, 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: ActionMapfixRetryValidateOperation, ID: "actionMapfixRetryValidate", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixRetryValidateOperation, 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 := decodeActionMapfixRetryValidateParams(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 *ActionMapfixRetryValidateNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixRetryValidateOperation, OperationSummary: "Role Reviewer re-runs validation and changes status from Accepted -> Validating", OperationID: "actionMapfixRetryValidate", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixRetryValidateParams Response = *ActionMapfixRetryValidateNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixRetryValidateParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixRetryValidate(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixRetryValidate(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 := encodeActionMapfixRetryValidateResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionMapfixRevokeRequest handles actionMapfixRevoke operation. // // Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction. // // POST /mapfixes/{MapfixID}/status/revoke func (s *Server) handleActionMapfixRevokeRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixRevoke"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/revoke"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixRevokeOperation, 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: ActionMapfixRevokeOperation, ID: "actionMapfixRevoke", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixRevokeOperation, 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 := decodeActionMapfixRevokeParams(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 *ActionMapfixRevokeNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixRevokeOperation, OperationSummary: "Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction", OperationID: "actionMapfixRevoke", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixRevokeParams Response = *ActionMapfixRevokeNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixRevokeParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixRevoke(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixRevoke(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 := encodeActionMapfixRevokeResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionMapfixSubmitRequest handles actionMapfixSubmit operation. // // Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted. // // POST /mapfixes/{MapfixID}/status/submit func (s *Server) handleActionMapfixSubmitRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixSubmit"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/submit"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixSubmitOperation, 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: ActionMapfixSubmitOperation, ID: "actionMapfixSubmit", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixSubmitOperation, 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 := decodeActionMapfixSubmitParams(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 *ActionMapfixSubmitNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixSubmitOperation, OperationSummary: "Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted", OperationID: "actionMapfixSubmit", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixSubmitParams Response = *ActionMapfixSubmitNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixSubmitParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixSubmit(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixSubmit(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 := encodeActionMapfixSubmitResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionMapfixTriggerUploadRequest handles actionMapfixTriggerUpload operation. // // Role Admin changes status from Validated -> Uploading. // // POST /mapfixes/{MapfixID}/status/trigger-upload func (s *Server) handleActionMapfixTriggerUploadRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixTriggerUpload"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/trigger-upload"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixTriggerUploadOperation, 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: ActionMapfixTriggerUploadOperation, ID: "actionMapfixTriggerUpload", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixTriggerUploadOperation, 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 := decodeActionMapfixTriggerUploadParams(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 *ActionMapfixTriggerUploadNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixTriggerUploadOperation, OperationSummary: "Role Admin changes status from Validated -> Uploading", OperationID: "actionMapfixTriggerUpload", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixTriggerUploadParams Response = *ActionMapfixTriggerUploadNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixTriggerUploadParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixTriggerUpload(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixTriggerUpload(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 := encodeActionMapfixTriggerUploadResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionMapfixTriggerValidateRequest handles actionMapfixTriggerValidate operation. // // Role Reviewer triggers validation and changes status from Submitted -> Validating. // // POST /mapfixes/{MapfixID}/status/trigger-validate func (s *Server) handleActionMapfixTriggerValidateRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixTriggerValidate"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/trigger-validate"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixTriggerValidateOperation, 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: ActionMapfixTriggerValidateOperation, ID: "actionMapfixTriggerValidate", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixTriggerValidateOperation, 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 := decodeActionMapfixTriggerValidateParams(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 *ActionMapfixTriggerValidateNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixTriggerValidateOperation, OperationSummary: "Role Reviewer triggers validation and changes status from Submitted -> Validating", OperationID: "actionMapfixTriggerValidate", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixTriggerValidateParams Response = *ActionMapfixTriggerValidateNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixTriggerValidateParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixTriggerValidate(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixTriggerValidate(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 := encodeActionMapfixTriggerValidateResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionMapfixValidatedRequest handles actionMapfixValidated operation. // // Role Admin manually resets uploading softlock and changes status from Uploading -> Validated. // // POST /mapfixes/{MapfixID}/status/reset-uploading func (s *Server) handleActionMapfixValidatedRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionMapfixValidated"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/status/reset-uploading"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionMapfixValidatedOperation, 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: ActionMapfixValidatedOperation, ID: "actionMapfixValidated", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionMapfixValidatedOperation, 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 := decodeActionMapfixValidatedParams(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 *ActionMapfixValidatedNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionMapfixValidatedOperation, OperationSummary: "Role Admin manually resets uploading softlock and changes status from Uploading -> Validated", OperationID: "actionMapfixValidated", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = ActionMapfixValidatedParams Response = *ActionMapfixValidatedNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionMapfixValidatedParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionMapfixValidated(ctx, params) return response, err }, ) } else { err = s.h.ActionMapfixValidated(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 := encodeActionMapfixValidatedResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionAcceptedRequest handles actionSubmissionAccepted operation. // // Role Reviewer manually resets validating softlock and changes status from Validating -> Accepted. // // POST /submissions/{SubmissionID}/status/reset-validating func (s *Server) handleActionSubmissionAcceptedRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionAccepted"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/reset-validating"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionAcceptedOperation, 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: ActionSubmissionAcceptedOperation, ID: "actionSubmissionAccepted", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionAcceptedOperation, 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 := decodeActionSubmissionAcceptedParams(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 *ActionSubmissionAcceptedNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionAcceptedOperation, OperationSummary: "Role Reviewer manually resets validating softlock and changes status from Validating -> Accepted", OperationID: "actionSubmissionAccepted", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionAcceptedParams Response = *ActionSubmissionAcceptedNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionAcceptedParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionAccepted(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionAccepted(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 := encodeActionSubmissionAcceptedResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionRejectRequest handles actionSubmissionReject operation. // // Role Reviewer changes status from Submitted -> Rejected. // // POST /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("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/reject"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionRejectOperation, 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: ActionSubmissionRejectOperation, ID: "actionSubmissionReject", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionRejectOperation, 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 := decodeActionSubmissionRejectParams(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 *ActionSubmissionRejectNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionRejectOperation, OperationSummary: "Role Reviewer changes status from Submitted -> Rejected", OperationID: "actionSubmissionReject", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionRejectParams Response = *ActionSubmissionRejectNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionRejectParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionReject(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionReject(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 := encodeActionSubmissionRejectResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionRequestChangesRequest handles actionSubmissionRequestChanges operation. // // Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested. // // POST /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("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/request-changes"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionRequestChangesOperation, 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: ActionSubmissionRequestChangesOperation, ID: "actionSubmissionRequestChanges", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionRequestChangesOperation, 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 := decodeActionSubmissionRequestChangesParams(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 *ActionSubmissionRequestChangesNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionRequestChangesOperation, OperationSummary: "Role Reviewer changes status from Validated|Accepted|Submitted -> ChangesRequested", OperationID: "actionSubmissionRequestChanges", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionRequestChangesParams Response = *ActionSubmissionRequestChangesNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionRequestChangesParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionRequestChanges(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionRequestChanges(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 := encodeActionSubmissionRequestChangesResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionRetryValidateRequest handles actionSubmissionRetryValidate operation. // // Role Reviewer re-runs validation and changes status from Accepted -> Validating. // // POST /submissions/{SubmissionID}/status/retry-validate func (s *Server) handleActionSubmissionRetryValidateRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionRetryValidate"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/retry-validate"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionRetryValidateOperation, 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: ActionSubmissionRetryValidateOperation, ID: "actionSubmissionRetryValidate", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionRetryValidateOperation, 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 := decodeActionSubmissionRetryValidateParams(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 *ActionSubmissionRetryValidateNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionRetryValidateOperation, OperationSummary: "Role Reviewer re-runs validation and changes status from Accepted -> Validating", OperationID: "actionSubmissionRetryValidate", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionRetryValidateParams Response = *ActionSubmissionRetryValidateNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionRetryValidateParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionRetryValidate(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionRetryValidate(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 := encodeActionSubmissionRetryValidateResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionRevokeRequest handles actionSubmissionRevoke operation. // // Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction. // // POST /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("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/revoke"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionRevokeOperation, 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: ActionSubmissionRevokeOperation, ID: "actionSubmissionRevoke", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionRevokeOperation, 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 := decodeActionSubmissionRevokeParams(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 *ActionSubmissionRevokeNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionRevokeOperation, OperationSummary: "Role Submitter changes status from Submitted|ChangesRequested -> UnderConstruction", OperationID: "actionSubmissionRevoke", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionRevokeParams Response = *ActionSubmissionRevokeNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionRevokeParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionRevoke(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionRevoke(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 := encodeActionSubmissionRevokeResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionSubmitRequest handles actionSubmissionSubmit operation. // // Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted. // // POST /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("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/submit"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionSubmitOperation, 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: ActionSubmissionSubmitOperation, ID: "actionSubmissionSubmit", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionSubmitOperation, 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 := decodeActionSubmissionSubmitParams(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 *ActionSubmissionSubmitNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionSubmitOperation, OperationSummary: "Role Submitter changes status from UnderConstruction|ChangesRequested -> Submitted", OperationID: "actionSubmissionSubmit", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionSubmitParams Response = *ActionSubmissionSubmitNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionSubmitParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionSubmit(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionSubmit(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 := encodeActionSubmissionSubmitResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionTriggerUploadRequest handles actionSubmissionTriggerUpload operation. // // Role Admin changes status from Validated -> Uploading. // // POST /submissions/{SubmissionID}/status/trigger-upload func (s *Server) handleActionSubmissionTriggerUploadRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionTriggerUpload"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/trigger-upload"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionTriggerUploadOperation, 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: ActionSubmissionTriggerUploadOperation, ID: "actionSubmissionTriggerUpload", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionTriggerUploadOperation, 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 := decodeActionSubmissionTriggerUploadParams(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 *ActionSubmissionTriggerUploadNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionTriggerUploadOperation, OperationSummary: "Role Admin changes status from Validated -> Uploading", OperationID: "actionSubmissionTriggerUpload", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionTriggerUploadParams Response = *ActionSubmissionTriggerUploadNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionTriggerUploadParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionTriggerUpload(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionTriggerUpload(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 := encodeActionSubmissionTriggerUploadResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionTriggerValidateRequest handles actionSubmissionTriggerValidate operation. // // Role Reviewer triggers validation and changes status from Submitted -> Validating. // // POST /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("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/trigger-validate"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionTriggerValidateOperation, 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: ActionSubmissionTriggerValidateOperation, ID: "actionSubmissionTriggerValidate", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionTriggerValidateOperation, 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 := decodeActionSubmissionTriggerValidateParams(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 *ActionSubmissionTriggerValidateNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionTriggerValidateOperation, OperationSummary: "Role Reviewer triggers validation and changes status from Submitted -> Validating", OperationID: "actionSubmissionTriggerValidate", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionTriggerValidateParams Response = *ActionSubmissionTriggerValidateNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionTriggerValidateParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionTriggerValidate(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionTriggerValidate(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 := encodeActionSubmissionTriggerValidateResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleActionSubmissionValidatedRequest handles actionSubmissionValidated operation. // // Role Admin manually resets uploading softlock and changes status from Uploading -> Validated. // // POST /submissions/{SubmissionID}/status/reset-uploading func (s *Server) handleActionSubmissionValidatedRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("actionSubmissionValidated"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/status/reset-uploading"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ActionSubmissionValidatedOperation, 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: ActionSubmissionValidatedOperation, ID: "actionSubmissionValidated", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ActionSubmissionValidatedOperation, 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 := decodeActionSubmissionValidatedParams(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 *ActionSubmissionValidatedNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ActionSubmissionValidatedOperation, OperationSummary: "Role Admin manually resets uploading softlock and changes status from Uploading -> Validated", OperationID: "actionSubmissionValidated", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = ActionSubmissionValidatedParams Response = *ActionSubmissionValidatedNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackActionSubmissionValidatedParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ActionSubmissionValidated(ctx, params) return response, err }, ) } else { err = s.h.ActionSubmissionValidated(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 := encodeActionSubmissionValidatedResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleCreateMapfixRequest handles createMapfix operation. // // Create new mapfix. // // POST /mapfixes func (s *Server) handleCreateMapfixRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("createMapfix"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), CreateMapfixOperation, 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: CreateMapfixOperation, ID: "createMapfix", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, CreateMapfixOperation, 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.decodeCreateMapfixRequest(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: CreateMapfixOperation, OperationSummary: "Create new mapfix", OperationID: "createMapfix", Body: request, Params: middleware.Parameters{}, Raw: r, } type ( Request = *MapfixCreate 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.CreateMapfix(ctx, request) return response, err }, ) } else { response, err = s.h.CreateMapfix(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 := encodeCreateMapfixResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // 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 = *ScriptCreate 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 = *ScriptPolicyCreate 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"), semconv.HTTPRouteKey.String("/submissions"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), CreateSubmissionOperation, 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: CreateSubmissionOperation, ID: "createSubmission", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, CreateSubmissionOperation, 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.decodeCreateSubmissionRequest(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: CreateSubmissionOperation, OperationSummary: "Create new submission", OperationID: "createSubmission", Body: request, Params: middleware.Parameters{}, Raw: r, } type ( Request = *SubmissionCreate 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.CreateSubmission(ctx, request) return response, err }, ) } else { response, err = s.h.CreateSubmission(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 := encodeCreateSubmissionResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // 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 *DeleteScriptNoContent 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 = *DeleteScriptNoContent ) 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/{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/{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 *DeleteScriptPolicyNoContent 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 = *DeleteScriptPolicyNoContent ) 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 } } // handleGetMapfixRequest handles getMapfix operation. // // Retrieve map with ID. // // GET /mapfixes/{MapfixID} func (s *Server) handleGetMapfixRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("getMapfix"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), GetMapfixOperation, 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: GetMapfixOperation, ID: "getMapfix", } ) params, err := decodeGetMapfixParams(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 *Mapfix if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: GetMapfixOperation, OperationSummary: "Retrieve map with ID", OperationID: "getMapfix", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = GetMapfixParams Response = *Mapfix ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackGetMapfixParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { response, err = s.h.GetMapfix(ctx, params) return response, err }, ) } else { response, err = s.h.GetMapfix(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 := encodeGetMapfixResponse(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", } ) 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/{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/{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", } ) 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 } } // 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"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), GetSubmissionOperation, 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: GetSubmissionOperation, ID: "getSubmission", } ) params, err := decodeGetSubmissionParams(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 *Submission if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: GetSubmissionOperation, OperationSummary: "Retrieve map with ID", OperationID: "getSubmission", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = GetSubmissionParams Response = *Submission ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackGetSubmissionParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { response, err = s.h.GetSubmission(ctx, params) return response, err }, ) } else { response, err = s.h.GetSubmission(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 := encodeGetSubmissionResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleListMapfixesRequest handles listMapfixes operation. // // Get list of mapfixes. // // GET /mapfixes func (s *Server) handleListMapfixesRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("listMapfixes"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/mapfixes"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ListMapfixesOperation, 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: ListMapfixesOperation, ID: "listMapfixes", } ) params, err := decodeListMapfixesParams(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 []Mapfix if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ListMapfixesOperation, OperationSummary: "Get list of mapfixes", OperationID: "listMapfixes", Body: nil, Params: middleware.Parameters{ { Name: "Page", In: "query", }: params.Page, { Name: "Limit", In: "query", }: params.Limit, { Name: "DisplayName", In: "query", }: params.DisplayName, { Name: "Creator", In: "query", }: params.Creator, { Name: "GameID", In: "query", }: params.GameID, { Name: "Sort", In: "query", }: params.Sort, }, Raw: r, } type ( Request = struct{} Params = ListMapfixesParams Response = []Mapfix ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackListMapfixesParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { response, err = s.h.ListMapfixes(ctx, params) return response, err }, ) } else { response, err = s.h.ListMapfixes(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 := encodeListMapfixesResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleListScriptPolicyRequest handles listScriptPolicy operation. // // Get list of script policies. // // GET /script-policy func (s *Server) handleListScriptPolicyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("listScriptPolicy"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/script-policy"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ListScriptPolicyOperation, 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: ListScriptPolicyOperation, ID: "listScriptPolicy", } ) params, err := decodeListScriptPolicyParams(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: ListScriptPolicyOperation, OperationSummary: "Get list of script policies", OperationID: "listScriptPolicy", Body: nil, Params: middleware.Parameters{ { Name: "Page", In: "query", }: params.Page, { Name: "Limit", In: "query", }: params.Limit, { Name: "FromScriptHash", In: "query", }: params.FromScriptHash, { Name: "ToScriptID", In: "query", }: params.ToScriptID, { Name: "Policy", In: "query", }: params.Policy, }, Raw: r, } type ( Request = struct{} Params = ListScriptPolicyParams Response = []ScriptPolicy ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackListScriptPolicyParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { response, err = s.h.ListScriptPolicy(ctx, params) return response, err }, ) } else { response, err = s.h.ListScriptPolicy(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 := encodeListScriptPolicyResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleListScriptsRequest handles listScripts operation. // // Get list of scripts. // // GET /scripts func (s *Server) handleListScriptsRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("listScripts"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/scripts"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ListScriptsOperation, 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: ListScriptsOperation, ID: "listScripts", } ) params, err := decodeListScriptsParams(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: ListScriptsOperation, OperationSummary: "Get list of scripts", OperationID: "listScripts", Body: nil, Params: middleware.Parameters{ { Name: "Page", In: "query", }: params.Page, { Name: "Limit", In: "query", }: params.Limit, { Name: "Hash", In: "query", }: params.Hash, { Name: "Name", In: "query", }: params.Name, { Name: "Source", In: "query", }: params.Source, { Name: "ResourceType", In: "query", }: params.ResourceType, { Name: "ResourceID", In: "query", }: params.ResourceID, }, Raw: r, } type ( Request = struct{} Params = ListScriptsParams Response = []Script ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackListScriptsParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { response, err = s.h.ListScripts(ctx, params) return response, err }, ) } else { response, err = s.h.ListScripts(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 := encodeListScriptsResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleListSubmissionsRequest handles listSubmissions operation. // // Get list of submissions. // // 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"), semconv.HTTPRouteKey.String("/submissions"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ListSubmissionsOperation, 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: ListSubmissionsOperation, ID: "listSubmissions", } ) params, err := decodeListSubmissionsParams(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 []Submission if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ListSubmissionsOperation, OperationSummary: "Get list of submissions", OperationID: "listSubmissions", Body: nil, Params: middleware.Parameters{ { Name: "Page", In: "query", }: params.Page, { Name: "Limit", In: "query", }: params.Limit, { Name: "DisplayName", In: "query", }: params.DisplayName, { Name: "Creator", In: "query", }: params.Creator, { Name: "GameID", In: "query", }: params.GameID, { Name: "Sort", In: "query", }: params.Sort, }, Raw: r, } type ( Request = struct{} Params = ListSubmissionsParams Response = []Submission ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackListSubmissionsParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { response, err = s.h.ListSubmissions(ctx, params) return response, err }, ) } else { response, err = s.h.ListSubmissions(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 := encodeListSubmissionsResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleReleaseSubmissionsRequest handles releaseSubmissions operation. // // Release a set of uploaded maps. // // POST /release-submissions func (s *Server) handleReleaseSubmissionsRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("releaseSubmissions"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/release-submissions"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), ReleaseSubmissionsOperation, 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: ReleaseSubmissionsOperation, ID: "releaseSubmissions", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, ReleaseSubmissionsOperation, 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.decodeReleaseSubmissionsRequest(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 *ReleaseSubmissionsCreated if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: ReleaseSubmissionsOperation, OperationSummary: "Release a set of uploaded maps", OperationID: "releaseSubmissions", Body: request, Params: middleware.Parameters{}, Raw: r, } type ( Request = []ReleaseInfo Params = struct{} Response = *ReleaseSubmissionsCreated ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, nil, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.ReleaseSubmissions(ctx, request) return response, err }, ) } else { err = s.h.ReleaseSubmissions(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 := encodeReleaseSubmissionsResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleSessionRolesRequest handles sessionRoles operation. // // Get list of roles for the current session. // // GET /session/roles func (s *Server) handleSessionRolesRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("sessionRoles"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/session/roles"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), SessionRolesOperation, 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: SessionRolesOperation, ID: "sessionRoles", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, SessionRolesOperation, 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 } } var response *Roles if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: SessionRolesOperation, OperationSummary: "Get list of roles for the current session", OperationID: "sessionRoles", Body: nil, Params: middleware.Parameters{}, Raw: r, } type ( Request = struct{} Params = struct{} Response = *Roles ) 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.SessionRoles(ctx) return response, err }, ) } else { response, err = s.h.SessionRoles(ctx) } 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 := encodeSessionRolesResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleSessionUserRequest handles sessionUser operation. // // Get information about the currently logged in user. // // GET /session/user func (s *Server) handleSessionUserRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("sessionUser"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/session/user"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), SessionUserOperation, 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: SessionUserOperation, ID: "sessionUser", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, SessionUserOperation, 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 } } var response *User if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: SessionUserOperation, OperationSummary: "Get information about the currently logged in user", OperationID: "sessionUser", Body: nil, Params: middleware.Parameters{}, Raw: r, } type ( Request = struct{} Params = struct{} Response = *User ) 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.SessionUser(ctx) return response, err }, ) } else { response, err = s.h.SessionUser(ctx) } 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 := encodeSessionUserResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleSessionValidateRequest handles sessionValidate operation. // // Ask if the current session is valid. // // GET /session/validate func (s *Server) handleSessionValidateRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("sessionValidate"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/session/validate"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), SessionValidateOperation, 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: SessionValidateOperation, ID: "sessionValidate", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, SessionValidateOperation, 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 } } var response bool if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: SessionValidateOperation, OperationSummary: "Ask if the current session is valid", OperationID: "sessionValidate", Body: nil, Params: middleware.Parameters{}, Raw: r, } type ( Request = struct{} Params = struct{} Response = bool ) 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.SessionValidate(ctx) return response, err }, ) } else { response, err = s.h.SessionValidate(ctx) } 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 := encodeSessionValidateResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleSetMapfixCompletedRequest handles setMapfixCompleted operation. // // Called by maptest when a player completes the map. // // POST /mapfixes/{MapfixID}/completed func (s *Server) handleSetMapfixCompletedRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("setMapfixCompleted"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/completed"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), SetMapfixCompletedOperation, 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: SetMapfixCompletedOperation, ID: "setMapfixCompleted", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, SetMapfixCompletedOperation, 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 := decodeSetMapfixCompletedParams(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 *SetMapfixCompletedNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: SetMapfixCompletedOperation, OperationSummary: "Called by maptest when a player completes the map", OperationID: "setMapfixCompleted", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, }, Raw: r, } type ( Request = struct{} Params = SetMapfixCompletedParams Response = *SetMapfixCompletedNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackSetMapfixCompletedParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.SetMapfixCompleted(ctx, params) return response, err }, ) } else { err = s.h.SetMapfixCompleted(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 := encodeSetMapfixCompletedResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleSetSubmissionCompletedRequest handles setSubmissionCompleted operation. // // Called by maptest when a player completes the map. // // POST /submissions/{SubmissionID}/completed func (s *Server) handleSetSubmissionCompletedRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("setSubmissionCompleted"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/completed"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), SetSubmissionCompletedOperation, 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: SetSubmissionCompletedOperation, ID: "setSubmissionCompleted", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, SetSubmissionCompletedOperation, 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 := decodeSetSubmissionCompletedParams(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 *SetSubmissionCompletedNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: SetSubmissionCompletedOperation, OperationSummary: "Called by maptest when a player completes the map", OperationID: "setSubmissionCompleted", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, }, Raw: r, } type ( Request = struct{} Params = SetSubmissionCompletedParams Response = *SetSubmissionCompletedNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackSetSubmissionCompletedParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.SetSubmissionCompleted(ctx, params) return response, err }, ) } else { err = s.h.SetSubmissionCompleted(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 := encodeSetSubmissionCompletedResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleUpdateMapfixModelRequest handles updateMapfixModel operation. // // Update model following role restrictions. // // POST /mapfixes/{MapfixID}/model func (s *Server) handleUpdateMapfixModelRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("updateMapfixModel"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/mapfixes/{MapfixID}/model"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), UpdateMapfixModelOperation, 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: UpdateMapfixModelOperation, ID: "updateMapfixModel", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, UpdateMapfixModelOperation, 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 := decodeUpdateMapfixModelParams(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 *UpdateMapfixModelNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: UpdateMapfixModelOperation, OperationSummary: "Update model following role restrictions", OperationID: "updateMapfixModel", Body: nil, Params: middleware.Parameters{ { Name: "MapfixID", In: "path", }: params.MapfixID, { Name: "ModelID", In: "query", }: params.ModelID, { Name: "VersionID", In: "query", }: params.VersionID, }, Raw: r, } type ( Request = struct{} Params = UpdateMapfixModelParams Response = *UpdateMapfixModelNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackUpdateMapfixModelParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.UpdateMapfixModel(ctx, params) return response, err }, ) } else { err = s.h.UpdateMapfixModel(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 := encodeUpdateMapfixModelResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleUpdateScriptRequest handles updateScript operation. // // Update the specified script by ID. // // POST /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("POST"), 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 *UpdateScriptNoContent 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 = *ScriptUpdate Params = UpdateScriptParams Response = *UpdateScriptNoContent ) 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. // // POST /script-policy/{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("POST"), semconv.HTTPRouteKey.String("/script-policy/{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 *UpdateScriptPolicyNoContent 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 = *ScriptPolicyUpdate Params = UpdateScriptPolicyParams Response = *UpdateScriptPolicyNoContent ) 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 } } // handleUpdateSubmissionModelRequest handles updateSubmissionModel operation. // // Update model following role restrictions. // // POST /submissions/{SubmissionID}/model func (s *Server) handleUpdateSubmissionModelRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("updateSubmissionModel"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/submissions/{SubmissionID}/model"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), UpdateSubmissionModelOperation, 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: UpdateSubmissionModelOperation, ID: "updateSubmissionModel", } ) { type bitset = [1]uint8 var satisfied bitset { sctx, ok, err := s.securityCookieAuth(ctx, UpdateSubmissionModelOperation, 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 := decodeUpdateSubmissionModelParams(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 *UpdateSubmissionModelNoContent if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: UpdateSubmissionModelOperation, OperationSummary: "Update model following role restrictions", OperationID: "updateSubmissionModel", Body: nil, Params: middleware.Parameters{ { Name: "SubmissionID", In: "path", }: params.SubmissionID, { Name: "ModelID", In: "query", }: params.ModelID, { Name: "VersionID", In: "query", }: params.VersionID, }, Raw: r, } type ( Request = struct{} Params = UpdateSubmissionModelParams Response = *UpdateSubmissionModelNoContent ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackUpdateSubmissionModelParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.UpdateSubmissionModel(ctx, params) return response, err }, ) } else { err = s.h.UpdateSubmissionModel(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 := encodeUpdateSubmissionModelResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } }