Add signal contracts for reachability, exploitability, trust, and unknown symbols
- Introduced `ReachabilityState`, `RuntimeHit`, `ExploitabilitySignal`, `ReachabilitySignal`, `SignalEnvelope`, `SignalType`, `TrustSignal`, and `UnknownSymbolSignal` records to define various signal types and their properties. - Implemented JSON serialization attributes for proper data interchange. - Created project files for the new signal contracts library and corresponding test projects. - Added deterministic test fixtures for micro-interaction testing. - Included cryptographic keys for secure operations with cosign.
This commit is contained in:
17
src/__Libraries/StellaOps.Router.Common/ClaimRequirement.cs
Normal file
17
src/__Libraries/StellaOps.Router.Common/ClaimRequirement.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a claim requirement for endpoint authorization.
|
||||
/// </summary>
|
||||
public sealed record ClaimRequirement
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the claim type that must be present.
|
||||
/// </summary>
|
||||
public required string Type { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional claim value that must match.
|
||||
/// </summary>
|
||||
public string? Value { get; init; }
|
||||
}
|
||||
42
src/__Libraries/StellaOps.Router.Common/ConnectionState.cs
Normal file
42
src/__Libraries/StellaOps.Router.Common/ConnectionState.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the state of a connection between a microservice and the router.
|
||||
/// </summary>
|
||||
public sealed class ConnectionState
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this connection.
|
||||
/// </summary>
|
||||
public required string ConnectionId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance descriptor for the connected microservice.
|
||||
/// </summary>
|
||||
public required InstanceDescriptor Instance { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the health status of this connection.
|
||||
/// </summary>
|
||||
public InstanceHealthStatus Status { get; set; } = InstanceHealthStatus.Unknown;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the UTC timestamp of the last heartbeat.
|
||||
/// </summary>
|
||||
public DateTime LastHeartbeatUtc { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the average ping time in milliseconds.
|
||||
/// </summary>
|
||||
public double AveragePingMs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the endpoints served by this connection.
|
||||
/// </summary>
|
||||
public Dictionary<(string Method, string Path), EndpointDescriptor> Endpoints { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the transport type used for this connection.
|
||||
/// </summary>
|
||||
public required TransportType TransportType { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Describes an endpoint's identity and metadata.
|
||||
/// </summary>
|
||||
public sealed record EndpointDescriptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of the service that owns this endpoint.
|
||||
/// </summary>
|
||||
public required string ServiceName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the semantic version of the service.
|
||||
/// </summary>
|
||||
public required string Version { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTP method (GET, POST, PUT, PATCH, DELETE).
|
||||
/// </summary>
|
||||
public required string Method { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path template (e.g., "/billing/invoices/{id}").
|
||||
/// </summary>
|
||||
public required string Path { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default timeout for this endpoint.
|
||||
/// </summary>
|
||||
public TimeSpan DefaultTimeout { get; init; } = TimeSpan.FromSeconds(30);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the claim requirements for authorization.
|
||||
/// </summary>
|
||||
public IReadOnlyList<ClaimRequirement> RequiringClaims { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this endpoint supports streaming.
|
||||
/// </summary>
|
||||
public bool SupportsStreaming { get; init; }
|
||||
}
|
||||
22
src/__Libraries/StellaOps.Router.Common/Frame.cs
Normal file
22
src/__Libraries/StellaOps.Router.Common/Frame.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a protocol frame in the router transport layer.
|
||||
/// </summary>
|
||||
public sealed record Frame
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the type of this frame.
|
||||
/// </summary>
|
||||
public required FrameType Type { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the correlation ID for request/response matching.
|
||||
/// </summary>
|
||||
public string? CorrelationId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw payload bytes.
|
||||
/// </summary>
|
||||
public ReadOnlyMemory<byte> Payload { get; init; }
|
||||
}
|
||||
47
src/__Libraries/StellaOps.Router.Common/FrameType.cs
Normal file
47
src/__Libraries/StellaOps.Router.Common/FrameType.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the frame types used in the router protocol.
|
||||
/// </summary>
|
||||
public enum FrameType
|
||||
{
|
||||
/// <summary>
|
||||
/// Initial registration frame sent by microservice.
|
||||
/// </summary>
|
||||
Hello,
|
||||
|
||||
/// <summary>
|
||||
/// Periodic health check frame.
|
||||
/// </summary>
|
||||
Heartbeat,
|
||||
|
||||
/// <summary>
|
||||
/// Request frame containing method, path, headers, and body.
|
||||
/// </summary>
|
||||
Request,
|
||||
|
||||
/// <summary>
|
||||
/// Response frame containing status, headers, and body.
|
||||
/// </summary>
|
||||
Response,
|
||||
|
||||
/// <summary>
|
||||
/// Streaming request data frame.
|
||||
/// </summary>
|
||||
RequestStreamData,
|
||||
|
||||
/// <summary>
|
||||
/// Streaming response data frame.
|
||||
/// </summary>
|
||||
ResponseStreamData,
|
||||
|
||||
/// <summary>
|
||||
/// Cancellation frame for aborting in-flight requests.
|
||||
/// </summary>
|
||||
Cancel,
|
||||
|
||||
/// <summary>
|
||||
/// Optional frame for updating endpoint metadata at runtime.
|
||||
/// </summary>
|
||||
EndpointsUpdate
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Provides global routing state derived from all live connections.
|
||||
/// </summary>
|
||||
public interface IGlobalRoutingState
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves an HTTP request to an endpoint descriptor.
|
||||
/// </summary>
|
||||
/// <param name="method">The HTTP method.</param>
|
||||
/// <param name="path">The request path.</param>
|
||||
/// <returns>The endpoint descriptor, or null if not found.</returns>
|
||||
EndpointDescriptor? ResolveEndpoint(string method, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all connections that can handle the specified endpoint.
|
||||
/// </summary>
|
||||
/// <param name="serviceName">The service name.</param>
|
||||
/// <param name="version">The service version.</param>
|
||||
/// <param name="method">The HTTP method.</param>
|
||||
/// <param name="path">The request path.</param>
|
||||
/// <returns>The available connection states.</returns>
|
||||
IEnumerable<ConnectionState> GetConnectionsForEndpoint(
|
||||
string serviceName,
|
||||
string version,
|
||||
string method,
|
||||
string path);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a connection and its endpoints.
|
||||
/// </summary>
|
||||
/// <param name="connection">The connection state to register.</param>
|
||||
void RegisterConnection(ConnectionState connection);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a connection from the routing state.
|
||||
/// </summary>
|
||||
/// <param name="connectionId">The connection ID to remove.</param>
|
||||
void UnregisterConnection(string connectionId);
|
||||
}
|
||||
24
src/__Libraries/StellaOps.Router.Common/IRoutingPlugin.cs
Normal file
24
src/__Libraries/StellaOps.Router.Common/IRoutingPlugin.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extensibility for routing decisions.
|
||||
/// </summary>
|
||||
public interface IRoutingPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the priority of this plugin. Lower values run first.
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Filters or reorders candidate connections for routing.
|
||||
/// </summary>
|
||||
/// <param name="candidates">The candidate connections.</param>
|
||||
/// <param name="endpoint">The target endpoint.</param>
|
||||
/// <param name="gatewayRegion">The gateway's region.</param>
|
||||
/// <returns>The filtered/reordered connections.</returns>
|
||||
IEnumerable<ConnectionState> Filter(
|
||||
IEnumerable<ConnectionState> candidates,
|
||||
EndpointDescriptor endpoint,
|
||||
string gatewayRegion);
|
||||
}
|
||||
24
src/__Libraries/StellaOps.Router.Common/ITransportClient.cs
Normal file
24
src/__Libraries/StellaOps.Router.Common/ITransportClient.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a transport client that connects to routers.
|
||||
/// </summary>
|
||||
public interface ITransportClient : IAsyncDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the transport type for this client.
|
||||
/// </summary>
|
||||
TransportType TransportType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Connects to a router endpoint.
|
||||
/// </summary>
|
||||
/// <param name="host">The router host.</param>
|
||||
/// <param name="port">The router port.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>The established connection.</returns>
|
||||
Task<ITransportConnection> ConnectAsync(
|
||||
string host,
|
||||
int port,
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a bidirectional transport connection.
|
||||
/// </summary>
|
||||
public interface ITransportConnection : IAsyncDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this connection.
|
||||
/// </summary>
|
||||
string ConnectionId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the connection is open.
|
||||
/// </summary>
|
||||
bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sends a frame over the connection.
|
||||
/// </summary>
|
||||
/// <param name="frame">The frame to send.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
ValueTask SendAsync(Frame frame, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Receives the next frame from the connection.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>The received frame, or null if connection closed.</returns>
|
||||
ValueTask<Frame?> ReceiveAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Closes the connection gracefully.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
Task CloseAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
45
src/__Libraries/StellaOps.Router.Common/ITransportServer.cs
Normal file
45
src/__Libraries/StellaOps.Router.Common/ITransportServer.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a transport server that accepts connections from microservices.
|
||||
/// </summary>
|
||||
public interface ITransportServer : IAsyncDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the transport type for this server.
|
||||
/// </summary>
|
||||
TransportType TransportType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Starts listening for incoming connections.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
Task StartAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Stops accepting new connections.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
Task StopAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a new connection is established.
|
||||
/// </summary>
|
||||
event EventHandler<TransportConnectionEventArgs>? ConnectionEstablished;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a connection is closed.
|
||||
/// </summary>
|
||||
event EventHandler<TransportConnectionEventArgs>? ConnectionClosed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event arguments for transport connection events.
|
||||
/// </summary>
|
||||
public sealed class TransportConnectionEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the connection that triggered the event.
|
||||
/// </summary>
|
||||
public required ITransportConnection Connection { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Describes a microservice instance's identity.
|
||||
/// </summary>
|
||||
public sealed record InstanceDescriptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier for this instance.
|
||||
/// </summary>
|
||||
public required string InstanceId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the service.
|
||||
/// </summary>
|
||||
public required string ServiceName { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the semantic version of the service.
|
||||
/// </summary>
|
||||
public required string Version { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the region where this instance is deployed.
|
||||
/// </summary>
|
||||
public required string Region { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the health status of a microservice instance.
|
||||
/// </summary>
|
||||
public enum InstanceHealthStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Health status is not yet determined.
|
||||
/// </summary>
|
||||
Unknown,
|
||||
|
||||
/// <summary>
|
||||
/// Instance is healthy and can accept requests.
|
||||
/// </summary>
|
||||
Healthy,
|
||||
|
||||
/// <summary>
|
||||
/// Instance is degraded but can still accept requests.
|
||||
/// </summary>
|
||||
Degraded,
|
||||
|
||||
/// <summary>
|
||||
/// Instance is draining and will not accept new requests.
|
||||
/// </summary>
|
||||
Draining,
|
||||
|
||||
/// <summary>
|
||||
/// Instance is unhealthy and should not receive requests.
|
||||
/// </summary>
|
||||
Unhealthy
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
32
src/__Libraries/StellaOps.Router.Common/TransportType.cs
Normal file
32
src/__Libraries/StellaOps.Router.Common/TransportType.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace StellaOps.Router.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the transport types supported for microservice-to-router communication.
|
||||
/// </summary>
|
||||
public enum TransportType
|
||||
{
|
||||
/// <summary>
|
||||
/// In-memory transport for testing and local development.
|
||||
/// </summary>
|
||||
InMemory,
|
||||
|
||||
/// <summary>
|
||||
/// UDP transport for small/bounded payloads.
|
||||
/// </summary>
|
||||
Udp,
|
||||
|
||||
/// <summary>
|
||||
/// TCP transport with length-prefixed framing.
|
||||
/// </summary>
|
||||
Tcp,
|
||||
|
||||
/// <summary>
|
||||
/// TLS/mTLS transport with certificate-based authentication.
|
||||
/// </summary>
|
||||
Tls,
|
||||
|
||||
/// <summary>
|
||||
/// RabbitMQ transport for queue-based communication.
|
||||
/// </summary>
|
||||
RabbitMq
|
||||
}
|
||||
Reference in New Issue
Block a user