Add unit tests for Router configuration and transport layers
- Implemented tests for RouterConfig, RoutingOptions, StaticInstanceConfig, and RouterConfigOptions to ensure default values are set correctly. - Added tests for RouterConfigProvider to validate configurations and ensure defaults are returned when no file is specified. - Created tests for ConfigValidationResult to check success and error scenarios. - Developed tests for ServiceCollectionExtensions to verify service registration for RouterConfig. - Introduced UdpTransportTests to validate serialization, connection, request-response, and error handling in UDP transport. - Added scripts for signing authority gaps and hashing DevPortal SDK snippets.
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
using System.Text;
|
||||
using RabbitMQ.Client;
|
||||
using StellaOps.Router.Common.Enums;
|
||||
using StellaOps.Router.Common.Models;
|
||||
|
||||
namespace StellaOps.Router.Transport.RabbitMq;
|
||||
|
||||
/// <summary>
|
||||
/// Handles serialization and deserialization of frames for RabbitMQ transport.
|
||||
/// </summary>
|
||||
public static class RabbitMqFrameProtocol
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses a frame from a RabbitMQ message.
|
||||
/// </summary>
|
||||
/// <param name="body">The message body.</param>
|
||||
/// <param name="properties">The message properties.</param>
|
||||
/// <returns>The parsed frame.</returns>
|
||||
public static Frame ParseFrame(ReadOnlyMemory<byte> body, IReadOnlyBasicProperties properties)
|
||||
{
|
||||
var frameType = ParseFrameType(properties.Type);
|
||||
var correlationId = properties.CorrelationId;
|
||||
|
||||
return new Frame
|
||||
{
|
||||
Type = frameType,
|
||||
CorrelationId = correlationId,
|
||||
Payload = body
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates BasicProperties for a frame.
|
||||
/// </summary>
|
||||
/// <param name="frame">The frame to serialize.</param>
|
||||
/// <param name="replyTo">The reply queue name.</param>
|
||||
/// <param name="timeout">Optional timeout for the message.</param>
|
||||
/// <returns>The basic properties.</returns>
|
||||
public static BasicProperties CreateProperties(Frame frame, string? replyTo, TimeSpan? timeout = null)
|
||||
{
|
||||
var props = new BasicProperties
|
||||
{
|
||||
Type = frame.Type.ToString(),
|
||||
Timestamp = new AmqpTimestamp(DateTimeOffset.UtcNow.ToUnixTimeSeconds()),
|
||||
DeliveryMode = DeliveryModes.Transient // Non-persistent (1)
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(frame.CorrelationId))
|
||||
{
|
||||
props.CorrelationId = frame.CorrelationId;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(replyTo))
|
||||
{
|
||||
props.ReplyTo = replyTo;
|
||||
}
|
||||
|
||||
if (timeout.HasValue)
|
||||
{
|
||||
props.Expiration = ((int)timeout.Value.TotalMilliseconds).ToString();
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a FrameType from the message Type property.
|
||||
/// </summary>
|
||||
private static FrameType ParseFrameType(string? type)
|
||||
{
|
||||
if (string.IsNullOrEmpty(type))
|
||||
{
|
||||
return FrameType.Request;
|
||||
}
|
||||
|
||||
if (Enum.TryParse<FrameType>(type, ignoreCase: true, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return FrameType.Request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the connection ID from message properties.
|
||||
/// </summary>
|
||||
/// <param name="properties">The message properties.</param>
|
||||
/// <returns>The connection ID.</returns>
|
||||
public static string ExtractConnectionId(IReadOnlyBasicProperties properties)
|
||||
{
|
||||
// Use ReplyTo as the basis for connection ID (identifies the instance)
|
||||
if (!string.IsNullOrEmpty(properties.ReplyTo))
|
||||
{
|
||||
// Extract instance ID from queue name like "stella.svc.{instanceId}"
|
||||
var parts = properties.ReplyTo.Split('.');
|
||||
if (parts.Length >= 3)
|
||||
{
|
||||
return $"rmq-{parts[^1]}";
|
||||
}
|
||||
return $"rmq-{properties.ReplyTo}";
|
||||
}
|
||||
|
||||
// Fallback to correlation ID
|
||||
if (!string.IsNullOrEmpty(properties.CorrelationId))
|
||||
{
|
||||
return $"rmq-{properties.CorrelationId[..Math.Min(16, properties.CorrelationId.Length)]}";
|
||||
}
|
||||
|
||||
return $"rmq-{Guid.NewGuid():N}"[..32];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user