feat(deploy): single-origin path-based deployment + project site
Serve the whole stack behind one host: site at /, game UI at /game/, gateway REST at /api + /healthz, Connect at /rpc (prefix stripped by the edge Caddy). The built artifact is domain-agnostic — the UI talks to the gateway same-origin via relative URLs, so the same bundle runs under any host with no rebuild and with CORS disabled. - Rename the Connect proto service galaxy.gateway.v1.EdgeGateway -> edge.v1.Gateway; regenerate Go + TS; public path /rpc/edge.v1.Gateway. - Move the game UI under base path /game (env BASE_PATH); make the manifest, service-worker scope, WASM loader, and all navigation base-aware via a withBase helper. - Relative API + /rpc Connect prefix; Vite dev proxy mirrors the strip. - Rewrite the edge Caddy (dev + prod) for path-based routing; empty CORS allow-lists (same-origin); single host. - New VitePress project site (site/): i18n en/ru with switcher, LaTeX math, minimal monospace theme; built and served at /. - dev-deploy compose/Makefile + CI (dev-deploy, prod-build, new site-build) build and seed the site; probes hit /, /game/, /healthz. - Sync docs (ARCHITECTURE, gateway README/openapi, dev-deploy & local-dev READMEs, CLAUDE.md, ui/PLAN). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
-5
@@ -94,8 +94,20 @@ The authenticated edge listener is built on
|
||||
the Connect, gRPC, and gRPC-Web protocols on a single HTTP/2 cleartext
|
||||
(`h2c`) port. Browser clients use `@connectrpc/connect-web`; native
|
||||
clients can use either Connect or raw gRPC framing against the same
|
||||
listener. Production TLS termination happens upstream of the gateway,
|
||||
matching the previous gRPC-only deployment posture.
|
||||
listener. TLS termination happens upstream of the gateway at the edge
|
||||
Caddy, which fronts both transports under one host.
|
||||
|
||||
Both transports are served same-origin under one host. The edge routes
|
||||
public REST and the health probe at `/api/*` and `/healthz` to the
|
||||
public listener, and the authenticated Connect/gRPC-Web surface at
|
||||
`/rpc/*` to the authenticated listener (the `/rpc` prefix is stripped
|
||||
before the gateway). Because the game UI is served from the same origin,
|
||||
the gateway runs with CORS disabled by default: both
|
||||
`GATEWAY_PUBLIC_HTTP_CORS_ALLOWED_ORIGINS` and
|
||||
`GATEWAY_AUTHENTICATED_GRPC_CORS_ALLOWED_ORIGINS` are empty, an empty
|
||||
allow-list turns the CORS middleware off, and responses carry no
|
||||
`Access-Control-*` headers. Those knobs would only be repopulated if a
|
||||
deployment ever fronted the gateway on a different host than the UI.
|
||||
|
||||
### Public REST Surface
|
||||
|
||||
@@ -225,10 +237,13 @@ It binds the stream to `user_id` and `device_session_id` and starts by sending
|
||||
a signed service event that includes the current server time in milliseconds.
|
||||
|
||||
The v1 protobuf contract lives in
|
||||
`proto/galaxy/gateway/v1/edge_gateway.proto` under package
|
||||
`galaxy.gateway.v1` and service `EdgeGateway`.
|
||||
`proto/edge/v1/edge_gateway.proto` under package `edge.v1` and service
|
||||
`Gateway`. Browser and native clients address its methods at
|
||||
`/rpc/edge.v1.Gateway/<Method>`; the edge Caddy strips the `/rpc`
|
||||
prefix so the gateway listener sees the proto-derived
|
||||
`/edge.v1.Gateway/<Method>` path.
|
||||
Generated Go bindings are committed under
|
||||
`proto/galaxy/gateway/v1/` (gRPC stubs and `gatewayv1connect/` Connect
|
||||
`proto/edge/v1/` (gRPC stubs and `edgev1connect/` Connect
|
||||
handlers) and are regenerated with:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"galaxy/gateway/authn"
|
||||
"galaxy/gateway/internal/clock"
|
||||
"galaxy/gateway/internal/downstream"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -21,9 +21,9 @@ import (
|
||||
// commandRoutingService translates the verified authenticated request context
|
||||
// into an internal downstream command and signs successful unary responses.
|
||||
type commandRoutingService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
subscribeDelegate gatewayv1.EdgeGatewayServer
|
||||
subscribeDelegate edgev1.GatewayServer
|
||||
router downstream.Router
|
||||
responseSigner authn.ResponseSigner
|
||||
clock clock.Clock
|
||||
@@ -32,7 +32,7 @@ type commandRoutingService struct {
|
||||
|
||||
// ExecuteCommand builds a verified downstream command, routes it by exact
|
||||
// message_type, executes it, and signs the resulting unary response.
|
||||
func (s commandRoutingService) ExecuteCommand(ctx context.Context, _ *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
func (s commandRoutingService) ExecuteCommand(ctx context.Context, _ *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
command, err := authenticatedCommandFromContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -80,7 +80,7 @@ func (s commandRoutingService) ExecuteCommand(ctx context.Context, _ *gatewayv1.
|
||||
return nil, status.Error(codes.Unavailable, "response signer is unavailable")
|
||||
}
|
||||
|
||||
return &gatewayv1.ExecuteCommandResponse{
|
||||
return &edgev1.ExecuteCommandResponse{
|
||||
ProtocolVersion: command.ProtocolVersion,
|
||||
RequestId: command.RequestID,
|
||||
TimestampMs: responseTimestampMS,
|
||||
@@ -93,13 +93,13 @@ func (s commandRoutingService) ExecuteCommand(ctx context.Context, _ *gatewayv1.
|
||||
|
||||
// SubscribeEvents delegates to the authenticated streaming service
|
||||
// implementation selected during server construction.
|
||||
func (s commandRoutingService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s commandRoutingService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
return s.subscribeDelegate.SubscribeEvents(req, stream)
|
||||
}
|
||||
|
||||
// newCommandRoutingService constructs the final authenticated service that
|
||||
// owns verified unary routing while preserving the delegated streaming path.
|
||||
func newCommandRoutingService(subscribeDelegate gatewayv1.EdgeGatewayServer, router downstream.Router, responseSigner authn.ResponseSigner, clk clock.Clock, downstreamTimeout time.Duration) gatewayv1.EdgeGatewayServer {
|
||||
func newCommandRoutingService(subscribeDelegate edgev1.GatewayServer, router downstream.Router, responseSigner authn.ResponseSigner, clk clock.Clock, downstreamTimeout time.Duration) edgev1.GatewayServer {
|
||||
return commandRoutingService{
|
||||
subscribeDelegate: subscribeDelegate,
|
||||
router: router,
|
||||
@@ -142,4 +142,4 @@ func (unavailableResponseSigner) SignEvent(authn.EventSigningFields) ([]byte, er
|
||||
return nil, errors.New("response signer is unavailable")
|
||||
}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = commandRoutingService{}
|
||||
var _ edgev1.GatewayServer = commandRoutingService{}
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
"galaxy/gateway/proto/galaxy/gateway/v1/gatewayv1connect"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
"galaxy/gateway/proto/edge/v1/edgev1connect"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -17,15 +17,15 @@ import (
|
||||
// connectEdgeAdapter exposes the existing gRPC-shaped authenticated edge
|
||||
// service decorator stack (envelope → session → payload-hash → signature →
|
||||
// freshness/replay → rate-limit → routing/push) through the
|
||||
// gatewayv1connect.EdgeGatewayHandler interface. It owns no logic of its
|
||||
// edgev1connect.GatewayHandler interface. It owns no logic of its
|
||||
// own; the underlying decorator stack carries the full ingress contract
|
||||
// unchanged.
|
||||
type connectEdgeAdapter struct {
|
||||
impl gatewayv1.EdgeGatewayServer
|
||||
impl edgev1.GatewayServer
|
||||
}
|
||||
|
||||
// newConnectEdgeAdapter wraps impl as a Connect handler.
|
||||
func newConnectEdgeAdapter(impl gatewayv1.EdgeGatewayServer) gatewayv1connect.EdgeGatewayHandler {
|
||||
func newConnectEdgeAdapter(impl edgev1.GatewayServer) edgev1connect.GatewayHandler {
|
||||
return &connectEdgeAdapter{impl: impl}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func newConnectEdgeAdapter(impl gatewayv1.EdgeGatewayServer) gatewayv1connect.Ed
|
||||
// service, and wraps the typed response. gRPC `status.Error` values
|
||||
// returned by the decorator stack are translated to *connect.Error so
|
||||
// the Connect client receives the matching code and message.
|
||||
func (a *connectEdgeAdapter) ExecuteCommand(ctx context.Context, req *connect.Request[gatewayv1.ExecuteCommandRequest]) (*connect.Response[gatewayv1.ExecuteCommandResponse], error) {
|
||||
func (a *connectEdgeAdapter) ExecuteCommand(ctx context.Context, req *connect.Request[edgev1.ExecuteCommandRequest]) (*connect.Response[edgev1.ExecuteCommandResponse], error) {
|
||||
resp, err := a.impl.ExecuteCommand(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, translateGRPCStatusError(err)
|
||||
@@ -48,7 +48,7 @@ func (a *connectEdgeAdapter) ExecuteCommand(ctx context.Context, req *connect.Re
|
||||
// stream; the remaining grpc.ServerStream surface is satisfied by no-op
|
||||
// shims so the interface contract is met without panicking. Errors
|
||||
// returned by the decorator stack are translated to *connect.Error.
|
||||
func (a *connectEdgeAdapter) SubscribeEvents(ctx context.Context, req *connect.Request[gatewayv1.SubscribeEventsRequest], stream *connect.ServerStream[gatewayv1.GatewayEvent]) error {
|
||||
func (a *connectEdgeAdapter) SubscribeEvents(ctx context.Context, req *connect.Request[edgev1.SubscribeEventsRequest], stream *connect.ServerStream[edgev1.GatewayEvent]) error {
|
||||
wrapped := &connectEdgeStream{ctx: ctx, stream: stream}
|
||||
if err := a.impl.SubscribeEvents(req.Msg, wrapped); err != nil {
|
||||
return translateGRPCStatusError(err)
|
||||
@@ -83,19 +83,19 @@ func translateGRPCStatusError(err error) error {
|
||||
return connect.NewError(connect.Code(grpcStatus.Code()), errors.New(grpcStatus.Message()))
|
||||
}
|
||||
|
||||
// connectEdgeStream satisfies grpc.ServerStreamingServer[gatewayv1.GatewayEvent]
|
||||
// connectEdgeStream satisfies grpc.ServerStreamingServer[edgev1.GatewayEvent]
|
||||
// on top of *connect.ServerStream. The decorator stack reads the request
|
||||
// context and pushes outbound events through Send; the rest of the
|
||||
// grpc.ServerStream surface is not exercised in the gateway, so the no-op
|
||||
// implementations preserve the type contract without surprising behaviour.
|
||||
type connectEdgeStream struct {
|
||||
ctx context.Context
|
||||
stream *connect.ServerStream[gatewayv1.GatewayEvent]
|
||||
stream *connect.ServerStream[edgev1.GatewayEvent]
|
||||
}
|
||||
|
||||
// Send forwards a typed gateway event through the underlying Connect server
|
||||
// stream.
|
||||
func (s *connectEdgeStream) Send(event *gatewayv1.GatewayEvent) error {
|
||||
func (s *connectEdgeStream) Send(event *edgev1.GatewayEvent) error {
|
||||
return s.stream.Send(event)
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ func (s *connectEdgeStream) SetTrailer(metadata.MD) {}
|
||||
// SendMsg directly; if a future caller does, the typed Send path is used
|
||||
// when the message is a GatewayEvent.
|
||||
func (s *connectEdgeStream) SendMsg(m any) error {
|
||||
event, ok := m.(*gatewayv1.GatewayEvent)
|
||||
event, ok := m.(*edgev1.GatewayEvent)
|
||||
if !ok {
|
||||
return fmt.Errorf("connectEdgeStream.SendMsg: unsupported message type %T", m)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"buf.build/go/protovalidate"
|
||||
"google.golang.org/grpc"
|
||||
@@ -47,14 +47,14 @@ func parsedEnvelopeFromContext(ctx context.Context) (parsedEnvelope, bool) {
|
||||
// envelopeValidatingService applies envelope parsing and the protocol gate
|
||||
// before delegating to the configured service implementation.
|
||||
type envelopeValidatingService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
delegate gatewayv1.EdgeGatewayServer
|
||||
delegate edgev1.GatewayServer
|
||||
}
|
||||
|
||||
// ExecuteCommand validates req and only then forwards it to the configured
|
||||
// delegate with the parsed envelope attached to ctx.
|
||||
func (s envelopeValidatingService) ExecuteCommand(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
func (s envelopeValidatingService) ExecuteCommand(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
envelope, err := parseExecuteCommandRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -65,7 +65,7 @@ func (s envelopeValidatingService) ExecuteCommand(ctx context.Context, req *gate
|
||||
|
||||
// SubscribeEvents validates req and only then forwards it to the configured
|
||||
// delegate with the parsed envelope attached to the stream context.
|
||||
func (s envelopeValidatingService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s envelopeValidatingService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
envelope, err := parseSubscribeEventsRequest(req)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -79,7 +79,7 @@ func (s envelopeValidatingService) SubscribeEvents(req *gatewayv1.SubscribeEvent
|
||||
|
||||
// parseExecuteCommandRequest validates req according to the request-envelope
|
||||
// rules and returns a cloned parsed envelope suitable for later auth steps.
|
||||
func parseExecuteCommandRequest(req *gatewayv1.ExecuteCommandRequest) (parsedEnvelope, error) {
|
||||
func parseExecuteCommandRequest(req *edgev1.ExecuteCommandRequest) (parsedEnvelope, error) {
|
||||
if req == nil {
|
||||
return parsedEnvelope{}, newMalformedEnvelopeError("request envelope must not be nil")
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func parseExecuteCommandRequest(req *gatewayv1.ExecuteCommandRequest) (parsedEnv
|
||||
|
||||
// parseSubscribeEventsRequest validates req according to the request-envelope
|
||||
// rules and returns a cloned parsed envelope suitable for later auth steps.
|
||||
func parseSubscribeEventsRequest(req *gatewayv1.SubscribeEventsRequest) (parsedEnvelope, error) {
|
||||
func parseSubscribeEventsRequest(req *edgev1.SubscribeEventsRequest) (parsedEnvelope, error) {
|
||||
if req == nil {
|
||||
return parsedEnvelope{}, newMalformedEnvelopeError("request envelope must not be nil")
|
||||
}
|
||||
@@ -131,13 +131,13 @@ func parseSubscribeEventsRequest(req *gatewayv1.SubscribeEventsRequest) (parsedE
|
||||
|
||||
// newEnvelopeValidatingService wraps delegate with the envelope-validation
|
||||
// gate.
|
||||
func newEnvelopeValidatingService(delegate gatewayv1.EdgeGatewayServer) gatewayv1.EdgeGatewayServer {
|
||||
func newEnvelopeValidatingService(delegate edgev1.GatewayServer) edgev1.GatewayServer {
|
||||
return envelopeValidatingService{delegate: delegate}
|
||||
}
|
||||
|
||||
// canonicalExecuteCommandValidationError maps any ExecuteCommand validation
|
||||
// failure into the stable canonical error chosen by field order.
|
||||
func canonicalExecuteCommandValidationError(req *gatewayv1.ExecuteCommandRequest) error {
|
||||
func canonicalExecuteCommandValidationError(req *edgev1.ExecuteCommandRequest) error {
|
||||
switch {
|
||||
case req.GetProtocolVersion() == "":
|
||||
return newMalformedEnvelopeError("protocol_version must not be empty")
|
||||
@@ -162,7 +162,7 @@ func canonicalExecuteCommandValidationError(req *gatewayv1.ExecuteCommandRequest
|
||||
|
||||
// canonicalSubscribeEventsValidationError maps any SubscribeEvents validation
|
||||
// failure into the stable canonical error chosen by field order.
|
||||
func canonicalSubscribeEventsValidationError(req *gatewayv1.SubscribeEventsRequest) error {
|
||||
func canonicalSubscribeEventsValidationError(req *edgev1.SubscribeEventsRequest) error {
|
||||
switch {
|
||||
case req.GetProtocolVersion() == "":
|
||||
return newMalformedEnvelopeError("protocol_version must not be empty")
|
||||
@@ -198,7 +198,7 @@ func newUnsupportedProtocolVersionError(version string) error {
|
||||
type parsedEnvelopeContextKey struct{}
|
||||
|
||||
type envelopeContextStream struct {
|
||||
grpc.ServerStreamingServer[gatewayv1.GatewayEvent]
|
||||
grpc.ServerStreamingServer[edgev1.GatewayEvent]
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
@@ -210,4 +210,4 @@ func (s envelopeContextStream) Context() context.Context {
|
||||
return s.ctx
|
||||
}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = envelopeValidatingService{}
|
||||
var _ edgev1.GatewayServer = envelopeValidatingService{}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -19,10 +19,10 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
mutate func(*gatewayv1.ExecuteCommandRequest)
|
||||
mutate func(*edgev1.ExecuteCommandRequest)
|
||||
wantCode codes.Code
|
||||
wantMessage string
|
||||
assertValid func(*testing.T, *gatewayv1.ExecuteCommandRequest, parsedEnvelope)
|
||||
assertValid func(*testing.T, *edgev1.ExecuteCommandRequest, parsedEnvelope)
|
||||
}{
|
||||
{
|
||||
name: "nil request",
|
||||
@@ -31,7 +31,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty protocol version",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.ProtocolVersion = ""
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -39,7 +39,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty device session id",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.DeviceSessionId = ""
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -47,7 +47,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty message type",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.MessageType = ""
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -55,7 +55,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "zero timestamp",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.TimestampMs = 0
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -63,7 +63,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty request id",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.RequestId = ""
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -71,7 +71,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty payload bytes",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.PayloadBytes = nil
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -79,7 +79,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty payload hash",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.PayloadHash = nil
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -87,7 +87,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty signature",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.Signature = nil
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -95,7 +95,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "unsupported protocol version",
|
||||
mutate: func(req *gatewayv1.ExecuteCommandRequest) {
|
||||
mutate: func(req *edgev1.ExecuteCommandRequest) {
|
||||
req.ProtocolVersion = "v2"
|
||||
},
|
||||
wantCode: codes.FailedPrecondition,
|
||||
@@ -104,7 +104,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
{
|
||||
name: "valid request",
|
||||
wantCode: codes.OK,
|
||||
assertValid: func(t *testing.T, req *gatewayv1.ExecuteCommandRequest, envelope parsedEnvelope) {
|
||||
assertValid: func(t *testing.T, req *edgev1.ExecuteCommandRequest, envelope parsedEnvelope) {
|
||||
t.Helper()
|
||||
|
||||
assert.Equal(t, supportedProtocolVersion, envelope.ProtocolVersion)
|
||||
@@ -138,7 +138,7 @@ func TestParseExecuteCommandRequest(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var req *gatewayv1.ExecuteCommandRequest
|
||||
var req *edgev1.ExecuteCommandRequest
|
||||
if tt.name != "nil request" {
|
||||
req = newValidExecuteCommandRequest()
|
||||
if tt.mutate != nil {
|
||||
@@ -166,10 +166,10 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
mutate func(*gatewayv1.SubscribeEventsRequest)
|
||||
mutate func(*edgev1.SubscribeEventsRequest)
|
||||
wantCode codes.Code
|
||||
wantMessage string
|
||||
assertValid func(*testing.T, *gatewayv1.SubscribeEventsRequest, parsedEnvelope)
|
||||
assertValid func(*testing.T, *edgev1.SubscribeEventsRequest, parsedEnvelope)
|
||||
}{
|
||||
{
|
||||
name: "nil request",
|
||||
@@ -178,7 +178,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty protocol version",
|
||||
mutate: func(req *gatewayv1.SubscribeEventsRequest) {
|
||||
mutate: func(req *edgev1.SubscribeEventsRequest) {
|
||||
req.ProtocolVersion = ""
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -186,7 +186,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty device session id",
|
||||
mutate: func(req *gatewayv1.SubscribeEventsRequest) {
|
||||
mutate: func(req *edgev1.SubscribeEventsRequest) {
|
||||
req.DeviceSessionId = ""
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -194,7 +194,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty message type",
|
||||
mutate: func(req *gatewayv1.SubscribeEventsRequest) {
|
||||
mutate: func(req *edgev1.SubscribeEventsRequest) {
|
||||
req.MessageType = ""
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -202,7 +202,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "zero timestamp",
|
||||
mutate: func(req *gatewayv1.SubscribeEventsRequest) {
|
||||
mutate: func(req *edgev1.SubscribeEventsRequest) {
|
||||
req.TimestampMs = 0
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -210,7 +210,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty request id",
|
||||
mutate: func(req *gatewayv1.SubscribeEventsRequest) {
|
||||
mutate: func(req *edgev1.SubscribeEventsRequest) {
|
||||
req.RequestId = ""
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -218,7 +218,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty payload hash",
|
||||
mutate: func(req *gatewayv1.SubscribeEventsRequest) {
|
||||
mutate: func(req *edgev1.SubscribeEventsRequest) {
|
||||
req.PayloadHash = nil
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -226,7 +226,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty signature",
|
||||
mutate: func(req *gatewayv1.SubscribeEventsRequest) {
|
||||
mutate: func(req *edgev1.SubscribeEventsRequest) {
|
||||
req.Signature = nil
|
||||
},
|
||||
wantCode: codes.InvalidArgument,
|
||||
@@ -234,7 +234,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "unsupported protocol version",
|
||||
mutate: func(req *gatewayv1.SubscribeEventsRequest) {
|
||||
mutate: func(req *edgev1.SubscribeEventsRequest) {
|
||||
req.ProtocolVersion = "v2"
|
||||
},
|
||||
wantCode: codes.FailedPrecondition,
|
||||
@@ -243,7 +243,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
{
|
||||
name: "valid request with empty payload bytes",
|
||||
wantCode: codes.OK,
|
||||
assertValid: func(t *testing.T, req *gatewayv1.SubscribeEventsRequest, envelope parsedEnvelope) {
|
||||
assertValid: func(t *testing.T, req *edgev1.SubscribeEventsRequest, envelope parsedEnvelope) {
|
||||
t.Helper()
|
||||
|
||||
assert.Empty(t, req.GetPayloadBytes())
|
||||
@@ -260,7 +260,7 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var req *gatewayv1.SubscribeEventsRequest
|
||||
var req *edgev1.SubscribeEventsRequest
|
||||
if tt.name != "nil request" {
|
||||
req = newValidSubscribeEventsRequest()
|
||||
if tt.mutate != nil {
|
||||
@@ -286,10 +286,10 @@ func TestParseSubscribeEventsRequest(t *testing.T) {
|
||||
func TestEnvelopeValidatingServiceExecuteCommandRejectsInvalidRequestBeforeDelegate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
service := newEnvelopeValidatingService(delegate)
|
||||
|
||||
_, err := service.ExecuteCommand(context.Background(), &gatewayv1.ExecuteCommandRequest{})
|
||||
_, err := service.ExecuteCommand(context.Background(), &edgev1.ExecuteCommandRequest{})
|
||||
require.Error(t, err)
|
||||
|
||||
assert.Equal(t, codes.InvalidArgument, status.Code(err))
|
||||
@@ -299,10 +299,10 @@ func TestEnvelopeValidatingServiceExecuteCommandRejectsInvalidRequestBeforeDeleg
|
||||
func TestEnvelopeValidatingServiceSubscribeEventsRejectsInvalidRequestBeforeDelegate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
service := newEnvelopeValidatingService(delegate)
|
||||
|
||||
err := service.SubscribeEvents(&gatewayv1.SubscribeEventsRequest{}, stubGatewayEventStream{})
|
||||
err := service.SubscribeEvents(&edgev1.SubscribeEventsRequest{}, stubGatewayEventStream{})
|
||||
require.Error(t, err)
|
||||
|
||||
assert.Equal(t, codes.InvalidArgument, status.Code(err))
|
||||
@@ -313,15 +313,15 @@ func TestEnvelopeValidatingServiceExecuteCommandAttachesParsedEnvelope(t *testin
|
||||
t.Parallel()
|
||||
|
||||
want := newValidExecuteCommandRequest()
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
delegate := &recordingGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
envelope, ok := parsedEnvelopeFromContext(ctx)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, want.GetRequestId(), envelope.RequestID)
|
||||
assert.Equal(t, want.GetDeviceSessionId(), envelope.DeviceSessionID)
|
||||
assert.Equal(t, want.GetMessageType(), envelope.MessageType)
|
||||
assert.Equal(t, want.GetPayloadBytes(), envelope.PayloadBytes)
|
||||
return &gatewayv1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
return &edgev1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
},
|
||||
}
|
||||
service := newEnvelopeValidatingService(delegate)
|
||||
@@ -337,8 +337,8 @@ func TestEnvelopeValidatingServiceSubscribeEventsAttachesParsedEnvelope(t *testi
|
||||
t.Parallel()
|
||||
|
||||
want := newValidSubscribeEventsRequest()
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
subscribeEventsFunc: func(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
delegate := &recordingGatewayService{
|
||||
subscribeEventsFunc: func(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
envelope, ok := parsedEnvelopeFromContext(stream.Context())
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, want.GetRequestId(), envelope.RequestID)
|
||||
@@ -357,25 +357,25 @@ func TestEnvelopeValidatingServiceSubscribeEventsAttachesParsedEnvelope(t *testi
|
||||
assert.Equal(t, 1, delegate.subscribeCalls)
|
||||
}
|
||||
|
||||
type recordingEdgeGatewayService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
type recordingGatewayService struct {
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
executeCalls int
|
||||
subscribeCalls int
|
||||
executeCommandFunc func(context.Context, *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error)
|
||||
subscribeEventsFunc func(*gatewayv1.SubscribeEventsRequest, grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error
|
||||
executeCommandFunc func(context.Context, *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error)
|
||||
subscribeEventsFunc func(*edgev1.SubscribeEventsRequest, grpc.ServerStreamingServer[edgev1.GatewayEvent]) error
|
||||
}
|
||||
|
||||
func (s *recordingEdgeGatewayService) ExecuteCommand(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
func (s *recordingGatewayService) ExecuteCommand(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
s.executeCalls++
|
||||
if s.executeCommandFunc != nil {
|
||||
return s.executeCommandFunc(ctx, req)
|
||||
}
|
||||
|
||||
return &gatewayv1.ExecuteCommandResponse{}, nil
|
||||
return &edgev1.ExecuteCommandResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *recordingEdgeGatewayService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s *recordingGatewayService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
s.subscribeCalls++
|
||||
if s.subscribeEventsFunc != nil {
|
||||
return s.subscribeEventsFunc(req, stream)
|
||||
@@ -389,7 +389,7 @@ type stubGatewayEventStream struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (s stubGatewayEventStream) Send(*gatewayv1.GatewayEvent) error {
|
||||
func (s stubGatewayEventStream) Send(*edgev1.GatewayEvent) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
|
||||
"galaxy/gateway/internal/clock"
|
||||
"galaxy/gateway/internal/replay"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -19,9 +19,9 @@ const minimumReplayReservationTTL = time.Millisecond
|
||||
// freshnessAndReplayService applies freshness and anti-replay checks after
|
||||
// client-signature verification and before later policy or routing steps run.
|
||||
type freshnessAndReplayService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
delegate gatewayv1.EdgeGatewayServer
|
||||
delegate edgev1.GatewayServer
|
||||
clock clock.Clock
|
||||
replayStore replay.Store
|
||||
freshnessWindow time.Duration
|
||||
@@ -29,7 +29,7 @@ type freshnessAndReplayService struct {
|
||||
|
||||
// ExecuteCommand verifies request freshness and replay protection before
|
||||
// delegating to the configured service implementation.
|
||||
func (s freshnessAndReplayService) ExecuteCommand(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
func (s freshnessAndReplayService) ExecuteCommand(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
if err := s.verifyFreshnessAndReplay(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -39,7 +39,7 @@ func (s freshnessAndReplayService) ExecuteCommand(ctx context.Context, req *gate
|
||||
|
||||
// SubscribeEvents verifies request freshness and replay protection before
|
||||
// delegating to the configured service implementation.
|
||||
func (s freshnessAndReplayService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s freshnessAndReplayService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
if err := s.verifyFreshnessAndReplay(stream.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -49,7 +49,7 @@ func (s freshnessAndReplayService) SubscribeEvents(req *gatewayv1.SubscribeEvent
|
||||
|
||||
// newFreshnessAndReplayService wraps delegate with the freshness and replay
|
||||
// gate.
|
||||
func newFreshnessAndReplayService(delegate gatewayv1.EdgeGatewayServer, clk clock.Clock, replayStore replay.Store, freshnessWindow time.Duration) gatewayv1.EdgeGatewayServer {
|
||||
func newFreshnessAndReplayService(delegate edgev1.GatewayServer, clk clock.Clock, replayStore replay.Store, freshnessWindow time.Duration) edgev1.GatewayServer {
|
||||
return freshnessAndReplayService{
|
||||
delegate: delegate,
|
||||
clock: clk,
|
||||
@@ -92,4 +92,4 @@ func (unavailableReplayStore) Reserve(context.Context, string, string, time.Dura
|
||||
return errors.New("replay store is unavailable")
|
||||
}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = freshnessAndReplayService{}
|
||||
var _ edgev1.GatewayServer = freshnessAndReplayService{}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"galaxy/gateway/internal/replay"
|
||||
"galaxy/gateway/internal/session"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -40,7 +40,7 @@ func TestExecuteCommandRejectsStaleTimestamp(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -82,7 +82,7 @@ func TestSubscribeEventsRejectsStaleTimestamp(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -104,7 +104,7 @@ func TestSubscribeEventsRejectsStaleTimestamp(t *testing.T) {
|
||||
func TestExecuteCommandRejectsReplay(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -131,7 +131,7 @@ func TestExecuteCommandRejectsReplay(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsReplay(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -162,9 +162,9 @@ func TestSubscribeEventsRejectsReplay(t *testing.T) {
|
||||
func TestExecuteCommandAllowsSameRequestIDAcrossDistinctSessions(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
return &gatewayv1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
delegate := &recordingGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
return &edgev1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -196,8 +196,8 @@ func TestExecuteCommandAllowsSameRequestIDAcrossDistinctSessions(t *testing.T) {
|
||||
func TestSubscribeEventsAllowsSameRequestIDAcrossDistinctSessions(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
subscribeEventsFunc: func(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
delegate := &recordingGatewayService{
|
||||
subscribeEventsFunc: func(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -238,7 +238,7 @@ func TestSubscribeEventsAllowsSameRequestIDAcrossDistinctSessions(t *testing.T)
|
||||
func TestExecuteCommandRejectsReplayStoreUnavailable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -262,7 +262,7 @@ func TestExecuteCommandRejectsReplayStoreUnavailable(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsReplayStoreUnavailable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -286,9 +286,9 @@ func TestSubscribeEventsRejectsReplayStoreUnavailable(t *testing.T) {
|
||||
func TestExecuteCommandFreshRequestReachesDelegateAndUsesDynamicReplayTTL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
return &gatewayv1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
delegate := &recordingGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
return &edgev1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -324,8 +324,8 @@ func TestExecuteCommandFreshRequestReachesDelegateAndUsesDynamicReplayTTL(t *tes
|
||||
func TestSubscribeEventsFreshRequestReachesDelegateAndUsesDynamicReplayTTL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
subscribeEventsFunc: func(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
delegate := &recordingGatewayService{
|
||||
subscribeEventsFunc: func(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -361,9 +361,9 @@ func TestSubscribeEventsFreshRequestReachesDelegateAndUsesDynamicReplayTTL(t *te
|
||||
func TestExecuteCommandFutureSkewUsesExtendedReplayTTL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
return &gatewayv1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
delegate := &recordingGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
return &edgev1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -395,9 +395,9 @@ func TestExecuteCommandFutureSkewUsesExtendedReplayTTL(t *testing.T) {
|
||||
func TestExecuteCommandBoundaryFreshnessUsesMinimumReplayTTL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
return &gatewayv1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
delegate := &recordingGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
return &edgev1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"galaxy/gateway/internal/logging"
|
||||
"galaxy/gateway/internal/telemetry"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.uber.org/zap"
|
||||
@@ -78,9 +78,9 @@ func recordEdgeRequest(logger *zap.Logger, metrics *telemetry.Runtime, ctx conte
|
||||
|
||||
func envelopeFieldsFromRequest(req any) (messageType string, requestID string, traceID string) {
|
||||
switch typed := req.(type) {
|
||||
case *gatewayv1.ExecuteCommandRequest:
|
||||
case *edgev1.ExecuteCommandRequest:
|
||||
return typed.GetMessageType(), typed.GetRequestId(), typed.GetTraceId()
|
||||
case *gatewayv1.SubscribeEventsRequest:
|
||||
case *edgev1.SubscribeEventsRequest:
|
||||
return typed.GetMessageType(), typed.GetRequestId(), typed.GetTraceId()
|
||||
default:
|
||||
return "", "", ""
|
||||
@@ -88,7 +88,7 @@ func envelopeFieldsFromRequest(req any) (messageType string, requestID string, t
|
||||
}
|
||||
|
||||
func resultCodeFromResponse(resp any) string {
|
||||
typed, ok := resp.(*gatewayv1.ExecuteCommandResponse)
|
||||
typed, ok := resp.(*edgev1.ExecuteCommandResponse)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
|
||||
"galaxy/gateway/authn"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -15,14 +15,14 @@ import (
|
||||
// payloadHashVerifyingService applies payload-hash verification after session
|
||||
// lookup and before any later auth or routing step runs.
|
||||
type payloadHashVerifyingService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
delegate gatewayv1.EdgeGatewayServer
|
||||
delegate edgev1.GatewayServer
|
||||
}
|
||||
|
||||
// ExecuteCommand verifies req payload integrity before delegating to the
|
||||
// configured service implementation.
|
||||
func (s payloadHashVerifyingService) ExecuteCommand(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
func (s payloadHashVerifyingService) ExecuteCommand(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
if err := verifyPayloadHash(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -32,7 +32,7 @@ func (s payloadHashVerifyingService) ExecuteCommand(ctx context.Context, req *ga
|
||||
|
||||
// SubscribeEvents verifies req payload integrity before delegating to the
|
||||
// configured service implementation.
|
||||
func (s payloadHashVerifyingService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s payloadHashVerifyingService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
if err := verifyPayloadHash(stream.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -42,7 +42,7 @@ func (s payloadHashVerifyingService) SubscribeEvents(req *gatewayv1.SubscribeEve
|
||||
|
||||
// newPayloadHashVerifyingService wraps delegate with the payload-hash
|
||||
// verification gate.
|
||||
func newPayloadHashVerifyingService(delegate gatewayv1.EdgeGatewayServer) gatewayv1.EdgeGatewayServer {
|
||||
func newPayloadHashVerifyingService(delegate edgev1.GatewayServer) edgev1.GatewayServer {
|
||||
return payloadHashVerifyingService{delegate: delegate}
|
||||
}
|
||||
|
||||
@@ -63,4 +63,4 @@ func verifyPayloadHash(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = payloadHashVerifyingService{}
|
||||
var _ edgev1.GatewayServer = payloadHashVerifyingService{}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
func TestExecuteCommandRejectsPayloadHashWithInvalidLength(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -38,7 +38,7 @@ func TestExecuteCommandRejectsPayloadHashWithInvalidLength(t *testing.T) {
|
||||
func TestExecuteCommandRejectsPayloadHashMismatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -62,7 +62,7 @@ func TestExecuteCommandRejectsPayloadHashMismatch(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsPayloadHashWithInvalidLength(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -85,7 +85,7 @@ func TestSubscribeEventsRejectsPayloadHashWithInvalidLength(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsPayloadHashMismatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"galaxy/gateway/internal/logging"
|
||||
"galaxy/gateway/internal/push"
|
||||
"galaxy/gateway/internal/telemetry"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
// NewFanOutPushStreamService constructs the authenticated SubscribeEvents tail
|
||||
// service that registers active streams in hub and forwards client-facing
|
||||
// events after the bootstrap event has been sent.
|
||||
func NewFanOutPushStreamService(hub *push.Hub, responseSigner authn.ResponseSigner, clk clock.Clock, logger *zap.Logger) gatewayv1.EdgeGatewayServer {
|
||||
func NewFanOutPushStreamService(hub *push.Hub, responseSigner authn.ResponseSigner, clk clock.Clock, logger *zap.Logger) edgev1.GatewayServer {
|
||||
if responseSigner == nil {
|
||||
responseSigner = unavailableResponseSigner{}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func NewFanOutPushStreamService(hub *push.Hub, responseSigner authn.ResponseSign
|
||||
// fanOutPushStreamService owns the post-bootstrap authenticated push-stream
|
||||
// lifecycle backed by the in-memory push hub.
|
||||
type fanOutPushStreamService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
hub *push.Hub
|
||||
responseSigner authn.ResponseSigner
|
||||
@@ -54,7 +54,7 @@ type fanOutPushStreamService struct {
|
||||
|
||||
// SubscribeEvents registers the verified stream in the push hub and forwards
|
||||
// matching client-facing events until the stream ends.
|
||||
func (s fanOutPushStreamService) SubscribeEvents(_ *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s fanOutPushStreamService) SubscribeEvents(_ *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
binding, ok := authenticatedStreamBindingFromContext(stream.Context())
|
||||
if !ok {
|
||||
return status.Error(codes.Internal, "authenticated request context is incomplete")
|
||||
@@ -109,7 +109,7 @@ func (s fanOutPushStreamService) SubscribeEvents(_ *gatewayv1.SubscribeEventsReq
|
||||
}
|
||||
}
|
||||
|
||||
func (s fanOutPushStreamService) buildGatewayEvent(event push.Event) (*gatewayv1.GatewayEvent, error) {
|
||||
func (s fanOutPushStreamService) buildGatewayEvent(event push.Event) (*edgev1.GatewayEvent, error) {
|
||||
timestampMS := s.clock.Now().UTC().UnixMilli()
|
||||
payloadHash := sha256.Sum256(event.PayloadBytes)
|
||||
|
||||
@@ -125,7 +125,7 @@ func (s fanOutPushStreamService) buildGatewayEvent(event push.Event) (*gatewayv1
|
||||
return nil, status.Error(codes.Unavailable, "response signer is unavailable")
|
||||
}
|
||||
|
||||
return &gatewayv1.GatewayEvent{
|
||||
return &edgev1.GatewayEvent{
|
||||
EventType: event.EventType,
|
||||
EventId: event.EventID,
|
||||
TimestampMs: timestampMS,
|
||||
@@ -169,4 +169,4 @@ func mapSubscriptionOutcome(err error) telemetry.EdgeOutcome {
|
||||
}
|
||||
}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = fanOutPushStreamService{}
|
||||
var _ edgev1.GatewayServer = fanOutPushStreamService{}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"galaxy/gateway/internal/telemetry"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"google.golang.org/grpc"
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
// 15-second default a fully-idle stream costs ~840 KB/day per client;
|
||||
// see `docs/ARCHITECTURE.md` for the per-scale projection.
|
||||
type heartbeatingStream struct {
|
||||
grpc.ServerStreamingServer[gatewayv1.GatewayEvent]
|
||||
grpc.ServerStreamingServer[edgev1.GatewayEvent]
|
||||
|
||||
interval time.Duration
|
||||
metrics *telemetry.Runtime
|
||||
@@ -43,7 +43,7 @@ type heartbeatingStream struct {
|
||||
// the wrapping entirely; non-nil returns must have `Stop()` called once
|
||||
// the stream lifecycle ends.
|
||||
func newHeartbeatingStream(
|
||||
inner grpc.ServerStreamingServer[gatewayv1.GatewayEvent],
|
||||
inner grpc.ServerStreamingServer[edgev1.GatewayEvent],
|
||||
interval time.Duration,
|
||||
metrics *telemetry.Runtime,
|
||||
) *heartbeatingStream {
|
||||
@@ -64,7 +64,7 @@ func newHeartbeatingStream(
|
||||
// so the heartbeat goroutine waits a fresh interval before firing
|
||||
// again. A Send that succeeds means the transport just delivered real
|
||||
// bytes; the silence window restarts from "now".
|
||||
func (s *heartbeatingStream) Send(event *gatewayv1.GatewayEvent) error {
|
||||
func (s *heartbeatingStream) Send(event *edgev1.GatewayEvent) error {
|
||||
s.sendMu.Lock()
|
||||
defer s.sendMu.Unlock()
|
||||
if err := s.ServerStreamingServer.Send(event); err != nil {
|
||||
@@ -158,6 +158,6 @@ func (s *heartbeatingStream) resetTimerLocked() {
|
||||
// EventType is left at its proto3 default so the wire frame stays as
|
||||
// small as Connect framing allows. See `gatewayHeartbeatEventType` for
|
||||
// the security rationale of leaving the event unsigned.
|
||||
func buildHeartbeatEvent() *gatewayv1.GatewayEvent {
|
||||
return &gatewayv1.GatewayEvent{EventType: gatewayHeartbeatEventType}
|
||||
func buildHeartbeatEvent() *edgev1.GatewayEvent {
|
||||
return &edgev1.GatewayEvent{EventType: gatewayHeartbeatEventType}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -66,7 +66,7 @@ func TestHeartbeatingStreamRealSendResetsSilenceTimer(t *testing.T) {
|
||||
defer ticker.Stop()
|
||||
for range 6 {
|
||||
<-ticker.C
|
||||
if err := hb.Send(&gatewayv1.GatewayEvent{EventType: "real.event"}); err != nil {
|
||||
if err := hb.Send(&edgev1.GatewayEvent{EventType: "real.event"}); err != nil {
|
||||
t.Errorf("real Send failed: %v", err)
|
||||
return
|
||||
}
|
||||
@@ -134,16 +134,16 @@ func TestHeartbeatingStreamSendErrorPropagates(t *testing.T) {
|
||||
require.NotNil(t, hb)
|
||||
defer hb.Stop()
|
||||
|
||||
err := hb.Send(&gatewayv1.GatewayEvent{EventType: "real.event"})
|
||||
err := hb.Send(&edgev1.GatewayEvent{EventType: "real.event"})
|
||||
require.ErrorIs(t, err, wantErr)
|
||||
}
|
||||
|
||||
// capturingStream is a minimal grpc.ServerStreamingServer that pushes
|
||||
// every Send into a channel so tests can assert on the wire frame.
|
||||
type capturingStream struct {
|
||||
grpc.ServerStreamingServer[gatewayv1.GatewayEvent]
|
||||
grpc.ServerStreamingServer[edgev1.GatewayEvent]
|
||||
|
||||
events chan *gatewayv1.GatewayEvent
|
||||
events chan *edgev1.GatewayEvent
|
||||
sendErr atomic.Pointer[errorBox]
|
||||
}
|
||||
|
||||
@@ -152,10 +152,10 @@ type errorBox struct{ err error }
|
||||
func newCapturingStream(t *testing.T) *capturingStream {
|
||||
t.Helper()
|
||||
|
||||
return &capturingStream{events: make(chan *gatewayv1.GatewayEvent, 16)}
|
||||
return &capturingStream{events: make(chan *edgev1.GatewayEvent, 16)}
|
||||
}
|
||||
|
||||
func (s *capturingStream) Send(event *gatewayv1.GatewayEvent) error {
|
||||
func (s *capturingStream) Send(event *edgev1.GatewayEvent) error {
|
||||
if box := s.sendErr.Load(); box != nil {
|
||||
return box.err
|
||||
}
|
||||
@@ -172,7 +172,7 @@ func (s *capturingStream) SetTrailer(metadata.MD) {}
|
||||
func (s *capturingStream) SendMsg(any) error { return errors.New("capturingStream.SendMsg: unused") }
|
||||
func (s *capturingStream) RecvMsg(any) error { return errors.New("capturingStream.RecvMsg: unused") }
|
||||
|
||||
func (s *capturingStream) recv(t *testing.T, timeout time.Duration) *gatewayv1.GatewayEvent {
|
||||
func (s *capturingStream) recv(t *testing.T, timeout time.Duration) *edgev1.GatewayEvent {
|
||||
t.Helper()
|
||||
|
||||
select {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"galaxy/gateway/authn"
|
||||
"galaxy/gateway/internal/clock"
|
||||
"galaxy/gateway/internal/telemetry"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
gatewayfbs "galaxy/schema/fbs/gateway"
|
||||
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
@@ -81,9 +81,9 @@ func authenticatedStreamBindingFromContext(ctx context.Context) (authenticatedSt
|
||||
// the tail performs and only emits a heartbeat when the silence window
|
||||
// elapses; tails remain heartbeat-unaware.
|
||||
type authenticatedPushStreamService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
tailDelegate gatewayv1.EdgeGatewayServer
|
||||
tailDelegate edgev1.GatewayServer
|
||||
responseSigner authn.ResponseSigner
|
||||
clock clock.Clock
|
||||
heartbeatInterval time.Duration
|
||||
@@ -92,7 +92,7 @@ type authenticatedPushStreamService struct {
|
||||
|
||||
// SubscribeEvents binds the verified stream identity, sends the initial signed
|
||||
// server-time event, and then delegates the remaining lifecycle.
|
||||
func (s authenticatedPushStreamService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s authenticatedPushStreamService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
envelope, ok := parsedEnvelopeFromContext(stream.Context())
|
||||
if !ok {
|
||||
return status.Error(codes.Internal, "authenticated request context is incomplete")
|
||||
@@ -134,7 +134,7 @@ func (s authenticatedPushStreamService) SubscribeEvents(req *gatewayv1.Subscribe
|
||||
return status.Error(codes.Unavailable, "response signer is unavailable")
|
||||
}
|
||||
|
||||
if err := boundStream.Send(&gatewayv1.GatewayEvent{
|
||||
if err := boundStream.Send(&edgev1.GatewayEvent{
|
||||
EventType: serverTimeEventType,
|
||||
EventId: envelope.RequestID,
|
||||
TimestampMs: serverTimeMS,
|
||||
@@ -147,7 +147,7 @@ func (s authenticatedPushStreamService) SubscribeEvents(req *gatewayv1.Subscribe
|
||||
return err
|
||||
}
|
||||
|
||||
var streamForTail grpc.ServerStreamingServer[gatewayv1.GatewayEvent] = boundStream
|
||||
var streamForTail grpc.ServerStreamingServer[edgev1.GatewayEvent] = boundStream
|
||||
if hbStream := newHeartbeatingStream(boundStream, s.heartbeatInterval, s.metrics); hbStream != nil {
|
||||
defer hbStream.Stop()
|
||||
go func() {
|
||||
@@ -165,12 +165,12 @@ func (s authenticatedPushStreamService) SubscribeEvents(req *gatewayv1.Subscribe
|
||||
}
|
||||
|
||||
func newAuthenticatedPushStreamService(
|
||||
tailDelegate gatewayv1.EdgeGatewayServer,
|
||||
tailDelegate edgev1.GatewayServer,
|
||||
responseSigner authn.ResponseSigner,
|
||||
clk clock.Clock,
|
||||
heartbeatInterval time.Duration,
|
||||
metrics *telemetry.Runtime,
|
||||
) gatewayv1.EdgeGatewayServer {
|
||||
) edgev1.GatewayServer {
|
||||
if tailDelegate == nil {
|
||||
tailDelegate = holdOpenSubscribeEventsService{}
|
||||
}
|
||||
@@ -197,7 +197,7 @@ func buildServerTimeEventPayload(serverTimeMS int64) []byte {
|
||||
type authenticatedStreamBindingContextKey struct{}
|
||||
|
||||
type authenticatedStreamContextStream struct {
|
||||
grpc.ServerStreamingServer[gatewayv1.GatewayEvent]
|
||||
grpc.ServerStreamingServer[edgev1.GatewayEvent]
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
@@ -210,12 +210,12 @@ func (s authenticatedStreamContextStream) Context() context.Context {
|
||||
}
|
||||
|
||||
type holdOpenSubscribeEventsService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
}
|
||||
|
||||
func (holdOpenSubscribeEventsService) SubscribeEvents(_ *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (holdOpenSubscribeEventsService) SubscribeEvents(_ *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
<-stream.Context().Done()
|
||||
return stream.Context().Err()
|
||||
}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = authenticatedPushStreamService{}
|
||||
var _ edgev1.GatewayServer = authenticatedPushStreamService{}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"galaxy/gateway/internal/config"
|
||||
"galaxy/gateway/internal/ratelimit"
|
||||
"galaxy/gateway/internal/session"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -102,9 +102,9 @@ type AuthenticatedRequestPolicy interface {
|
||||
}
|
||||
|
||||
type authenticatedRateLimitService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
delegate gatewayv1.EdgeGatewayServer
|
||||
delegate edgev1.GatewayServer
|
||||
limiter AuthenticatedRequestLimiter
|
||||
policy AuthenticatedRequestPolicy
|
||||
cfg config.AuthenticatedGRPCAntiAbuseConfig
|
||||
@@ -112,7 +112,7 @@ type authenticatedRateLimitService struct {
|
||||
|
||||
// ExecuteCommand applies authenticated rate limits and edge policy before
|
||||
// delegating to the configured service implementation.
|
||||
func (s authenticatedRateLimitService) ExecuteCommand(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
func (s authenticatedRateLimitService) ExecuteCommand(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
if err := s.applyRateLimitsAndPolicy(ctx, authenticatedRPCExecuteCommand); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func (s authenticatedRateLimitService) ExecuteCommand(ctx context.Context, req *
|
||||
|
||||
// SubscribeEvents applies authenticated rate limits and edge policy before
|
||||
// delegating to the configured service implementation.
|
||||
func (s authenticatedRateLimitService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s authenticatedRateLimitService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
if err := s.applyRateLimitsAndPolicy(stream.Context(), authenticatedRPCSubscribeEvents); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -132,7 +132,7 @@ func (s authenticatedRateLimitService) SubscribeEvents(req *gatewayv1.SubscribeE
|
||||
|
||||
// newAuthenticatedRateLimitService wraps delegate with the authenticated
|
||||
// rate-limit and edge-policy gate.
|
||||
func newAuthenticatedRateLimitService(delegate gatewayv1.EdgeGatewayServer, limiter AuthenticatedRequestLimiter, policy AuthenticatedRequestPolicy, cfg config.AuthenticatedGRPCAntiAbuseConfig) gatewayv1.EdgeGatewayServer {
|
||||
func newAuthenticatedRateLimitService(delegate edgev1.GatewayServer, limiter AuthenticatedRequestLimiter, policy AuthenticatedRequestPolicy, cfg config.AuthenticatedGRPCAntiAbuseConfig) edgev1.GatewayServer {
|
||||
return authenticatedRateLimitService{
|
||||
delegate: delegate,
|
||||
limiter: limiter,
|
||||
@@ -279,4 +279,4 @@ func (noopAuthenticatedRequestPolicy) Evaluate(context.Context, AuthenticatedReq
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = authenticatedRateLimitService{}
|
||||
var _ edgev1.GatewayServer = authenticatedRateLimitService{}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"galaxy/gateway/internal/ratelimit"
|
||||
"galaxy/gateway/internal/restapi"
|
||||
"galaxy/gateway/internal/session"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
func TestExecuteCommandRateLimitsByIP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGatewayWithGRPCConfig(t, newAuthenticatedGRPCConfigForTest(func(cfg *config.AuthenticatedGRPCConfig) {
|
||||
cfg.AntiAbuse.IP = config.AuthenticatedRateLimitConfig{
|
||||
Requests: 1,
|
||||
@@ -54,7 +54,7 @@ func TestExecuteCommandRateLimitsByIP(t *testing.T) {
|
||||
func TestExecuteCommandRateLimitsBySession(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGatewayWithGRPCConfig(t, newAuthenticatedGRPCConfigForTest(func(cfg *config.AuthenticatedGRPCConfig) {
|
||||
cfg.AntiAbuse.Session = config.AuthenticatedRateLimitConfig{
|
||||
Requests: 1,
|
||||
@@ -87,7 +87,7 @@ func TestExecuteCommandRateLimitsBySession(t *testing.T) {
|
||||
func TestExecuteCommandRateLimitsByUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGatewayWithGRPCConfig(t, newAuthenticatedGRPCConfigForTest(func(cfg *config.AuthenticatedGRPCConfig) {
|
||||
cfg.AntiAbuse.User = config.AuthenticatedRateLimitConfig{
|
||||
Requests: 1,
|
||||
@@ -124,7 +124,7 @@ func TestExecuteCommandRateLimitsByUser(t *testing.T) {
|
||||
func TestExecuteCommandRateLimitsByMessageClass(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGatewayWithGRPCConfig(t, newAuthenticatedGRPCConfigForTest(func(cfg *config.AuthenticatedGRPCConfig) {
|
||||
cfg.AntiAbuse.MessageClass = config.AuthenticatedRateLimitConfig{
|
||||
Requests: 1,
|
||||
@@ -161,7 +161,7 @@ func TestAuthenticatedPolicyHookReceivesVerifiedRequest(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
policy := &recordingAuthenticatedRequestPolicy{}
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: userMappedSessionCache(map[string]string{"device-session-123": "user-123"}),
|
||||
@@ -189,7 +189,7 @@ func TestAuthenticatedPolicyHookReceivesVerifiedRequest(t *testing.T) {
|
||||
func TestExecuteCommandPolicyRejectMapsToPermissionDenied(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: userMappedSessionCache(map[string]string{"device-session-123": "user-123"}),
|
||||
@@ -212,7 +212,7 @@ func TestExecuteCommandPolicyRejectMapsToPermissionDenied(t *testing.T) {
|
||||
func TestSubscribeEventsRateLimitRejectsStream(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGatewayWithGRPCConfig(t, newAuthenticatedGRPCConfigForTest(func(cfg *config.AuthenticatedGRPCConfig) {
|
||||
cfg.AntiAbuse.IP = config.AuthenticatedRateLimitConfig{
|
||||
Requests: 1,
|
||||
@@ -274,7 +274,7 @@ func TestAuthenticatedRateLimitsStayIsolatedFromPublicREST(t *testing.T) {
|
||||
AuthService: staticAuthServiceClient{},
|
||||
Limiter: publicLimiterAdapter{limiter: sharedLimiter},
|
||||
})
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
grpcServer := NewServer(grpcCfg, ServerDependencies{
|
||||
Service: delegate,
|
||||
Router: executeCommandAdapterRouter{service: delegate},
|
||||
@@ -342,7 +342,7 @@ func newAuthenticatedGRPCConfigForTest(mutate func(*config.AuthenticatedGRPCConf
|
||||
return cfg
|
||||
}
|
||||
|
||||
func newValidExecuteCommandRequestWithMessageType(deviceSessionID string, requestID string, messageType string) *gatewayv1.ExecuteCommandRequest {
|
||||
func newValidExecuteCommandRequestWithMessageType(deviceSessionID string, requestID string, messageType string) *edgev1.ExecuteCommandRequest {
|
||||
req := newValidExecuteCommandRequestWithSessionAndRequestID(deviceSessionID, requestID)
|
||||
req.MessageType = messageType
|
||||
req.Signature = signRequest(
|
||||
|
||||
@@ -24,8 +24,8 @@ import (
|
||||
"galaxy/gateway/internal/replay"
|
||||
"galaxy/gateway/internal/session"
|
||||
"galaxy/gateway/internal/telemetry"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
"galaxy/gateway/proto/galaxy/gateway/v1/gatewayv1connect"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
"galaxy/gateway/proto/edge/v1/edgev1connect"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
@@ -42,7 +42,7 @@ type ServerDependencies struct {
|
||||
// after the initial authenticated service event has been sent. When nil, the
|
||||
// gateway keeps authenticated SubscribeEvents streams open until the client
|
||||
// cancels them, the server shuts down, or a later stream send fails.
|
||||
Service gatewayv1.EdgeGatewayServer
|
||||
Service edgev1.GatewayServer
|
||||
|
||||
// Router resolves the exact downstream unary client for the verified
|
||||
// message_type value. When nil, the authenticated unary surface uses an
|
||||
@@ -93,7 +93,7 @@ type ServerDependencies struct {
|
||||
// single net/http listener.
|
||||
type Server struct {
|
||||
cfg config.AuthenticatedGRPCConfig
|
||||
service gatewayv1.EdgeGatewayServer
|
||||
service edgev1.GatewayServer
|
||||
logger *zap.Logger
|
||||
pushHub *push.Hub
|
||||
metrics *telemetry.Runtime
|
||||
@@ -169,7 +169,7 @@ func (s *Server) Run(ctx context.Context) error {
|
||||
|
||||
mux := http.NewServeMux()
|
||||
connectHandler := newConnectEdgeAdapter(s.service)
|
||||
path, handler := gatewayv1connect.NewEdgeGatewayHandler(
|
||||
path, handler := edgev1connect.NewGatewayHandler(
|
||||
connectHandler,
|
||||
connect.WithInterceptors(observabilityConnectInterceptor(s.logger, s.metrics)),
|
||||
)
|
||||
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
"galaxy/gateway/internal/app"
|
||||
"galaxy/gateway/internal/config"
|
||||
"galaxy/gateway/internal/session"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
"galaxy/gateway/proto/galaxy/gateway/v1/gatewayv1connect"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
"galaxy/gateway/proto/edge/v1/edgev1connect"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -30,7 +30,7 @@ func TestExecuteCommandRejectsMalformedEnvelope(t *testing.T) {
|
||||
addr := waitForListenAddr(t, server)
|
||||
client := newEdgeClient(t, addr)
|
||||
|
||||
_, err := client.ExecuteCommand(context.Background(), connect.NewRequest(&gatewayv1.ExecuteCommandRequest{}))
|
||||
_, err := client.ExecuteCommand(context.Background(), connect.NewRequest(&edgev1.ExecuteCommandRequest{}))
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, connect.CodeInvalidArgument, connect.CodeOf(err))
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func TestSubscribeEventsRejectsMalformedEnvelope(t *testing.T) {
|
||||
addr := waitForListenAddr(t, server)
|
||||
client := newEdgeClient(t, addr)
|
||||
|
||||
err := subscribeEventsError(t, context.Background(), client, &gatewayv1.SubscribeEventsRequest{})
|
||||
err := subscribeEventsError(t, context.Background(), client, &edgev1.SubscribeEventsRequest{})
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, connect.CodeInvalidArgument, connect.CodeOf(err))
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func TestExecuteCommandRejectsUnsupportedProtocolVersion(t *testing.T) {
|
||||
addr := waitForListenAddr(t, server)
|
||||
client := newEdgeClient(t, addr)
|
||||
|
||||
_, err := client.ExecuteCommand(context.Background(), connect.NewRequest(&gatewayv1.ExecuteCommandRequest{
|
||||
_, err := client.ExecuteCommand(context.Background(), connect.NewRequest(&edgev1.ExecuteCommandRequest{
|
||||
ProtocolVersion: "v2",
|
||||
DeviceSessionId: "device-session-123",
|
||||
MessageType: "fleet.move",
|
||||
@@ -418,7 +418,7 @@ func waitForListenAddr(t *testing.T, server *Server) string {
|
||||
// authenticated edge listener. AllowHTTP forces the client to issue plain
|
||||
// HTTP/2 requests (h2c) instead of attempting TLS, which the gateway's
|
||||
// in-process test bootstrap does not configure.
|
||||
func newEdgeClient(t *testing.T, addr string) gatewayv1connect.EdgeGatewayClient {
|
||||
func newEdgeClient(t *testing.T, addr string) edgev1connect.GatewayClient {
|
||||
t.Helper()
|
||||
|
||||
httpClient := &http.Client{
|
||||
@@ -429,7 +429,7 @@ func newEdgeClient(t *testing.T, addr string) gatewayv1connect.EdgeGatewayClient
|
||||
},
|
||||
},
|
||||
}
|
||||
return gatewayv1connect.NewEdgeGatewayClient(httpClient, "http://"+addr)
|
||||
return edgev1connect.NewGatewayClient(httpClient, "http://"+addr)
|
||||
}
|
||||
|
||||
// connectErrorMessage extracts the *connect.Error message from err. It
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
|
||||
"galaxy/gateway/internal/session"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -30,15 +30,15 @@ func resolvedSessionFromContext(ctx context.Context) (session.Record, bool) {
|
||||
// sessionLookupService resolves the authenticated session from SessionCache
|
||||
// after envelope parsing succeeds and before later auth steps run.
|
||||
type sessionLookupService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
delegate gatewayv1.EdgeGatewayServer
|
||||
delegate edgev1.GatewayServer
|
||||
cache session.Cache
|
||||
}
|
||||
|
||||
// ExecuteCommand resolves the cached session for req and only then forwards it
|
||||
// to the configured delegate with the resolved session attached to ctx.
|
||||
func (s sessionLookupService) ExecuteCommand(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
func (s sessionLookupService) ExecuteCommand(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
record, err := s.lookupSession(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -50,7 +50,7 @@ func (s sessionLookupService) ExecuteCommand(ctx context.Context, req *gatewayv1
|
||||
// SubscribeEvents resolves the cached session for req and only then forwards it
|
||||
// to the configured delegate with the resolved session attached to the stream
|
||||
// context.
|
||||
func (s sessionLookupService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s sessionLookupService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
record, err := s.lookupSession(stream.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -63,7 +63,7 @@ func (s sessionLookupService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequ
|
||||
}
|
||||
|
||||
// newSessionLookupService wraps delegate with the session-cache lookup gate.
|
||||
func newSessionLookupService(delegate gatewayv1.EdgeGatewayServer, cache session.Cache) gatewayv1.EdgeGatewayServer {
|
||||
func newSessionLookupService(delegate edgev1.GatewayServer, cache session.Cache) edgev1.GatewayServer {
|
||||
return sessionLookupService{
|
||||
delegate: delegate,
|
||||
cache: cache,
|
||||
@@ -105,7 +105,7 @@ func cloneSessionRecord(record session.Record) session.Record {
|
||||
type resolvedSessionContextKey struct{}
|
||||
|
||||
type resolvedSessionContextStream struct {
|
||||
grpc.ServerStreamingServer[gatewayv1.GatewayEvent]
|
||||
grpc.ServerStreamingServer[edgev1.GatewayEvent]
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
@@ -126,4 +126,4 @@ func (unavailableSessionCache) Lookup(context.Context, string) (session.Record,
|
||||
func (unavailableSessionCache) MarkRevoked(string) {}
|
||||
func (unavailableSessionCache) MarkAllRevokedForUser(string) {}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = sessionLookupService{}
|
||||
var _ edgev1.GatewayServer = sessionLookupService{}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"galaxy/gateway/internal/session"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
func TestExecuteCommandRejectsUnknownSession(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{
|
||||
@@ -40,7 +40,7 @@ func TestExecuteCommandRejectsUnknownSession(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsUnknownSession(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{
|
||||
@@ -63,7 +63,7 @@ func TestSubscribeEventsRejectsUnknownSession(t *testing.T) {
|
||||
func TestExecuteCommandRejectsRevokedSession(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newRevokedSessionRecord(), nil }},
|
||||
@@ -82,7 +82,7 @@ func TestExecuteCommandRejectsRevokedSession(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsRevokedSession(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newRevokedSessionRecord(), nil }},
|
||||
@@ -101,7 +101,7 @@ func TestSubscribeEventsRejectsRevokedSession(t *testing.T) {
|
||||
func TestExecuteCommandRejectsSessionCacheUnavailable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{
|
||||
@@ -124,7 +124,7 @@ func TestExecuteCommandRejectsSessionCacheUnavailable(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsSessionCacheUnavailable(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{
|
||||
@@ -147,12 +147,12 @@ func TestSubscribeEventsRejectsSessionCacheUnavailable(t *testing.T) {
|
||||
func TestExecuteCommandAttachesResolvedSession(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
delegate := &recordingGatewayService{
|
||||
executeCommandFunc: func(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
record, ok := resolvedSessionFromContext(ctx)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, newActiveSessionRecord(), record)
|
||||
return &gatewayv1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
return &edgev1.ExecuteCommandResponse{RequestId: req.GetRequestId()}, nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -173,8 +173,8 @@ func TestExecuteCommandAttachesResolvedSession(t *testing.T) {
|
||||
func TestSubscribeEventsAttachesResolvedSession(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
subscribeEventsFunc: func(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
delegate := &recordingGatewayService{
|
||||
subscribeEventsFunc: func(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
record, ok := resolvedSessionFromContext(stream.Context())
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, newActiveSessionRecord(), record)
|
||||
@@ -204,8 +204,8 @@ func TestSubscribeEventsAttachesResolvedSession(t *testing.T) {
|
||||
func TestSubscribeEventsAttachesAuthenticatedStreamBinding(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{
|
||||
subscribeEventsFunc: func(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
delegate := &recordingGatewayService{
|
||||
subscribeEventsFunc: func(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
binding, ok := authenticatedStreamBindingFromContext(stream.Context())
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, authenticatedStreamBinding{
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
|
||||
"galaxy/gateway/authn"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
@@ -15,14 +15,14 @@ import (
|
||||
// signatureVerifyingService applies client-signature verification after
|
||||
// payload integrity checks and before later auth or routing steps run.
|
||||
type signatureVerifyingService struct {
|
||||
gatewayv1.UnimplementedEdgeGatewayServer
|
||||
edgev1.UnimplementedGatewayServer
|
||||
|
||||
delegate gatewayv1.EdgeGatewayServer
|
||||
delegate edgev1.GatewayServer
|
||||
}
|
||||
|
||||
// ExecuteCommand verifies req client signature before delegating to the
|
||||
// configured service implementation.
|
||||
func (s signatureVerifyingService) ExecuteCommand(ctx context.Context, req *gatewayv1.ExecuteCommandRequest) (*gatewayv1.ExecuteCommandResponse, error) {
|
||||
func (s signatureVerifyingService) ExecuteCommand(ctx context.Context, req *edgev1.ExecuteCommandRequest) (*edgev1.ExecuteCommandResponse, error) {
|
||||
if err := verifyRequestSignature(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -32,7 +32,7 @@ func (s signatureVerifyingService) ExecuteCommand(ctx context.Context, req *gate
|
||||
|
||||
// SubscribeEvents verifies req client signature before delegating to the
|
||||
// configured service implementation.
|
||||
func (s signatureVerifyingService) SubscribeEvents(req *gatewayv1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[gatewayv1.GatewayEvent]) error {
|
||||
func (s signatureVerifyingService) SubscribeEvents(req *edgev1.SubscribeEventsRequest, stream grpc.ServerStreamingServer[edgev1.GatewayEvent]) error {
|
||||
if err := verifyRequestSignature(stream.Context()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -42,7 +42,7 @@ func (s signatureVerifyingService) SubscribeEvents(req *gatewayv1.SubscribeEvent
|
||||
|
||||
// newSignatureVerifyingService wraps delegate with the client-signature
|
||||
// verification gate.
|
||||
func newSignatureVerifyingService(delegate gatewayv1.EdgeGatewayServer) gatewayv1.EdgeGatewayServer {
|
||||
func newSignatureVerifyingService(delegate edgev1.GatewayServer) edgev1.GatewayServer {
|
||||
return signatureVerifyingService{delegate: delegate}
|
||||
}
|
||||
|
||||
@@ -77,4 +77,4 @@ func verifyRequestSignature(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
var _ gatewayv1.EdgeGatewayServer = signatureVerifyingService{}
|
||||
var _ edgev1.GatewayServer = signatureVerifyingService{}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
func TestExecuteCommandRejectsInvalidSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -37,7 +37,7 @@ func TestExecuteCommandRejectsInvalidSignature(t *testing.T) {
|
||||
func TestExecuteCommandRejectsWrongKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{
|
||||
@@ -62,7 +62,7 @@ func TestExecuteCommandRejectsWrongKey(t *testing.T) {
|
||||
func TestExecuteCommandRejectsInvalidCachedPublicKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{
|
||||
@@ -87,7 +87,7 @@ func TestExecuteCommandRejectsInvalidCachedPublicKey(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsInvalidSignature(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{lookupFunc: func(context.Context, string) (session.Record, error) { return newActiveSessionRecord(), nil }},
|
||||
@@ -110,7 +110,7 @@ func TestSubscribeEventsRejectsInvalidSignature(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsWrongKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{
|
||||
@@ -135,7 +135,7 @@ func TestSubscribeEventsRejectsWrongKey(t *testing.T) {
|
||||
func TestSubscribeEventsRejectsInvalidCachedPublicKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
delegate := &recordingEdgeGatewayService{}
|
||||
delegate := &recordingGatewayService{}
|
||||
server, runGateway := newTestGateway(t, ServerDependencies{
|
||||
Service: delegate,
|
||||
SessionCache: staticSessionCache{
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
"galaxy/gateway/authn"
|
||||
"galaxy/gateway/internal/downstream"
|
||||
"galaxy/gateway/internal/session"
|
||||
gatewayv1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
"galaxy/gateway/proto/galaxy/gateway/v1/gatewayv1connect"
|
||||
edgev1 "galaxy/gateway/proto/edge/v1"
|
||||
"galaxy/gateway/proto/edge/v1/edgev1connect"
|
||||
|
||||
gatewayfbs "galaxy/schema/fbs/gateway"
|
||||
|
||||
@@ -29,19 +29,19 @@ var (
|
||||
testFreshnessWindow = 5 * time.Minute
|
||||
)
|
||||
|
||||
func newValidExecuteCommandRequest() *gatewayv1.ExecuteCommandRequest {
|
||||
func newValidExecuteCommandRequest() *edgev1.ExecuteCommandRequest {
|
||||
return newValidExecuteCommandRequestWithSessionAndRequestID("device-session-123", "request-123")
|
||||
}
|
||||
|
||||
func newValidExecuteCommandRequestWithSessionAndRequestID(deviceSessionID string, requestID string) *gatewayv1.ExecuteCommandRequest {
|
||||
func newValidExecuteCommandRequestWithSessionAndRequestID(deviceSessionID string, requestID string) *edgev1.ExecuteCommandRequest {
|
||||
return newValidExecuteCommandRequestWithTimestamp(deviceSessionID, requestID, testCurrentTime.UnixMilli())
|
||||
}
|
||||
|
||||
func newValidExecuteCommandRequestWithTimestamp(deviceSessionID string, requestID string, timestampMS int64) *gatewayv1.ExecuteCommandRequest {
|
||||
func newValidExecuteCommandRequestWithTimestamp(deviceSessionID string, requestID string, timestampMS int64) *edgev1.ExecuteCommandRequest {
|
||||
payloadBytes := []byte("payload")
|
||||
payloadHash := sha256.Sum256(payloadBytes)
|
||||
|
||||
req := &gatewayv1.ExecuteCommandRequest{
|
||||
req := &edgev1.ExecuteCommandRequest{
|
||||
ProtocolVersion: supportedProtocolVersion,
|
||||
DeviceSessionId: deviceSessionID,
|
||||
MessageType: "fleet.move",
|
||||
@@ -56,18 +56,18 @@ func newValidExecuteCommandRequestWithTimestamp(deviceSessionID string, requestI
|
||||
return req
|
||||
}
|
||||
|
||||
func newValidSubscribeEventsRequest() *gatewayv1.SubscribeEventsRequest {
|
||||
func newValidSubscribeEventsRequest() *edgev1.SubscribeEventsRequest {
|
||||
return newValidSubscribeEventsRequestWithSessionAndRequestID("device-session-123", "request-123")
|
||||
}
|
||||
|
||||
func newValidSubscribeEventsRequestWithSessionAndRequestID(deviceSessionID string, requestID string) *gatewayv1.SubscribeEventsRequest {
|
||||
func newValidSubscribeEventsRequestWithSessionAndRequestID(deviceSessionID string, requestID string) *edgev1.SubscribeEventsRequest {
|
||||
return newValidSubscribeEventsRequestWithTimestamp(deviceSessionID, requestID, testCurrentTime.UnixMilli())
|
||||
}
|
||||
|
||||
func newValidSubscribeEventsRequestWithTimestamp(deviceSessionID string, requestID string, timestampMS int64) *gatewayv1.SubscribeEventsRequest {
|
||||
func newValidSubscribeEventsRequestWithTimestamp(deviceSessionID string, requestID string, timestampMS int64) *edgev1.SubscribeEventsRequest {
|
||||
payloadHash := sha256.Sum256(nil)
|
||||
|
||||
req := &gatewayv1.SubscribeEventsRequest{
|
||||
req := &edgev1.SubscribeEventsRequest{
|
||||
ProtocolVersion: supportedProtocolVersion,
|
||||
DeviceSessionId: deviceSessionID,
|
||||
MessageType: "gateway.subscribe",
|
||||
@@ -172,7 +172,7 @@ func (c fixedClock) Now() time.Time {
|
||||
func recvBootstrapEvent(t interface {
|
||||
require.TestingT
|
||||
Helper()
|
||||
}, stream *connect.ServerStreamForClient[gatewayv1.GatewayEvent]) *gatewayv1.GatewayEvent {
|
||||
}, stream *connect.ServerStreamForClient[edgev1.GatewayEvent]) *edgev1.GatewayEvent {
|
||||
t.Helper()
|
||||
|
||||
if !stream.Receive() {
|
||||
@@ -189,7 +189,7 @@ func recvBootstrapEvent(t interface {
|
||||
func subscribeEventsError(t interface {
|
||||
require.TestingT
|
||||
Helper()
|
||||
}, ctx context.Context, client gatewayv1connect.EdgeGatewayClient, req *gatewayv1.SubscribeEventsRequest) error {
|
||||
}, ctx context.Context, client edgev1connect.GatewayClient, req *edgev1.SubscribeEventsRequest) error {
|
||||
t.Helper()
|
||||
|
||||
stream, err := client.SubscribeEvents(ctx, connect.NewRequest(req))
|
||||
@@ -208,7 +208,7 @@ func subscribeEventsError(t interface {
|
||||
func assertServerTimeBootstrapEvent(t interface {
|
||||
require.TestingT
|
||||
Helper()
|
||||
}, event *gatewayv1.GatewayEvent, publicKey ed25519.PublicKey, wantRequestID string, wantTraceID string, wantTimestampMS int64) {
|
||||
}, event *edgev1.GatewayEvent, publicKey ed25519.PublicKey, wantRequestID string, wantTraceID string, wantTimestampMS int64) {
|
||||
t.Helper()
|
||||
|
||||
require.NotNil(t, event)
|
||||
@@ -244,7 +244,7 @@ func (s staticReplayStore) Reserve(ctx context.Context, deviceSessionID string,
|
||||
}
|
||||
|
||||
type executeCommandAdapterRouter struct {
|
||||
service gatewayv1.EdgeGatewayServer
|
||||
service edgev1.GatewayServer
|
||||
}
|
||||
|
||||
func (r executeCommandAdapterRouter) Route(string) (downstream.Client, error) {
|
||||
@@ -252,11 +252,11 @@ func (r executeCommandAdapterRouter) Route(string) (downstream.Client, error) {
|
||||
}
|
||||
|
||||
type executeCommandAdapterClient struct {
|
||||
service gatewayv1.EdgeGatewayServer
|
||||
service edgev1.GatewayServer
|
||||
}
|
||||
|
||||
func (c executeCommandAdapterClient) ExecuteCommand(ctx context.Context, command downstream.AuthenticatedCommand) (downstream.UnaryResult, error) {
|
||||
response, err := c.service.ExecuteCommand(ctx, &gatewayv1.ExecuteCommandRequest{
|
||||
response, err := c.service.ExecuteCommand(ctx, &edgev1.ExecuteCommandRequest{
|
||||
ProtocolVersion: command.ProtocolVersion,
|
||||
DeviceSessionId: command.DeviceSessionID,
|
||||
MessageType: command.MessageType,
|
||||
|
||||
@@ -6,6 +6,14 @@ info:
|
||||
This specification documents the implemented `galaxy/gateway` v1 public
|
||||
REST surface.
|
||||
|
||||
At the edge this surface is served same-origin under one host: the edge
|
||||
Caddy routes `/api/*` and `/healthz` to the public REST listener, so those
|
||||
paths are reached at `https://<host>/healthz` and
|
||||
`https://<host>/api/v1/public/auth/*`. The authenticated Connect/gRPC-Web
|
||||
surface lives behind the same host at `/rpc/*` and is not part of this
|
||||
REST contract. `/readyz` is an in-process readiness probe served on the
|
||||
listener itself and is not exposed through the edge.
|
||||
|
||||
Implemented endpoints:
|
||||
- `GET /healthz`
|
||||
- `GET /readyz`
|
||||
|
||||
+48
-48
@@ -2,9 +2,9 @@
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.11
|
||||
// protoc (unknown)
|
||||
// source: galaxy/gateway/v1/edge_gateway.proto
|
||||
// source: edge/v1/edge_gateway.proto
|
||||
|
||||
package gatewayv1
|
||||
package edgev1
|
||||
|
||||
import (
|
||||
_ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate"
|
||||
@@ -42,7 +42,7 @@ type ExecuteCommandRequest struct {
|
||||
|
||||
func (x *ExecuteCommandRequest) Reset() {
|
||||
*x = ExecuteCommandRequest{}
|
||||
mi := &file_galaxy_gateway_v1_edge_gateway_proto_msgTypes[0]
|
||||
mi := &file_edge_v1_edge_gateway_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -54,7 +54,7 @@ func (x *ExecuteCommandRequest) String() string {
|
||||
func (*ExecuteCommandRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ExecuteCommandRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_galaxy_gateway_v1_edge_gateway_proto_msgTypes[0]
|
||||
mi := &file_edge_v1_edge_gateway_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -67,7 +67,7 @@ func (x *ExecuteCommandRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecuteCommandRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ExecuteCommandRequest) Descriptor() ([]byte, []int) {
|
||||
return file_galaxy_gateway_v1_edge_gateway_proto_rawDescGZIP(), []int{0}
|
||||
return file_edge_v1_edge_gateway_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ExecuteCommandRequest) GetProtocolVersion() string {
|
||||
@@ -148,7 +148,7 @@ type ExecuteCommandResponse struct {
|
||||
|
||||
func (x *ExecuteCommandResponse) Reset() {
|
||||
*x = ExecuteCommandResponse{}
|
||||
mi := &file_galaxy_gateway_v1_edge_gateway_proto_msgTypes[1]
|
||||
mi := &file_edge_v1_edge_gateway_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -160,7 +160,7 @@ func (x *ExecuteCommandResponse) String() string {
|
||||
func (*ExecuteCommandResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ExecuteCommandResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_galaxy_gateway_v1_edge_gateway_proto_msgTypes[1]
|
||||
mi := &file_edge_v1_edge_gateway_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -173,7 +173,7 @@ func (x *ExecuteCommandResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use ExecuteCommandResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ExecuteCommandResponse) Descriptor() ([]byte, []int) {
|
||||
return file_galaxy_gateway_v1_edge_gateway_proto_rawDescGZIP(), []int{1}
|
||||
return file_edge_v1_edge_gateway_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ExecuteCommandResponse) GetProtocolVersion() string {
|
||||
@@ -246,7 +246,7 @@ type SubscribeEventsRequest struct {
|
||||
|
||||
func (x *SubscribeEventsRequest) Reset() {
|
||||
*x = SubscribeEventsRequest{}
|
||||
mi := &file_galaxy_gateway_v1_edge_gateway_proto_msgTypes[2]
|
||||
mi := &file_edge_v1_edge_gateway_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -258,7 +258,7 @@ func (x *SubscribeEventsRequest) String() string {
|
||||
func (*SubscribeEventsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SubscribeEventsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_galaxy_gateway_v1_edge_gateway_proto_msgTypes[2]
|
||||
mi := &file_edge_v1_edge_gateway_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -271,7 +271,7 @@ func (x *SubscribeEventsRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use SubscribeEventsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SubscribeEventsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_galaxy_gateway_v1_edge_gateway_proto_rawDescGZIP(), []int{2}
|
||||
return file_edge_v1_edge_gateway_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *SubscribeEventsRequest) GetProtocolVersion() string {
|
||||
@@ -353,7 +353,7 @@ type GatewayEvent struct {
|
||||
|
||||
func (x *GatewayEvent) Reset() {
|
||||
*x = GatewayEvent{}
|
||||
mi := &file_galaxy_gateway_v1_edge_gateway_proto_msgTypes[3]
|
||||
mi := &file_edge_v1_edge_gateway_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -365,7 +365,7 @@ func (x *GatewayEvent) String() string {
|
||||
func (*GatewayEvent) ProtoMessage() {}
|
||||
|
||||
func (x *GatewayEvent) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_galaxy_gateway_v1_edge_gateway_proto_msgTypes[3]
|
||||
mi := &file_edge_v1_edge_gateway_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -378,7 +378,7 @@ func (x *GatewayEvent) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GatewayEvent.ProtoReflect.Descriptor instead.
|
||||
func (*GatewayEvent) Descriptor() ([]byte, []int) {
|
||||
return file_galaxy_gateway_v1_edge_gateway_proto_rawDescGZIP(), []int{3}
|
||||
return file_edge_v1_edge_gateway_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *GatewayEvent) GetEventType() string {
|
||||
@@ -437,11 +437,11 @@ func (x *GatewayEvent) GetTraceId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_galaxy_gateway_v1_edge_gateway_proto protoreflect.FileDescriptor
|
||||
var File_edge_v1_edge_gateway_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_galaxy_gateway_v1_edge_gateway_proto_rawDesc = "" +
|
||||
const file_edge_v1_edge_gateway_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"$galaxy/gateway/v1/edge_gateway.proto\x12\x11galaxy.gateway.v1\x1a\x1bbuf/validate/validate.proto\"\x9c\x03\n" +
|
||||
"\x1aedge/v1/edge_gateway.proto\x12\aedge.v1\x1a\x1bbuf/validate/validate.proto\"\x9c\x03\n" +
|
||||
"\x15ExecuteCommandRequest\x122\n" +
|
||||
"\x10protocol_version\x18\x01 \x01(\tB\a\xbaH\x04r\x02\x10\x01R\x0fprotocolVersion\x123\n" +
|
||||
"\x11device_session_id\x18\x02 \x01(\tB\a\xbaH\x04r\x02\x10\x01R\x0fdeviceSessionId\x12*\n" +
|
||||
@@ -484,35 +484,35 @@ const file_galaxy_gateway_v1_edge_gateway_proto_rawDesc = "" +
|
||||
"\tsignature\x18\x06 \x01(\fR\tsignature\x12\x1d\n" +
|
||||
"\n" +
|
||||
"request_id\x18\a \x01(\tR\trequestId\x12\x19\n" +
|
||||
"\btrace_id\x18\b \x01(\tR\atraceId2\xd5\x01\n" +
|
||||
"\vEdgeGateway\x12e\n" +
|
||||
"\x0eExecuteCommand\x12(.galaxy.gateway.v1.ExecuteCommandRequest\x1a).galaxy.gateway.v1.ExecuteCommandResponse\x12_\n" +
|
||||
"\x0fSubscribeEvents\x12).galaxy.gateway.v1.SubscribeEventsRequest\x1a\x1f.galaxy.gateway.v1.GatewayEvent0\x01B2Z0galaxy/gateway/proto/galaxy/gateway/v1;gatewayv1b\x06proto3"
|
||||
"\btrace_id\x18\b \x01(\tR\atraceId2\xa9\x01\n" +
|
||||
"\aGateway\x12Q\n" +
|
||||
"\x0eExecuteCommand\x12\x1e.edge.v1.ExecuteCommandRequest\x1a\x1f.edge.v1.ExecuteCommandResponse\x12K\n" +
|
||||
"\x0fSubscribeEvents\x12\x1f.edge.v1.SubscribeEventsRequest\x1a\x15.edge.v1.GatewayEvent0\x01B%Z#galaxy/gateway/proto/edge/v1;edgev1b\x06proto3"
|
||||
|
||||
var (
|
||||
file_galaxy_gateway_v1_edge_gateway_proto_rawDescOnce sync.Once
|
||||
file_galaxy_gateway_v1_edge_gateway_proto_rawDescData []byte
|
||||
file_edge_v1_edge_gateway_proto_rawDescOnce sync.Once
|
||||
file_edge_v1_edge_gateway_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_galaxy_gateway_v1_edge_gateway_proto_rawDescGZIP() []byte {
|
||||
file_galaxy_gateway_v1_edge_gateway_proto_rawDescOnce.Do(func() {
|
||||
file_galaxy_gateway_v1_edge_gateway_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_galaxy_gateway_v1_edge_gateway_proto_rawDesc), len(file_galaxy_gateway_v1_edge_gateway_proto_rawDesc)))
|
||||
func file_edge_v1_edge_gateway_proto_rawDescGZIP() []byte {
|
||||
file_edge_v1_edge_gateway_proto_rawDescOnce.Do(func() {
|
||||
file_edge_v1_edge_gateway_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_edge_v1_edge_gateway_proto_rawDesc), len(file_edge_v1_edge_gateway_proto_rawDesc)))
|
||||
})
|
||||
return file_galaxy_gateway_v1_edge_gateway_proto_rawDescData
|
||||
return file_edge_v1_edge_gateway_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_galaxy_gateway_v1_edge_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_galaxy_gateway_v1_edge_gateway_proto_goTypes = []any{
|
||||
(*ExecuteCommandRequest)(nil), // 0: galaxy.gateway.v1.ExecuteCommandRequest
|
||||
(*ExecuteCommandResponse)(nil), // 1: galaxy.gateway.v1.ExecuteCommandResponse
|
||||
(*SubscribeEventsRequest)(nil), // 2: galaxy.gateway.v1.SubscribeEventsRequest
|
||||
(*GatewayEvent)(nil), // 3: galaxy.gateway.v1.GatewayEvent
|
||||
var file_edge_v1_edge_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_edge_v1_edge_gateway_proto_goTypes = []any{
|
||||
(*ExecuteCommandRequest)(nil), // 0: edge.v1.ExecuteCommandRequest
|
||||
(*ExecuteCommandResponse)(nil), // 1: edge.v1.ExecuteCommandResponse
|
||||
(*SubscribeEventsRequest)(nil), // 2: edge.v1.SubscribeEventsRequest
|
||||
(*GatewayEvent)(nil), // 3: edge.v1.GatewayEvent
|
||||
}
|
||||
var file_galaxy_gateway_v1_edge_gateway_proto_depIdxs = []int32{
|
||||
0, // 0: galaxy.gateway.v1.EdgeGateway.ExecuteCommand:input_type -> galaxy.gateway.v1.ExecuteCommandRequest
|
||||
2, // 1: galaxy.gateway.v1.EdgeGateway.SubscribeEvents:input_type -> galaxy.gateway.v1.SubscribeEventsRequest
|
||||
1, // 2: galaxy.gateway.v1.EdgeGateway.ExecuteCommand:output_type -> galaxy.gateway.v1.ExecuteCommandResponse
|
||||
3, // 3: galaxy.gateway.v1.EdgeGateway.SubscribeEvents:output_type -> galaxy.gateway.v1.GatewayEvent
|
||||
var file_edge_v1_edge_gateway_proto_depIdxs = []int32{
|
||||
0, // 0: edge.v1.Gateway.ExecuteCommand:input_type -> edge.v1.ExecuteCommandRequest
|
||||
2, // 1: edge.v1.Gateway.SubscribeEvents:input_type -> edge.v1.SubscribeEventsRequest
|
||||
1, // 2: edge.v1.Gateway.ExecuteCommand:output_type -> edge.v1.ExecuteCommandResponse
|
||||
3, // 3: edge.v1.Gateway.SubscribeEvents:output_type -> edge.v1.GatewayEvent
|
||||
2, // [2:4] is the sub-list for method output_type
|
||||
0, // [0:2] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
@@ -520,26 +520,26 @@ var file_galaxy_gateway_v1_edge_gateway_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_galaxy_gateway_v1_edge_gateway_proto_init() }
|
||||
func file_galaxy_gateway_v1_edge_gateway_proto_init() {
|
||||
if File_galaxy_gateway_v1_edge_gateway_proto != nil {
|
||||
func init() { file_edge_v1_edge_gateway_proto_init() }
|
||||
func file_edge_v1_edge_gateway_proto_init() {
|
||||
if File_edge_v1_edge_gateway_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_galaxy_gateway_v1_edge_gateway_proto_rawDesc), len(file_galaxy_gateway_v1_edge_gateway_proto_rawDesc)),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_edge_v1_edge_gateway_proto_rawDesc), len(file_edge_v1_edge_gateway_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_galaxy_gateway_v1_edge_gateway_proto_goTypes,
|
||||
DependencyIndexes: file_galaxy_gateway_v1_edge_gateway_proto_depIdxs,
|
||||
MessageInfos: file_galaxy_gateway_v1_edge_gateway_proto_msgTypes,
|
||||
GoTypes: file_edge_v1_edge_gateway_proto_goTypes,
|
||||
DependencyIndexes: file_edge_v1_edge_gateway_proto_depIdxs,
|
||||
MessageInfos: file_edge_v1_edge_gateway_proto_msgTypes,
|
||||
}.Build()
|
||||
File_galaxy_gateway_v1_edge_gateway_proto = out.File
|
||||
file_galaxy_gateway_v1_edge_gateway_proto_goTypes = nil
|
||||
file_galaxy_gateway_v1_edge_gateway_proto_depIdxs = nil
|
||||
File_edge_v1_edge_gateway_proto = out.File
|
||||
file_edge_v1_edge_gateway_proto_goTypes = nil
|
||||
file_edge_v1_edge_gateway_proto_depIdxs = nil
|
||||
}
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package galaxy.gateway.v1;
|
||||
package edge.v1;
|
||||
|
||||
option go_package = "galaxy/gateway/proto/galaxy/gateway/v1;gatewayv1";
|
||||
option go_package = "galaxy/gateway/proto/edge/v1;edgev1";
|
||||
|
||||
import "buf/validate/validate.proto";
|
||||
|
||||
service EdgeGateway {
|
||||
service Gateway {
|
||||
rpc ExecuteCommand(ExecuteCommandRequest) returns (ExecuteCommandResponse);
|
||||
rpc SubscribeEvents(SubscribeEventsRequest) returns (stream GatewayEvent);
|
||||
}
|
||||
+45
-45
@@ -2,9 +2,9 @@
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.6.1
|
||||
// - protoc (unknown)
|
||||
// source: galaxy/gateway/v1/edge_gateway.proto
|
||||
// source: edge/v1/edge_gateway.proto
|
||||
|
||||
package gatewayv1
|
||||
package edgev1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
@@ -19,39 +19,39 @@ import (
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
EdgeGateway_ExecuteCommand_FullMethodName = "/galaxy.gateway.v1.EdgeGateway/ExecuteCommand"
|
||||
EdgeGateway_SubscribeEvents_FullMethodName = "/galaxy.gateway.v1.EdgeGateway/SubscribeEvents"
|
||||
Gateway_ExecuteCommand_FullMethodName = "/edge.v1.Gateway/ExecuteCommand"
|
||||
Gateway_SubscribeEvents_FullMethodName = "/edge.v1.Gateway/SubscribeEvents"
|
||||
)
|
||||
|
||||
// EdgeGatewayClient is the client API for EdgeGateway service.
|
||||
// GatewayClient is the client API for Gateway service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type EdgeGatewayClient interface {
|
||||
type GatewayClient interface {
|
||||
ExecuteCommand(ctx context.Context, in *ExecuteCommandRequest, opts ...grpc.CallOption) (*ExecuteCommandResponse, error)
|
||||
SubscribeEvents(ctx context.Context, in *SubscribeEventsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[GatewayEvent], error)
|
||||
}
|
||||
|
||||
type edgeGatewayClient struct {
|
||||
type gatewayClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewEdgeGatewayClient(cc grpc.ClientConnInterface) EdgeGatewayClient {
|
||||
return &edgeGatewayClient{cc}
|
||||
func NewGatewayClient(cc grpc.ClientConnInterface) GatewayClient {
|
||||
return &gatewayClient{cc}
|
||||
}
|
||||
|
||||
func (c *edgeGatewayClient) ExecuteCommand(ctx context.Context, in *ExecuteCommandRequest, opts ...grpc.CallOption) (*ExecuteCommandResponse, error) {
|
||||
func (c *gatewayClient) ExecuteCommand(ctx context.Context, in *ExecuteCommandRequest, opts ...grpc.CallOption) (*ExecuteCommandResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ExecuteCommandResponse)
|
||||
err := c.cc.Invoke(ctx, EdgeGateway_ExecuteCommand_FullMethodName, in, out, cOpts...)
|
||||
err := c.cc.Invoke(ctx, Gateway_ExecuteCommand_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *edgeGatewayClient) SubscribeEvents(ctx context.Context, in *SubscribeEventsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[GatewayEvent], error) {
|
||||
func (c *gatewayClient) SubscribeEvents(ctx context.Context, in *SubscribeEventsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[GatewayEvent], error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &EdgeGateway_ServiceDesc.Streams[0], EdgeGateway_SubscribeEvents_FullMethodName, cOpts...)
|
||||
stream, err := c.cc.NewStream(ctx, &Gateway_ServiceDesc.Streams[0], Gateway_SubscribeEvents_FullMethodName, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -66,98 +66,98 @@ func (c *edgeGatewayClient) SubscribeEvents(ctx context.Context, in *SubscribeEv
|
||||
}
|
||||
|
||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||
type EdgeGateway_SubscribeEventsClient = grpc.ServerStreamingClient[GatewayEvent]
|
||||
type Gateway_SubscribeEventsClient = grpc.ServerStreamingClient[GatewayEvent]
|
||||
|
||||
// EdgeGatewayServer is the server API for EdgeGateway service.
|
||||
// All implementations must embed UnimplementedEdgeGatewayServer
|
||||
// GatewayServer is the server API for Gateway service.
|
||||
// All implementations must embed UnimplementedGatewayServer
|
||||
// for forward compatibility.
|
||||
type EdgeGatewayServer interface {
|
||||
type GatewayServer interface {
|
||||
ExecuteCommand(context.Context, *ExecuteCommandRequest) (*ExecuteCommandResponse, error)
|
||||
SubscribeEvents(*SubscribeEventsRequest, grpc.ServerStreamingServer[GatewayEvent]) error
|
||||
mustEmbedUnimplementedEdgeGatewayServer()
|
||||
mustEmbedUnimplementedGatewayServer()
|
||||
}
|
||||
|
||||
// UnimplementedEdgeGatewayServer must be embedded to have
|
||||
// UnimplementedGatewayServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedEdgeGatewayServer struct{}
|
||||
type UnimplementedGatewayServer struct{}
|
||||
|
||||
func (UnimplementedEdgeGatewayServer) ExecuteCommand(context.Context, *ExecuteCommandRequest) (*ExecuteCommandResponse, error) {
|
||||
func (UnimplementedGatewayServer) ExecuteCommand(context.Context, *ExecuteCommandRequest) (*ExecuteCommandResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ExecuteCommand not implemented")
|
||||
}
|
||||
func (UnimplementedEdgeGatewayServer) SubscribeEvents(*SubscribeEventsRequest, grpc.ServerStreamingServer[GatewayEvent]) error {
|
||||
func (UnimplementedGatewayServer) SubscribeEvents(*SubscribeEventsRequest, grpc.ServerStreamingServer[GatewayEvent]) error {
|
||||
return status.Error(codes.Unimplemented, "method SubscribeEvents not implemented")
|
||||
}
|
||||
func (UnimplementedEdgeGatewayServer) mustEmbedUnimplementedEdgeGatewayServer() {}
|
||||
func (UnimplementedEdgeGatewayServer) testEmbeddedByValue() {}
|
||||
func (UnimplementedGatewayServer) mustEmbedUnimplementedGatewayServer() {}
|
||||
func (UnimplementedGatewayServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeEdgeGatewayServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to EdgeGatewayServer will
|
||||
// UnsafeGatewayServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to GatewayServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeEdgeGatewayServer interface {
|
||||
mustEmbedUnimplementedEdgeGatewayServer()
|
||||
type UnsafeGatewayServer interface {
|
||||
mustEmbedUnimplementedGatewayServer()
|
||||
}
|
||||
|
||||
func RegisterEdgeGatewayServer(s grpc.ServiceRegistrar, srv EdgeGatewayServer) {
|
||||
// If the following call panics, it indicates UnimplementedEdgeGatewayServer was
|
||||
func RegisterGatewayServer(s grpc.ServiceRegistrar, srv GatewayServer) {
|
||||
// If the following call panics, it indicates UnimplementedGatewayServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&EdgeGateway_ServiceDesc, srv)
|
||||
s.RegisterService(&Gateway_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _EdgeGateway_ExecuteCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Gateway_ExecuteCommand_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ExecuteCommandRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(EdgeGatewayServer).ExecuteCommand(ctx, in)
|
||||
return srv.(GatewayServer).ExecuteCommand(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: EdgeGateway_ExecuteCommand_FullMethodName,
|
||||
FullMethod: Gateway_ExecuteCommand_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(EdgeGatewayServer).ExecuteCommand(ctx, req.(*ExecuteCommandRequest))
|
||||
return srv.(GatewayServer).ExecuteCommand(ctx, req.(*ExecuteCommandRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _EdgeGateway_SubscribeEvents_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
func _Gateway_SubscribeEvents_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(SubscribeEventsRequest)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(EdgeGatewayServer).SubscribeEvents(m, &grpc.GenericServerStream[SubscribeEventsRequest, GatewayEvent]{ServerStream: stream})
|
||||
return srv.(GatewayServer).SubscribeEvents(m, &grpc.GenericServerStream[SubscribeEventsRequest, GatewayEvent]{ServerStream: stream})
|
||||
}
|
||||
|
||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
||||
type EdgeGateway_SubscribeEventsServer = grpc.ServerStreamingServer[GatewayEvent]
|
||||
type Gateway_SubscribeEventsServer = grpc.ServerStreamingServer[GatewayEvent]
|
||||
|
||||
// EdgeGateway_ServiceDesc is the grpc.ServiceDesc for EdgeGateway service.
|
||||
// Gateway_ServiceDesc is the grpc.ServiceDesc for Gateway service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var EdgeGateway_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "galaxy.gateway.v1.EdgeGateway",
|
||||
HandlerType: (*EdgeGatewayServer)(nil),
|
||||
var Gateway_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "edge.v1.Gateway",
|
||||
HandlerType: (*GatewayServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ExecuteCommand",
|
||||
Handler: _EdgeGateway_ExecuteCommand_Handler,
|
||||
Handler: _Gateway_ExecuteCommand_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "SubscribeEvents",
|
||||
Handler: _EdgeGateway_SubscribeEvents_Handler,
|
||||
Handler: _Gateway_SubscribeEvents_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "galaxy/gateway/v1/edge_gateway.proto",
|
||||
Metadata: "edge/v1/edge_gateway.proto",
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: edge/v1/edge_gateway.proto
|
||||
|
||||
package edgev1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "galaxy/gateway/proto/edge/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// GatewayName is the fully-qualified name of the Gateway service.
|
||||
GatewayName = "edge.v1.Gateway"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// GatewayExecuteCommandProcedure is the fully-qualified name of the Gateway's ExecuteCommand RPC.
|
||||
GatewayExecuteCommandProcedure = "/edge.v1.Gateway/ExecuteCommand"
|
||||
// GatewaySubscribeEventsProcedure is the fully-qualified name of the Gateway's SubscribeEvents RPC.
|
||||
GatewaySubscribeEventsProcedure = "/edge.v1.Gateway/SubscribeEvents"
|
||||
)
|
||||
|
||||
// GatewayClient is a client for the edge.v1.Gateway service.
|
||||
type GatewayClient interface {
|
||||
ExecuteCommand(context.Context, *connect.Request[v1.ExecuteCommandRequest]) (*connect.Response[v1.ExecuteCommandResponse], error)
|
||||
SubscribeEvents(context.Context, *connect.Request[v1.SubscribeEventsRequest]) (*connect.ServerStreamForClient[v1.GatewayEvent], error)
|
||||
}
|
||||
|
||||
// NewGatewayClient constructs a client for the edge.v1.Gateway service. By default, it uses the
|
||||
// Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
|
||||
// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
|
||||
// connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewGatewayClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) GatewayClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
gatewayMethods := v1.File_edge_v1_edge_gateway_proto.Services().ByName("Gateway").Methods()
|
||||
return &gatewayClient{
|
||||
executeCommand: connect.NewClient[v1.ExecuteCommandRequest, v1.ExecuteCommandResponse](
|
||||
httpClient,
|
||||
baseURL+GatewayExecuteCommandProcedure,
|
||||
connect.WithSchema(gatewayMethods.ByName("ExecuteCommand")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
subscribeEvents: connect.NewClient[v1.SubscribeEventsRequest, v1.GatewayEvent](
|
||||
httpClient,
|
||||
baseURL+GatewaySubscribeEventsProcedure,
|
||||
connect.WithSchema(gatewayMethods.ByName("SubscribeEvents")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// gatewayClient implements GatewayClient.
|
||||
type gatewayClient struct {
|
||||
executeCommand *connect.Client[v1.ExecuteCommandRequest, v1.ExecuteCommandResponse]
|
||||
subscribeEvents *connect.Client[v1.SubscribeEventsRequest, v1.GatewayEvent]
|
||||
}
|
||||
|
||||
// ExecuteCommand calls edge.v1.Gateway.ExecuteCommand.
|
||||
func (c *gatewayClient) ExecuteCommand(ctx context.Context, req *connect.Request[v1.ExecuteCommandRequest]) (*connect.Response[v1.ExecuteCommandResponse], error) {
|
||||
return c.executeCommand.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// SubscribeEvents calls edge.v1.Gateway.SubscribeEvents.
|
||||
func (c *gatewayClient) SubscribeEvents(ctx context.Context, req *connect.Request[v1.SubscribeEventsRequest]) (*connect.ServerStreamForClient[v1.GatewayEvent], error) {
|
||||
return c.subscribeEvents.CallServerStream(ctx, req)
|
||||
}
|
||||
|
||||
// GatewayHandler is an implementation of the edge.v1.Gateway service.
|
||||
type GatewayHandler interface {
|
||||
ExecuteCommand(context.Context, *connect.Request[v1.ExecuteCommandRequest]) (*connect.Response[v1.ExecuteCommandResponse], error)
|
||||
SubscribeEvents(context.Context, *connect.Request[v1.SubscribeEventsRequest], *connect.ServerStream[v1.GatewayEvent]) error
|
||||
}
|
||||
|
||||
// NewGatewayHandler builds an HTTP handler from the service implementation. It returns the path on
|
||||
// which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewGatewayHandler(svc GatewayHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
gatewayMethods := v1.File_edge_v1_edge_gateway_proto.Services().ByName("Gateway").Methods()
|
||||
gatewayExecuteCommandHandler := connect.NewUnaryHandler(
|
||||
GatewayExecuteCommandProcedure,
|
||||
svc.ExecuteCommand,
|
||||
connect.WithSchema(gatewayMethods.ByName("ExecuteCommand")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
gatewaySubscribeEventsHandler := connect.NewServerStreamHandler(
|
||||
GatewaySubscribeEventsProcedure,
|
||||
svc.SubscribeEvents,
|
||||
connect.WithSchema(gatewayMethods.ByName("SubscribeEvents")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/edge.v1.Gateway/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case GatewayExecuteCommandProcedure:
|
||||
gatewayExecuteCommandHandler.ServeHTTP(w, r)
|
||||
case GatewaySubscribeEventsProcedure:
|
||||
gatewaySubscribeEventsHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedGatewayHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedGatewayHandler struct{}
|
||||
|
||||
func (UnimplementedGatewayHandler) ExecuteCommand(context.Context, *connect.Request[v1.ExecuteCommandRequest]) (*connect.Response[v1.ExecuteCommandResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("edge.v1.Gateway.ExecuteCommand is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedGatewayHandler) SubscribeEvents(context.Context, *connect.Request[v1.SubscribeEventsRequest], *connect.ServerStream[v1.GatewayEvent]) error {
|
||||
return connect.NewError(connect.CodeUnimplemented, errors.New("edge.v1.Gateway.SubscribeEvents is not implemented"))
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: galaxy/gateway/v1/edge_gateway.proto
|
||||
|
||||
package gatewayv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "galaxy/gateway/proto/galaxy/gateway/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// EdgeGatewayName is the fully-qualified name of the EdgeGateway service.
|
||||
EdgeGatewayName = "galaxy.gateway.v1.EdgeGateway"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// EdgeGatewayExecuteCommandProcedure is the fully-qualified name of the EdgeGateway's
|
||||
// ExecuteCommand RPC.
|
||||
EdgeGatewayExecuteCommandProcedure = "/galaxy.gateway.v1.EdgeGateway/ExecuteCommand"
|
||||
// EdgeGatewaySubscribeEventsProcedure is the fully-qualified name of the EdgeGateway's
|
||||
// SubscribeEvents RPC.
|
||||
EdgeGatewaySubscribeEventsProcedure = "/galaxy.gateway.v1.EdgeGateway/SubscribeEvents"
|
||||
)
|
||||
|
||||
// EdgeGatewayClient is a client for the galaxy.gateway.v1.EdgeGateway service.
|
||||
type EdgeGatewayClient interface {
|
||||
ExecuteCommand(context.Context, *connect.Request[v1.ExecuteCommandRequest]) (*connect.Response[v1.ExecuteCommandResponse], error)
|
||||
SubscribeEvents(context.Context, *connect.Request[v1.SubscribeEventsRequest]) (*connect.ServerStreamForClient[v1.GatewayEvent], error)
|
||||
}
|
||||
|
||||
// NewEdgeGatewayClient constructs a client for the galaxy.gateway.v1.EdgeGateway service. By
|
||||
// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
|
||||
// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
|
||||
// connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewEdgeGatewayClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) EdgeGatewayClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
edgeGatewayMethods := v1.File_galaxy_gateway_v1_edge_gateway_proto.Services().ByName("EdgeGateway").Methods()
|
||||
return &edgeGatewayClient{
|
||||
executeCommand: connect.NewClient[v1.ExecuteCommandRequest, v1.ExecuteCommandResponse](
|
||||
httpClient,
|
||||
baseURL+EdgeGatewayExecuteCommandProcedure,
|
||||
connect.WithSchema(edgeGatewayMethods.ByName("ExecuteCommand")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
subscribeEvents: connect.NewClient[v1.SubscribeEventsRequest, v1.GatewayEvent](
|
||||
httpClient,
|
||||
baseURL+EdgeGatewaySubscribeEventsProcedure,
|
||||
connect.WithSchema(edgeGatewayMethods.ByName("SubscribeEvents")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// edgeGatewayClient implements EdgeGatewayClient.
|
||||
type edgeGatewayClient struct {
|
||||
executeCommand *connect.Client[v1.ExecuteCommandRequest, v1.ExecuteCommandResponse]
|
||||
subscribeEvents *connect.Client[v1.SubscribeEventsRequest, v1.GatewayEvent]
|
||||
}
|
||||
|
||||
// ExecuteCommand calls galaxy.gateway.v1.EdgeGateway.ExecuteCommand.
|
||||
func (c *edgeGatewayClient) ExecuteCommand(ctx context.Context, req *connect.Request[v1.ExecuteCommandRequest]) (*connect.Response[v1.ExecuteCommandResponse], error) {
|
||||
return c.executeCommand.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// SubscribeEvents calls galaxy.gateway.v1.EdgeGateway.SubscribeEvents.
|
||||
func (c *edgeGatewayClient) SubscribeEvents(ctx context.Context, req *connect.Request[v1.SubscribeEventsRequest]) (*connect.ServerStreamForClient[v1.GatewayEvent], error) {
|
||||
return c.subscribeEvents.CallServerStream(ctx, req)
|
||||
}
|
||||
|
||||
// EdgeGatewayHandler is an implementation of the galaxy.gateway.v1.EdgeGateway service.
|
||||
type EdgeGatewayHandler interface {
|
||||
ExecuteCommand(context.Context, *connect.Request[v1.ExecuteCommandRequest]) (*connect.Response[v1.ExecuteCommandResponse], error)
|
||||
SubscribeEvents(context.Context, *connect.Request[v1.SubscribeEventsRequest], *connect.ServerStream[v1.GatewayEvent]) error
|
||||
}
|
||||
|
||||
// NewEdgeGatewayHandler builds an HTTP handler from the service implementation. It returns the path
|
||||
// on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewEdgeGatewayHandler(svc EdgeGatewayHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
edgeGatewayMethods := v1.File_galaxy_gateway_v1_edge_gateway_proto.Services().ByName("EdgeGateway").Methods()
|
||||
edgeGatewayExecuteCommandHandler := connect.NewUnaryHandler(
|
||||
EdgeGatewayExecuteCommandProcedure,
|
||||
svc.ExecuteCommand,
|
||||
connect.WithSchema(edgeGatewayMethods.ByName("ExecuteCommand")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
edgeGatewaySubscribeEventsHandler := connect.NewServerStreamHandler(
|
||||
EdgeGatewaySubscribeEventsProcedure,
|
||||
svc.SubscribeEvents,
|
||||
connect.WithSchema(edgeGatewayMethods.ByName("SubscribeEvents")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/galaxy.gateway.v1.EdgeGateway/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case EdgeGatewayExecuteCommandProcedure:
|
||||
edgeGatewayExecuteCommandHandler.ServeHTTP(w, r)
|
||||
case EdgeGatewaySubscribeEventsProcedure:
|
||||
edgeGatewaySubscribeEventsHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedEdgeGatewayHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedEdgeGatewayHandler struct{}
|
||||
|
||||
func (UnimplementedEdgeGatewayHandler) ExecuteCommand(context.Context, *connect.Request[v1.ExecuteCommandRequest]) (*connect.Response[v1.ExecuteCommandResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("galaxy.gateway.v1.EdgeGateway.ExecuteCommand is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedEdgeGatewayHandler) SubscribeEvents(context.Context, *connect.Request[v1.SubscribeEventsRequest], *connect.ServerStream[v1.GatewayEvent]) error {
|
||||
return connect.NewError(connect.CodeUnimplemented, errors.New("galaxy.gateway.v1.EdgeGateway.SubscribeEvents is not implemented"))
|
||||
}
|
||||
Reference in New Issue
Block a user