forked from interuss/dss
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[versioning] add new versioning endpoint (interuss#1052)
* [versioning] implement versioning endpoint * remove args, return existing version, basic test
- Loading branch information
Showing
9 changed files
with
246 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -eo pipefail | ||
|
||
# Retrieve token from dummy OAuth server | ||
ACCESS_TOKEN=$(curl --silent \ | ||
"http://localhost:8085/token?grant_type=client_credentials&scope=interuss.versioning.read_system_versions&intended_audience=localhost&issuer=localhost&sub=check_scd" \ | ||
| python extract_json_field.py 'access_token') | ||
|
||
curl --silent -X GET \ | ||
"http://localhost:8082/versions/local.test.identity" \ | ||
-H "Authorization: Bearer ${ACCESS_TOKEN}" -H "Content-Type: application/json" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule automated_testing_interfaces
added at
4e07f4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// This file is auto-generated; do not change as any changes will be overwritten | ||
package versioning | ||
|
||
import ( | ||
"context" | ||
"github.com/interuss/dss/pkg/api" | ||
) | ||
|
||
var ( | ||
InterussVersioningReadSystemVersionsScope = api.RequiredScope("interuss.versioning.read_system_versions") | ||
GetVersionSecurity = []api.AuthorizationOption{ | ||
{ | ||
"Authority": {InterussVersioningReadSystemVersionsScope}, | ||
}, | ||
} | ||
) | ||
|
||
type GetVersionRequest struct { | ||
// The system identity/boundary for which a version should be provided, if known. | ||
SystemIdentity SystemBoundaryIdentifier | ||
|
||
// The result of attempting to authorize this request | ||
Auth api.AuthorizationResult | ||
} | ||
type GetVersionResponseSet struct { | ||
// This interface successfully provided the version of the system identity/boundary that was requested. | ||
Response200 *GetVersionResponse | ||
|
||
// Bearer access token was not provided in Authorization header, token could not be decoded, or token was invalid. | ||
Response401 *api.EmptyResponseBody | ||
|
||
// The access token was decoded successfully but did not include a scope appropriate to this endpoint. | ||
Response403 *api.EmptyResponseBody | ||
|
||
// The requested system identity/boundary is not known, or the versioning automated testing interface is not available. | ||
Response404 *api.EmptyResponseBody | ||
|
||
// Auto-generated internal server error response | ||
Response500 *api.InternalServerErrorBody | ||
} | ||
|
||
type Implementation interface { | ||
// System version | ||
// --- | ||
// Get the requested system version. | ||
GetVersion(ctx context.Context, req *GetVersionRequest) GetVersionResponseSet | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// This file is auto-generated; do not change as any changes will be overwritten | ||
package versioning | ||
|
||
import ( | ||
"context" | ||
"github.com/interuss/dss/pkg/api" | ||
"net/http" | ||
"regexp" | ||
) | ||
|
||
type APIRouter struct { | ||
Routes []*api.Route | ||
Implementation Implementation | ||
Authorizer api.Authorizer | ||
} | ||
|
||
// *versioning.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) { | ||
route.Handler(route.Pattern, w, r) | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func (s *APIRouter) GetVersion(exp *regexp.Regexp, w http.ResponseWriter, r *http.Request) { | ||
var req GetVersionRequest | ||
|
||
// Authorize request | ||
req.Auth = s.Authorizer.Authorize(w, r, GetVersionSecurity) | ||
|
||
// Parse path parameters | ||
pathMatch := exp.FindStringSubmatch(r.URL.Path) | ||
req.SystemIdentity = SystemBoundaryIdentifier(pathMatch[1]) | ||
|
||
// Call implementation | ||
ctx, cancel := context.WithCancel(r.Context()) | ||
defer cancel() | ||
response := s.Implementation.GetVersion(ctx, &req) | ||
|
||
// Write response to client | ||
if response.Response200 != nil { | ||
api.WriteJSON(w, 200, response.Response200) | ||
return | ||
} | ||
if response.Response401 != nil { | ||
api.WriteJSON(w, 401, response.Response401) | ||
return | ||
} | ||
if response.Response403 != nil { | ||
api.WriteJSON(w, 403, response.Response403) | ||
return | ||
} | ||
if response.Response404 != nil { | ||
api.WriteJSON(w, 404, response.Response404) | ||
return | ||
} | ||
if response.Response500 != nil { | ||
api.WriteJSON(w, 500, response.Response500) | ||
return | ||
} | ||
api.WriteJSON(w, 500, api.InternalServerErrorBody{ErrorMessage: "Handler implementation did not set a response"}) | ||
} | ||
|
||
func MakeAPIRouter(impl Implementation, auth api.Authorizer) APIRouter { | ||
router := APIRouter{Implementation: impl, Authorizer: auth, Routes: make([]*api.Route, 1)} | ||
|
||
pattern := regexp.MustCompile("^/versions/(?P<system_identity>[^/]*)$") | ||
router.Routes[0] = &api.Route{Method: http.MethodGet, Pattern: pattern, Handler: router.GetVersion} | ||
|
||
return router | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// This file is auto-generated; do not change as any changes will be overwritten | ||
package versioning | ||
|
||
// Identifier of a system boundary, known to both the client and the USS separate from this API, for which this interface can provide a version. While the format is not prescribed by this API, any value must be URL-safe. It is recommended to use an approach similar to reverse-order Internet domain names and Java packages where the global scope is described with increasingly-precise identifiers joined by periods. For instance, the system boundary containing the mandatory Network Identification U-space service might be identified with `gov.eu.uspace.v1.netid` because the authority defining this system boundary is a governmental organization (specifically, the European Union) with requirements imposed on the system under test by the U-space regulation (first version) -- specifically, the Network Identification Service section. | ||
type SystemBoundaryIdentifier string | ||
|
||
// Identifier of a particular version of a system (defined by a known system boundary). While the format is not prescribed by this API, a semantic version (https://semver.org/) prefixed with a `v` is recommended. | ||
type VersionIdentifier string | ||
|
||
type GetVersionResponse struct { | ||
// The requested system identity/boundary. | ||
SystemIdentity *SystemBoundaryIdentifier `json:"system_identity,omitempty"` | ||
|
||
// The version of the system with the specified system identity/boundary. | ||
SystemVersion *VersionIdentifier `json:"system_version,omitempty"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package versioning | ||
|
||
import ( | ||
"context" | ||
"github.com/interuss/dss/pkg/api" | ||
versioning "github.com/interuss/dss/pkg/api/versioningv1" | ||
dsserr "github.com/interuss/dss/pkg/errors" | ||
"github.com/interuss/dss/pkg/version" | ||
"github.com/interuss/stacktrace" | ||
) | ||
|
||
type Server struct { | ||
} | ||
|
||
func (s *Server) GetVersion(ctx context.Context, req *versioning.GetVersionRequest) versioning.GetVersionResponseSet { | ||
// This should take care of unauthenticated requests as well as | ||
// any request without the proper scope. | ||
if req.Auth.Error != nil { | ||
resp := versioning.GetVersionResponseSet{} | ||
setAuthError(ctx, stacktrace.Propagate(req.Auth.Error, "Auth failed"), &resp.Response401, &resp.Response403, &resp.Response500) | ||
return resp | ||
} | ||
|
||
// The DSS has no notion of particular system identities: whatever the request, we will | ||
// always return the current version of the DSS binary. | ||
versionStr := version.Current().String() | ||
return versioning.GetVersionResponseSet{ | ||
Response200: &versioning.GetVersionResponse{ | ||
SystemIdentity: &req.SystemIdentity, | ||
SystemVersion: (*versioning.VersionIdentifier)(&versionStr), | ||
}, | ||
} | ||
} | ||
|
||
func setAuthError(ctx context.Context, authErr error, resp401, resp403 **api.EmptyResponseBody, resp500 **api.InternalServerErrorBody) { | ||
switch stacktrace.GetCode(authErr) { | ||
case dsserr.Unauthenticated: | ||
*resp401 = &api.EmptyResponseBody{} | ||
case dsserr.PermissionDenied: | ||
*resp403 = &api.EmptyResponseBody{} | ||
default: | ||
*resp500 = &api.InternalServerErrorBody{ErrorMessage: *dsserr.Handle(ctx, stacktrace.Propagate(authErr, "Could not perform authorization"))} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package versioning | ||
|
||
import ( | ||
"context" | ||
versioning "github.com/interuss/dss/pkg/api/versioningv1" | ||
"github.com/interuss/dss/pkg/version" | ||
"github.com/stretchr/testify/assert" | ||
"testing" | ||
) | ||
|
||
func TestServer_GetVersion(t *testing.T) { | ||
s := &Server{} | ||
|
||
got := s.GetVersion(context.Background(), | ||
&versioning.GetVersionRequest{ | ||
SystemIdentity: "empty", | ||
}).Response200 | ||
|
||
assert.Equal( | ||
t, | ||
version.Current().String(), | ||
string(*got.SystemVersion), | ||
) | ||
|
||
assert.Equal( | ||
t, | ||
"empty", | ||
string(*got.SystemIdentity), | ||
) | ||
|
||
} |