Skip to content

Commit

Permalink
-
Browse files Browse the repository at this point in the history
  • Loading branch information
coronabytes committed Aug 14, 2024
1 parent 52eccb7 commit f1295c1
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 38 deletions.
4 changes: 2 additions & 2 deletions Core.ServiceMesh.Abstractions/ServiceMeshAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
namespace Core.ServiceMesh.Abstractions
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class ServiceMeshAttribute(string name, string? queueGroup = null) : Attribute
public class ServiceMeshAttribute(string name) : Attribute
{
public string Name => name;
public string? QueueGroup => queueGroup;
public string? QueueGroup { get; set; }
}
}
39 changes: 20 additions & 19 deletions Core.ServiceMesh/ServiceMeshExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,39 +183,40 @@ public static TracerProviderBuilder AddServiceMeshInstrumentation(this TracerPro

internal static void DynamicPublish<T>(WebApplication app) where T : class
{
app.MapPost("/publish/" + typeof(T).Name,
async ([FromBody] T value, [FromServices] IServiceMesh mesh) =>
var options = app.Services.GetRequiredService<ServiceMeshOptions>();

options.MapHttpPublishRoute(app, typeof(T), async ([FromBody] T value, [FromServices] IServiceMesh mesh) =>
{
await mesh.PublishAsync(value);
}).WithTags("mesh");
});
}

internal static void DynamicSend<T>(WebApplication app) where T : class
{
app.MapPost("/send/" + typeof(T).Name,
async ([FromBody] T value, [FromServices] IServiceMesh mesh) =>
{
await mesh.PublishAsync(value);
}).WithTags("mesh");
var options = app.Services.GetRequiredService<ServiceMeshOptions>();

options.MapHttpSendRoute(app, typeof(T), async ([FromBody] T value, [FromServices] IServiceMesh mesh) =>
{
await mesh.SendAsync(value);
});
}

internal static void DynamicRequestT<TReq, TRet>(WebApplication app, string service, MethodInfo info) where TReq : class
{
app.MapPost("/service/" + service + "/" + info.Name,
async ([FromBody] TReq value, [FromServices] IServiceMesh mesh) =>
await mesh.RequestAsync<TRet>(info, [value]))
.Produces<TRet>()
.WithTags(service);
var options = app.Services.GetRequiredService<ServiceMeshOptions>();

options.MapHttpRequestRoute(app, typeof(TReq), typeof(TRet), service, info,
async ([FromBody] TReq value, [FromServices] IServiceMesh mesh) =>
await mesh.RequestAsync<TRet>(info, [value]));
}

internal static void DynamicRequest<TReq>(WebApplication app, string service, MethodInfo info) where TReq : class
{
app.MapPost("/service/" + service + "/" + info.Name,
async ([FromBody] TReq value, [FromServices] IServiceMesh mesh) =>
{
await mesh.RequestAsync(info, [value]);
})
.WithTags(service);
var options = app.Services.GetRequiredService<ServiceMeshOptions>();

options.MapHttpRequestRoute(app, typeof(TReq), null, service, info,
async ([FromBody] TReq value, [FromServices] IServiceMesh mesh) =>
await mesh.RequestAsync(info, [value]));
}

public static WebApplication MapServiceMesh(this WebApplication app)
Expand Down
50 changes: 37 additions & 13 deletions Core.ServiceMesh/ServiceMeshOptions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System.Diagnostics.Metrics;
using System.Reflection;
using System.Reflection;
using System.Text.Json;
using Core.ServiceMesh.Abstractions;
using K4os.Compression.LZ4;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using NATS.Client.Core;
using NATS.Client.JetStream;
using NATS.Client.JetStream.Models;
Expand All @@ -11,6 +12,17 @@ namespace Core.ServiceMesh;

public class ServiceMeshOptions
{
/// <summary>
/// Nats durable consumer configuration
/// </summary>
public Func<string, ConsumerConfig, NatsJSConsumeOpts, NatsJSConsumeOpts> ConfigureConsumer =
(s, config, opts) => opts with { };

/// <summary>
/// Nats stream configuration
/// </summary>
public Action<string, StreamConfig> ConfigureStream = (s, config) => { };

/// <summary>
/// Prefix for streams and subjects
/// default: null
Expand Down Expand Up @@ -62,9 +74,9 @@ public class ServiceMeshOptions
$"{attr.Name}.{info.Name}.G{info.GetGenericArguments().Length}P{info.GetParameters().Length}";

/// <summary>
/// Nats subject for message
/// Nats subject for message
/// </summary>
public Func<Type, string> ResolveSubject { get; set; } = type => type.Name;
public Func<Type, string> ResolveSubject { get; set; } = type => type.FullName ?? type.Name;

/// <summary>
/// Resolve dotnet type from name
Expand All @@ -91,13 +103,25 @@ public class ServiceMeshOptions
/// </summary>
public int ServiceWorkers { get; set; } = Math.Max(1, Environment.ProcessorCount);

/// <summary>
/// Nats stream configuration
/// </summary>
public Action<string, StreamConfig> ConfigureStream = (s, config) => { };

/// <summary>
/// Nats durable consumer configuration
/// </summary>
public Func<string, ConsumerConfig, NatsJSConsumeOpts, NatsJSConsumeOpts> ConfigureConsumer = (s, config, opts) => opts with {};
public Action<WebApplication, Type, Delegate> MapHttpPublishRoute { get; set; } =
(app, type, handler) =>
{
app.MapPost("/publish/" + type.Name, handler)
.WithTags("mesh");
};

public Action<WebApplication, Type, Delegate> MapHttpSendRoute { get; set; } =
(app, type, handler) =>
{
app.MapPost("/send/" + type.Name, handler)
.WithTags("mesh");
};

public Action<WebApplication, Type, Type?, string, MethodInfo, Delegate> MapHttpRequestRoute { get; set; } =
(app, requestType, responseType, service, method, handler) =>
{
app.MapPost("/service/" + service + "/" + method.Name, handler)
.Produces(200, responseType)
.WithTags(service);
};
}
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ dotnet add package Core.ServiceMesh
```csharp
builder.AddServiceMesh(options =>
{
options.Nats = "nats://localhost:4222";
options.ConfigureNats = opts => opts with
{
Url = "nats://localhost:4222"
};
options.ConfigureStream = (name, config) =>
{
config.MaxAge = TimeSpan.FromDays(1);
};
options.InterfaceMode = ServiceInterfaceMode.Auto;
options.Assemblies = [typeof(ISomeService).Assembly, typeof(SomeService).Assembly];
});
```
Expand All @@ -36,7 +44,7 @@ public interface ISomeService
## Service Implementation

```csharp
[ServiceMesh("someservice", "someservice")]
[ServiceMesh("someservice")]
public class SomeService(ILogger<SomeService> logger) : ISomeService
{
public async Task<string> GetSomeString(int a, string b)
Expand Down
1 change: 0 additions & 1 deletion SampleApp/SampleApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Core.ServiceMesh.SampleInterfaces\SampleInterfaces.csproj" />
<ProjectReference Include="..\Core.ServiceMesh\Core.ServiceMesh.csproj" />
<ProjectReference Include="..\SampleInterfaces\SampleInterfaces.csproj" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion SampleApp/Services/SomeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace SampleApp.Services;

[ServiceMesh("someservice", "someservice")]
[ServiceMesh("someservice")]
public class SomeService(ILogger<SomeService> logger) : ISomeService
{
public async Task<string> GetSomeString(int a, string b)
Expand Down

0 comments on commit f1295c1

Please sign in to comment.