109 lines
3.3 KiB
Go
109 lines
3.3 KiB
Go
// Package downstream defines the verified internal command contract used by the
|
|
// gateway after the authenticated edge pipeline succeeds.
|
|
package downstream
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
)
|
|
|
|
var (
|
|
// ErrRouteNotFound reports that Router does not have an exact-match handler
|
|
// for the supplied authenticated message type.
|
|
ErrRouteNotFound = errors.New("downstream route not found")
|
|
|
|
// ErrDownstreamUnavailable reports that the resolved downstream dependency is
|
|
// temporarily unavailable.
|
|
ErrDownstreamUnavailable = errors.New("downstream service is unavailable")
|
|
)
|
|
|
|
// AuthenticatedCommand is the minimum verified unary command context the
|
|
// gateway may forward to downstream business services.
|
|
type AuthenticatedCommand struct {
|
|
// ProtocolVersion is the authenticated transport protocol version accepted
|
|
// by the gateway.
|
|
ProtocolVersion string
|
|
|
|
// UserID is the authenticated user identity resolved from SessionCache.
|
|
UserID string
|
|
|
|
// DeviceSessionID is the authenticated device session that originated the
|
|
// command.
|
|
DeviceSessionID string
|
|
|
|
// MessageType is the stable exact-match downstream routing key.
|
|
MessageType string
|
|
|
|
// TimestampMS is the client-supplied request timestamp that already passed
|
|
// freshness verification.
|
|
TimestampMS int64
|
|
|
|
// RequestID is the transport correlation and anti-replay identifier.
|
|
RequestID string
|
|
|
|
// TraceID is the optional client-supplied correlation identifier.
|
|
TraceID string
|
|
|
|
// PayloadBytes carries the verified opaque business payload bytes.
|
|
PayloadBytes []byte
|
|
}
|
|
|
|
// UnaryResult is the minimum downstream unary result the gateway needs in
|
|
// order to build a signed authenticated client response.
|
|
type UnaryResult struct {
|
|
// ResultCode is the stable opaque downstream result code returned to the
|
|
// client without business reinterpretation by the gateway.
|
|
ResultCode string
|
|
|
|
// PayloadBytes carries the opaque downstream response payload bytes.
|
|
PayloadBytes []byte
|
|
}
|
|
|
|
// Client executes a verified authenticated unary command against one concrete
|
|
// downstream service or adapter.
|
|
type Client interface {
|
|
// ExecuteCommand executes command and returns the downstream unary result.
|
|
ExecuteCommand(ctx context.Context, command AuthenticatedCommand) (UnaryResult, error)
|
|
}
|
|
|
|
// Router resolves the downstream unary client for one exact authenticated
|
|
// message_type value.
|
|
type Router interface {
|
|
// Route returns the downstream client for messageType. Implementations must
|
|
// wrap ErrRouteNotFound when the route table does not contain messageType.
|
|
Route(messageType string) (Client, error)
|
|
}
|
|
|
|
// StaticRouter resolves exact message_type literals from an immutable route
|
|
// map supplied at construction time.
|
|
type StaticRouter struct {
|
|
routes map[string]Client
|
|
}
|
|
|
|
// NewStaticRouter constructs a StaticRouter with a defensive copy of routes.
|
|
func NewStaticRouter(routes map[string]Client) *StaticRouter {
|
|
clonedRoutes := make(map[string]Client, len(routes))
|
|
for messageType, client := range routes {
|
|
if client == nil {
|
|
continue
|
|
}
|
|
clonedRoutes[messageType] = client
|
|
}
|
|
|
|
return &StaticRouter{routes: clonedRoutes}
|
|
}
|
|
|
|
// Route returns the exact-match client for messageType.
|
|
func (r *StaticRouter) Route(messageType string) (Client, error) {
|
|
if r == nil {
|
|
return nil, ErrRouteNotFound
|
|
}
|
|
|
|
client, ok := r.routes[messageType]
|
|
if !ok || client == nil {
|
|
return nil, ErrRouteNotFound
|
|
}
|
|
|
|
return client, nil
|
|
}
|