Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions cmds/core-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,8 @@ func RunHTTPServer(ctx context.Context, ctxCanceler func(), address, locality st
handler = authorizer.TokenMiddleware(handler)

if *enableOpenTelemetry {
httpSpanName := func(operation string, req *http.Request) string {
return fmt.Sprintf("%s %s", req.Method, req.URL.Path)
}

handler = otelhttp.NewHandler(handler, "http", otelhttp.WithSpanNameFormatter(httpSpanName))
// We use the default settings; the APIRouter handler will override the span value accordingly, as it has more information.
handler = otelhttp.NewHandler(handler, "http")
}

httpServer := &http.Server{
Expand Down
2 changes: 2 additions & 0 deletions interfaces/openapi-to-go-server/example/api/common.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ type Route struct {
Method string
Pattern *regexp.Regexp
Handler Handler
Name string
Path string
}

type PartialRouter interface {
Expand Down
37 changes: 27 additions & 10 deletions interfaces/openapi-to-go-server/example/api/rid/server.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"context"
"encoding/json"
"example/api"
"fmt"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
"net/http"
"regexp"
)
Expand All @@ -15,10 +18,24 @@ type APIRouter struct {
Authorizer api.Authorizer
}

var tracer = otel.Tracer("rid.api")

// *rid.APIRouter (type defined above) implements the api.PartialRouter interface
func (s *APIRouter) Handle(w http.ResponseWriter, r *http.Request) bool {
for _, route := range s.Routes {
if route.Method == r.Method && route.Pattern.MatchString(r.URL.Path) {

span := trace.SpanFromContext(r.Context())

if span.IsRecording() {
// Current span is the one from the otelhttp handler
span.SetName(fmt.Sprintf("%s %s", r.Method, route.Path))
}

ctx, span := tracer.Start(r.Context(), route.Name)
defer span.End()
r = r.WithContext(ctx)

route.Handler(route.Pattern, w, r)
return true
}
Expand Down Expand Up @@ -522,34 +539,34 @@ func MakeAPIRouter(impl Implementation, auth api.Authorizer) APIRouter {
router := APIRouter{Implementation: impl, Authorizer: auth, Routes: make([]*api.Route, 10)}

pattern := regexp.MustCompile("^/rid/v1/dss/identification_service_areas$")
router.Routes[0] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.SearchIdentificationServiceAreas}
router.Routes[0] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.SearchIdentificationServiceAreas, Name: "rid.SearchIdentificationServiceAreas", Path: "/rid/v1/dss/identification_service_areas"}

pattern = regexp.MustCompile("^/rid/v1/dss/identification_service_areas/(?P<id>[^/]*)$")
router.Routes[1] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetIdentificationServiceArea}
router.Routes[1] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetIdentificationServiceArea, Name: "rid.GetIdentificationServiceArea", Path: "/rid/v1/dss/identification_service_areas/{id}"}

pattern = regexp.MustCompile("^/rid/v1/dss/identification_service_areas/(?P<id>[^/]*)$")
router.Routes[2] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateIdentificationServiceArea}
router.Routes[2] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateIdentificationServiceArea, Name: "rid.CreateIdentificationServiceArea", Path: "/rid/v1/dss/identification_service_areas/{id}"}

pattern = regexp.MustCompile("^/rid/v1/dss/identification_service_areas/(?P<id>[^/]*)/(?P<version>[^/]*)$")
router.Routes[3] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateIdentificationServiceArea}
router.Routes[3] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateIdentificationServiceArea, Name: "rid.UpdateIdentificationServiceArea", Path: "/rid/v1/dss/identification_service_areas/{id}/{version}"}

pattern = regexp.MustCompile("^/rid/v1/dss/identification_service_areas/(?P<id>[^/]*)/(?P<version>[^/]*)$")
router.Routes[4] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteIdentificationServiceArea}
router.Routes[4] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteIdentificationServiceArea, Name: "rid.DeleteIdentificationServiceArea", Path: "/rid/v1/dss/identification_service_areas/{id}/{version}"}

pattern = regexp.MustCompile("^/rid/v1/dss/subscriptions$")
router.Routes[5] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.SearchSubscriptions}
router.Routes[5] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.SearchSubscriptions, Name: "rid.SearchSubscriptions", Path: "/rid/v1/dss/subscriptions"}

pattern = regexp.MustCompile("^/rid/v1/dss/subscriptions/(?P<id>[^/]*)$")
router.Routes[6] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetSubscription}
router.Routes[6] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetSubscription, Name: "rid.GetSubscription", Path: "/rid/v1/dss/subscriptions/{id}"}

pattern = regexp.MustCompile("^/rid/v1/dss/subscriptions/(?P<id>[^/]*)$")
router.Routes[7] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateSubscription}
router.Routes[7] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateSubscription, Name: "rid.CreateSubscription", Path: "/rid/v1/dss/subscriptions/{id}"}

pattern = regexp.MustCompile("^/rid/v1/dss/subscriptions/(?P<id>[^/]*)/(?P<version>[^/]*)$")
router.Routes[8] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateSubscription}
router.Routes[8] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateSubscription, Name: "rid.UpdateSubscription", Path: "/rid/v1/dss/subscriptions/{id}/{version}"}

pattern = regexp.MustCompile("^/rid/v1/dss/subscriptions/(?P<id>[^/]*)/(?P<version>[^/]*)$")
router.Routes[9] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteSubscription}
router.Routes[9] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteSubscription, Name: "rid.DeleteSubscription", Path: "/rid/v1/dss/subscriptions/{id}/{version}"}

return router
}
53 changes: 35 additions & 18 deletions interfaces/openapi-to-go-server/example/api/scd/server.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"context"
"encoding/json"
"example/api"
"fmt"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
"net/http"
"regexp"
)
Expand All @@ -15,10 +18,24 @@ type APIRouter struct {
Authorizer api.Authorizer
}

var tracer = otel.Tracer("scd.api")

// *scd.APIRouter (type defined above) implements the api.PartialRouter interface
func (s *APIRouter) Handle(w http.ResponseWriter, r *http.Request) bool {
for _, route := range s.Routes {
if route.Method == r.Method && route.Pattern.MatchString(r.URL.Path) {

span := trace.SpanFromContext(r.Context())

if span.IsRecording() {
// Current span is the one from the otelhttp handler
span.SetName(fmt.Sprintf("%s %s", r.Method, route.Path))
}

ctx, span := tracer.Start(r.Context(), route.Name)
defer span.End()
r = r.WithContext(ctx)

route.Handler(route.Pattern, w, r)
return true
}
Expand Down Expand Up @@ -953,58 +970,58 @@ func MakeAPIRouter(impl Implementation, auth api.Authorizer) APIRouter {
router := APIRouter{Implementation: impl, Authorizer: auth, Routes: make([]*api.Route, 18)}

pattern := regexp.MustCompile("^/scd/dss/v1/operational_intent_references/query$")
router.Routes[0] = &api.Route{Method: http.MethodPost, Pattern: pattern, Handler: router.QueryOperationalIntentReferences}
router.Routes[0] = &api.Route{Method: http.MethodPost, Pattern: pattern, Handler: router.QueryOperationalIntentReferences, Name: "scd.QueryOperationalIntentReferences", Path: "/scd/dss/v1/operational_intent_references/query"}

pattern = regexp.MustCompile("^/scd/dss/v1/operational_intent_references/(?P<entityid>[^/]*)$")
router.Routes[1] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetOperationalIntentReference}
router.Routes[1] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetOperationalIntentReference, Name: "scd.GetOperationalIntentReference", Path: "/scd/dss/v1/operational_intent_references/{entityid}"}

pattern = regexp.MustCompile("^/scd/dss/v1/operational_intent_references/(?P<entityid>[^/]*)$")
router.Routes[2] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateOperationalIntentReference}
router.Routes[2] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateOperationalIntentReference, Name: "scd.CreateOperationalIntentReference", Path: "/scd/dss/v1/operational_intent_references/{entityid}"}

pattern = regexp.MustCompile("^/scd/dss/v1/operational_intent_references/(?P<entityid>[^/]*)/(?P<ovn>[^/]*)$")
router.Routes[3] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateOperationalIntentReference}
router.Routes[3] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateOperationalIntentReference, Name: "scd.UpdateOperationalIntentReference", Path: "/scd/dss/v1/operational_intent_references/{entityid}/{ovn}"}

pattern = regexp.MustCompile("^/scd/dss/v1/operational_intent_references/(?P<entityid>[^/]*)/(?P<ovn>[^/]*)$")
router.Routes[4] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteOperationalIntentReference}
router.Routes[4] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteOperationalIntentReference, Name: "scd.DeleteOperationalIntentReference", Path: "/scd/dss/v1/operational_intent_references/{entityid}/{ovn}"}

pattern = regexp.MustCompile("^/scd/dss/v1/constraint_references/query$")
router.Routes[5] = &api.Route{Method: http.MethodPost, Pattern: pattern, Handler: router.QueryConstraintReferences}
router.Routes[5] = &api.Route{Method: http.MethodPost, Pattern: pattern, Handler: router.QueryConstraintReferences, Name: "scd.QueryConstraintReferences", Path: "/scd/dss/v1/constraint_references/query"}

pattern = regexp.MustCompile("^/scd/dss/v1/constraint_references/(?P<entityid>[^/]*)$")
router.Routes[6] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetConstraintReference}
router.Routes[6] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetConstraintReference, Name: "scd.GetConstraintReference", Path: "/scd/dss/v1/constraint_references/{entityid}"}

pattern = regexp.MustCompile("^/scd/dss/v1/constraint_references/(?P<entityid>[^/]*)$")
router.Routes[7] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateConstraintReference}
router.Routes[7] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateConstraintReference, Name: "scd.CreateConstraintReference", Path: "/scd/dss/v1/constraint_references/{entityid}"}

pattern = regexp.MustCompile("^/scd/dss/v1/constraint_references/(?P<entityid>[^/]*)/(?P<ovn>[^/]*)$")
router.Routes[8] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateConstraintReference}
router.Routes[8] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateConstraintReference, Name: "scd.UpdateConstraintReference", Path: "/scd/dss/v1/constraint_references/{entityid}/{ovn}"}

pattern = regexp.MustCompile("^/scd/dss/v1/constraint_references/(?P<entityid>[^/]*)/(?P<ovn>[^/]*)$")
router.Routes[9] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteConstraintReference}
router.Routes[9] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteConstraintReference, Name: "scd.DeleteConstraintReference", Path: "/scd/dss/v1/constraint_references/{entityid}/{ovn}"}

pattern = regexp.MustCompile("^/scd/dss/v1/subscriptions/query$")
router.Routes[10] = &api.Route{Method: http.MethodPost, Pattern: pattern, Handler: router.QuerySubscriptions}
router.Routes[10] = &api.Route{Method: http.MethodPost, Pattern: pattern, Handler: router.QuerySubscriptions, Name: "scd.QuerySubscriptions", Path: "/scd/dss/v1/subscriptions/query"}

pattern = regexp.MustCompile("^/scd/dss/v1/subscriptions/(?P<subscriptionid>[^/]*)$")
router.Routes[11] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetSubscription}
router.Routes[11] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetSubscription, Name: "scd.GetSubscription", Path: "/scd/dss/v1/subscriptions/{subscriptionid}"}

pattern = regexp.MustCompile("^/scd/dss/v1/subscriptions/(?P<subscriptionid>[^/]*)$")
router.Routes[12] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateSubscription}
router.Routes[12] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.CreateSubscription, Name: "scd.CreateSubscription", Path: "/scd/dss/v1/subscriptions/{subscriptionid}"}

pattern = regexp.MustCompile("^/scd/dss/v1/subscriptions/(?P<subscriptionid>[^/]*)/(?P<version>[^/]*)$")
router.Routes[13] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateSubscription}
router.Routes[13] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.UpdateSubscription, Name: "scd.UpdateSubscription", Path: "/scd/dss/v1/subscriptions/{subscriptionid}/{version}"}

pattern = regexp.MustCompile("^/scd/dss/v1/subscriptions/(?P<subscriptionid>[^/]*)/(?P<version>[^/]*)$")
router.Routes[14] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteSubscription}
router.Routes[14] = &api.Route{Method: http.MethodDelete, Pattern: pattern, Handler: router.DeleteSubscription, Name: "scd.DeleteSubscription", Path: "/scd/dss/v1/subscriptions/{subscriptionid}/{version}"}

pattern = regexp.MustCompile("^/scd/dss/v1/reports$")
router.Routes[15] = &api.Route{Method: http.MethodPost, Pattern: pattern, Handler: router.MakeDssReport}
router.Routes[15] = &api.Route{Method: http.MethodPost, Pattern: pattern, Handler: router.MakeDssReport, Name: "scd.MakeDssReport", Path: "/scd/dss/v1/reports"}

pattern = regexp.MustCompile("^/scd/dss/v1/uss_availability/(?P<uss_id>[^/]*)$")
router.Routes[16] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetUssAvailability}
router.Routes[16] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetUssAvailability, Name: "scd.GetUssAvailability", Path: "/scd/dss/v1/uss_availability/{uss_id}"}

pattern = regexp.MustCompile("^/scd/dss/v1/uss_availability/(?P<uss_id>[^/]*)$")
router.Routes[17] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.SetUssAvailability}
router.Routes[17] = &api.Route{Method: http.MethodPut, Pattern: pattern, Handler: router.SetUssAvailability, Name: "scd.SetUssAvailability", Path: "/scd/dss/v1/uss_availability/{uss_id}"}

return router
}
2 changes: 1 addition & 1 deletion interfaces/openapi-to-go-server/example/run_example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ cd "${BASEDIR}" || exit
docker image build -t openapi-to-go-server-demo . || exit

echo "Running server..."
docker container run -it -p 8080:8080 openapi-to-go-server-demo
docker container run -it -p 8180:8080 openapi-to-go-server-demo
10 changes: 9 additions & 1 deletion interfaces/openapi-to-go-server/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,15 @@ def _generate_apis(
routes, new_imports = rendering.routes(api, api_package, ensure_500)
server_template_vars = {
"<PACKAGE>": api.package,
"<IMPORTS>": rendering.imports(list(new_imports) + [api_import]),
"<IMPORTS>": rendering.imports(
list(new_imports)
+ [
api_import,
"fmt",
"go.opentelemetry.io/otel",
"go.opentelemetry.io/otel/trace",
]
),
"<API_PACKAGE>": api_package,
"<ROUTES>": "\n".join(routes),
"<ROUTING>": "\n".join(rendering.routing(api, api_package)),
Expand Down
13 changes: 11 additions & 2 deletions interfaces/openapi-to-go-server/rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,17 @@ def routing(api: apis.API, api_package: str) -> List[str]:
)
)
lines.append(
"router.Routes[%d] = &%s.Route{Method: %s, Pattern: pattern, Handler: router.%s}"
% (i, api_package, operation.verb_const_name, operation.interface_name)
'router.Routes[%d] = &%s.Route{Method: %s, Pattern: pattern, Handler: router.%s, Name: "%s.%s", Path: "%s%s"}'
% (
i,
api_package,
operation.verb_const_name,
operation.interface_name,
api.package,
operation.interface_name,
prefix,
operation.path,
)
)
lines.append("")
first_assignment = False
Expand Down
2 changes: 2 additions & 0 deletions interfaces/openapi-to-go-server/templates/common.go.template
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ type Route struct {
Method string
Pattern *regexp.Regexp
Handler Handler
Name string
Path string
}

type PartialRouter interface {
Expand Down
14 changes: 14 additions & 0 deletions interfaces/openapi-to-go-server/templates/server.go.template
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,24 @@ type APIRouter struct {
Authorizer <API_PACKAGE>.Authorizer
}

var tracer = otel.Tracer("<PACKAGE>.<API_PACKAGE>")

// *<PACKAGE>.APIRouter (type defined above) implements the <API_PACKAGE>.PartialRouter interface
func (s *APIRouter) Handle(w http.ResponseWriter, r *http.Request) bool {
for _, route := range s.Routes {
if route.Method == r.Method && route.Pattern.MatchString(r.URL.Path) {

// We retrieve the current span from the otelhttp handler to set its name property.
span := trace.SpanFromContext(r.Context())

if span.IsRecording() { // If the span is not recording, the name cannot be changed. This also likely means the otelhttp handler is not present (tracing disabled).
span.SetName(fmt.Sprintf("%s %s", r.Method, route.Path))
}

ctx, span := tracer.Start(r.Context(), route.Name)
defer span.End()
r = r.WithContext(ctx)

route.Handler(route.Pattern, w, r)
return true
}
Expand Down
Loading
Loading