mirror of
https://github.com/SigNoz/signoz.git
synced 2026-09-23 20:00:42 +01:00
Compare commits
1 Commits
fix/dashbo
...
nv/api-sta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c00dfa8aa |
File diff suppressed because it is too large
Load Diff
@@ -179,6 +179,7 @@ The `handler.New` function ties the HTTP handler to OpenAPI metadata via `OpenAP
|
||||
- **SuccessStatusCode**: The HTTP status for successful responses (for example, `http.StatusOK`, `http.StatusCreated`, `http.StatusNoContent`).
|
||||
- **ErrorStatusCodes**: Additional error status codes beyond the standard ones automatically added by `handler.New`.
|
||||
- **SecuritySchemes**: Auth mechanisms and scopes required by the operation.
|
||||
- **Stability**: Maturity marker (`handler.StabilityAlpha`, `handler.StabilityBeta`, `handler.StabilityStable`) emitted as the `x-stability` extension on every operation. Unset is emitted as `stable`.
|
||||
|
||||
The generic handler:
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ func (provider *provider) addAlertmanagerRoutes(router *mux.Router) error {
|
||||
SuccessStatusCode: http.StatusCreated,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusConflict},
|
||||
Deprecated: false,
|
||||
Stability: handler.StabilityBeta,
|
||||
SecuritySchemes: newScopedSecuritySchemes([]string{coretypes.ResourceMetaResourceNotificationChannel.Scope(coretypes.VerbCreate)}),
|
||||
},
|
||||
handler.WithResourceDefs(handler.BasicResourceDef{
|
||||
@@ -173,6 +174,7 @@ func (provider *provider) addAlertmanagerRoutes(router *mux.Router) error {
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest},
|
||||
Deprecated: false,
|
||||
Stability: handler.StabilityBeta,
|
||||
SecuritySchemes: newScopedSecuritySchemes([]string{coretypes.ResourceMetaResourceNotificationChannel.Scope(coretypes.VerbList)}),
|
||||
},
|
||||
handler.WithResourceDefs(handler.BasicResourceDef{
|
||||
@@ -199,6 +201,7 @@ func (provider *provider) addAlertmanagerRoutes(router *mux.Router) error {
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
|
||||
Deprecated: false,
|
||||
Stability: handler.StabilityBeta,
|
||||
SecuritySchemes: newScopedSecuritySchemes([]string{coretypes.ResourceMetaResourceNotificationChannel.Scope(coretypes.VerbRead)}),
|
||||
},
|
||||
handler.WithResourceDefs(handler.BasicResourceDef{
|
||||
@@ -226,6 +229,7 @@ func (provider *provider) addAlertmanagerRoutes(router *mux.Router) error {
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
|
||||
Deprecated: false,
|
||||
Stability: handler.StabilityBeta,
|
||||
SecuritySchemes: newScopedSecuritySchemes([]string{coretypes.ResourceMetaResourceNotificationChannel.Scope(coretypes.VerbUpdate)}),
|
||||
},
|
||||
handler.WithResourceDefs(handler.BasicResourceDef{
|
||||
@@ -253,6 +257,7 @@ func (provider *provider) addAlertmanagerRoutes(router *mux.Router) error {
|
||||
SuccessStatusCode: http.StatusNoContent,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
|
||||
Deprecated: false,
|
||||
Stability: handler.StabilityBeta,
|
||||
SecuritySchemes: newScopedSecuritySchemes([]string{coretypes.ResourceMetaResourceNotificationChannel.Scope(coretypes.VerbDelete)}),
|
||||
},
|
||||
handler.WithResourceDefs(handler.BasicResourceDef{
|
||||
@@ -281,6 +286,7 @@ func (provider *provider) addAlertmanagerRoutes(router *mux.Router) error {
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
|
||||
Deprecated: false,
|
||||
Stability: handler.StabilityBeta,
|
||||
SecuritySchemes: newScopedSecuritySchemes([]string{coretypes.ResourceMetaResourceNotificationChannel.Scope(coretypes.VerbUpdate)}),
|
||||
},
|
||||
handler.WithResourceDefs(handler.BasicResourceDef{
|
||||
@@ -308,6 +314,7 @@ func (provider *provider) addAlertmanagerRoutes(router *mux.Router) error {
|
||||
SuccessStatusCode: http.StatusNoContent,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest},
|
||||
Deprecated: false,
|
||||
Stability: handler.StabilityBeta,
|
||||
SecuritySchemes: newScopedSecuritySchemes([]string{coretypes.ResourceMetaResourceNotificationChannel.Scope(coretypes.VerbCreate)}),
|
||||
},
|
||||
handler.WithResourceDefs(handler.BasicResourceDef{
|
||||
|
||||
@@ -62,6 +62,10 @@ func (handler *handler) ServeOpenAPI(opCtx openapi.OperationContext) {
|
||||
opCtx.SetDescription(handler.openAPIDef.Description)
|
||||
opCtx.SetIsDeprecated(handler.openAPIDef.Deprecated)
|
||||
|
||||
if exposer, ok := opCtx.(openapi3.OperationExposer); ok {
|
||||
exposer.Operation().WithMapOfAnythingItem(openAPIStabilityKey, handler.openAPIDef.Stability.StringValue())
|
||||
}
|
||||
|
||||
// Add security schemes
|
||||
for _, securityScheme := range handler.openAPIDef.SecuritySchemes {
|
||||
opCtx.AddSecurity(securityScheme.Name, securityScheme.Scopes...)
|
||||
|
||||
52
pkg/http/handler/handler_test.go
Normal file
52
pkg/http/handler/handler_test.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/swaggest/openapi-go/openapi3"
|
||||
)
|
||||
|
||||
func TestServeOpenAPIStability(t *testing.T) {
|
||||
testCases := []struct {
|
||||
subtestName string
|
||||
stability Stability
|
||||
expectedExtensionValue any
|
||||
}{
|
||||
{
|
||||
subtestName: "beta is emitted as x-stability",
|
||||
stability: StabilityBeta,
|
||||
expectedExtensionValue: "beta",
|
||||
},
|
||||
{
|
||||
subtestName: "alpha is emitted as x-stability",
|
||||
stability: StabilityAlpha,
|
||||
expectedExtensionValue: "alpha",
|
||||
},
|
||||
{
|
||||
subtestName: "unset is emitted as stable",
|
||||
stability: Stability{},
|
||||
expectedExtensionValue: "stable",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.subtestName, func(t *testing.T) {
|
||||
reflector := openapi3.NewReflector()
|
||||
opCtx, err := reflector.NewOperationContext(http.MethodGet, "/test")
|
||||
require.NoError(t, err)
|
||||
|
||||
New(func(http.ResponseWriter, *http.Request) {}, OpenAPIDef{
|
||||
ID: "test",
|
||||
SuccessStatusCode: http.StatusOK,
|
||||
Stability: testCase.stability,
|
||||
}).ServeOpenAPI(opCtx)
|
||||
require.NoError(t, reflector.AddOperation(opCtx))
|
||||
|
||||
operation := reflector.Spec.Paths.MapOfPathItemValues["/test"].MapOfOperationValues["get"]
|
||||
assert.Equal(t, testCase.expectedExtensionValue, operation.MapOfAnything["x-stability"])
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,32 @@ package handler
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/swaggest/jsonschema-go"
|
||||
openapigo "github.com/swaggest/openapi-go"
|
||||
"github.com/swaggest/rest/openapi"
|
||||
)
|
||||
|
||||
const openAPIStabilityKey string = "x-stability"
|
||||
|
||||
var (
|
||||
StabilityAlpha = Stability{valuer.NewString("alpha")}
|
||||
StabilityBeta = Stability{valuer.NewString("beta")}
|
||||
StabilityStable = Stability{valuer.NewString("stable")}
|
||||
)
|
||||
|
||||
// Stability is emitted as the x-stability extension on every operation; unset means stable.
|
||||
type Stability struct{ valuer.String }
|
||||
|
||||
func (stability Stability) StringValue() string {
|
||||
if stability.IsZero() {
|
||||
return StabilityStable.String.StringValue()
|
||||
}
|
||||
|
||||
return stability.String.StringValue()
|
||||
}
|
||||
|
||||
// OpenAPIExample is a named example for an OpenAPI operation.
|
||||
type OpenAPIExample struct {
|
||||
Name string
|
||||
@@ -32,6 +52,7 @@ type OpenAPIDef struct {
|
||||
SuccessStatusCode int
|
||||
ErrorStatusCodes []int
|
||||
Deprecated bool
|
||||
Stability Stability
|
||||
SecuritySchemes []OpenAPISecurityScheme
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user