// Code generated by ogen, DO NOT EDIT. package gsn 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) } // handleGetSatellitesRequest handles GetSatellites operation. // // Get available satellites. // // GET /api/v1/satellite func (s *Server) handleGetSatellitesRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("GetSatellites"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/api/v1/satellite"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), GetSatellitesOperation, 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 ) var response *GetSatellitesOK if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: GetSatellitesOperation, OperationSummary: "Get available satellites", OperationID: "GetSatellites", Body: nil, Params: middleware.Parameters{}, Raw: r, } type ( Request = struct{} Params = struct{} Response = *GetSatellitesOK ) 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.GetSatellites(ctx) return response, err }, ) } else { response, err = s.h.GetSatellites(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 := encodeGetSatellitesResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleGetStationsRequest handles GetStations operation. // // Get available stations. // // GET /api/v1/station func (s *Server) handleGetStationsRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("GetStations"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/api/v1/station"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), GetStationsOperation, 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 ) var response *GetStationsOK if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: GetStationsOperation, OperationSummary: "Get available stations", OperationID: "GetStations", Body: nil, Params: middleware.Parameters{}, Raw: r, } type ( Request = struct{} Params = struct{} Response = *GetStationsOK ) 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.GetStations(ctx) return response, err }, ) } else { response, err = s.h.GetStations(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 := encodeGetStationsResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleGetSubscriptionsRequest handles GetSubscriptions operation. // // Get current subscriptions. // // GET /api/v1/subscription func (s *Server) handleGetSubscriptionsRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("GetSubscriptions"), semconv.HTTPRequestMethodKey.String("GET"), semconv.HTTPRouteKey.String("/api/v1/subscription"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), GetSubscriptionsOperation, 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 ) var response *GetSubscriptionsOK if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: GetSubscriptionsOperation, OperationSummary: "Get current subscriptions", OperationID: "GetSubscriptions", Body: nil, Params: middleware.Parameters{}, Raw: r, } type ( Request = struct{} Params = struct{} Response = *GetSubscriptionsOK ) 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.GetSubscriptions(ctx) return response, err }, ) } else { response, err = s.h.GetSubscriptions(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 := encodeGetSubscriptionsResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleSubscribeSatelliteRequest handles SubscribeSatellite operation. // // Subscribe to a given station. // // POST /api/v1/satellite/subscribe func (s *Server) handleSubscribeSatelliteRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("SubscribeSatellite"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/api/v1/satellite/subscribe"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), SubscribeSatelliteOperation, 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: SubscribeSatelliteOperation, ID: "SubscribeSatellite", } ) request, close, err := s.decodeSubscribeSatelliteRequest(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 *SubscribeSatelliteOK if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: SubscribeSatelliteOperation, OperationSummary: "Subscribe to a given station", OperationID: "SubscribeSatellite", Body: request, Params: middleware.Parameters{}, Raw: r, } type ( Request = *SubscribeSatelliteReq Params = struct{} Response = *SubscribeSatelliteOK ) 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.SubscribeSatellite(ctx, request) return response, err }, ) } else { response, err = s.h.SubscribeSatellite(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 := encodeSubscribeSatelliteResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleSubscribeStationRequest handles SubscribeStation operation. // // Subscribe to a given station. // // POST /api/v1/station/subscribe func (s *Server) handleSubscribeStationRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("SubscribeStation"), semconv.HTTPRequestMethodKey.String("POST"), semconv.HTTPRouteKey.String("/api/v1/station/subscribe"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), SubscribeStationOperation, 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: SubscribeStationOperation, ID: "SubscribeStation", } ) request, close, err := s.decodeSubscribeStationRequest(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 *SubscribeStationOK if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: SubscribeStationOperation, OperationSummary: "Subscribe to a given station", OperationID: "SubscribeStation", Body: request, Params: middleware.Parameters{}, Raw: r, } type ( Request = *SubscribeStationReq Params = struct{} Response = *SubscribeStationOK ) 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.SubscribeStation(ctx, request) return response, err }, ) } else { response, err = s.h.SubscribeStation(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 := encodeSubscribeStationResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } } // handleUnsubscribeRequest handles Unsubscribe operation. // // Remove subscription by subscription ID. // // DELETE /api/v1/subscription func (s *Server) handleUnsubscribeRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { statusWriter := &codeRecorder{ResponseWriter: w} w = statusWriter otelAttrs := []attribute.KeyValue{ otelogen.OperationID("Unsubscribe"), semconv.HTTPRequestMethodKey.String("DELETE"), semconv.HTTPRouteKey.String("/api/v1/subscription"), } // Start a span for this request. ctx, span := s.cfg.Tracer.Start(r.Context(), UnsubscribeOperation, 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: UnsubscribeOperation, ID: "Unsubscribe", } ) params, err := decodeUnsubscribeParams(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 *UnsubscribeOK if m := s.cfg.Middleware; m != nil { mreq := middleware.Request{ Context: ctx, OperationName: UnsubscribeOperation, OperationSummary: "Remove subscription by subscription ID", OperationID: "Unsubscribe", Body: nil, Params: middleware.Parameters{ { Name: "id", In: "query", }: params.ID, }, Raw: r, } type ( Request = struct{} Params = UnsubscribeParams Response = *UnsubscribeOK ) response, err = middleware.HookMiddleware[ Request, Params, Response, ]( m, mreq, unpackUnsubscribeParams, func(ctx context.Context, request Request, params Params) (response Response, err error) { err = s.h.Unsubscribe(ctx, params) return response, err }, ) } else { err = s.h.Unsubscribe(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 := encodeUnsubscribeResponse(response, w, span); err != nil { defer recordError("EncodeResponse", err) if !errors.Is(err, ht.ErrInternalServerErrorResponse) { s.cfg.ErrorHandler(ctx, w, r, err) } return } }