Skip to content

Commit 9b4ce43

Browse files
committed
commands + Middleware
1 parent c95cfdc commit 9b4ce43

22 files changed

Lines changed: 344 additions & 30 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.Diagnostics;
4+
using System.IO;
5+
using System.Net;
6+
using System.Runtime.Serialization;
7+
using System.Text.Json;
8+
using System.Threading.Tasks;
9+
using Microsoft.AspNetCore.Http;
10+
using Microsoft.Extensions.Logging;
11+
12+
namespace ManagedCode.Communication.Extensions;
13+
14+
public class CommunicationMiddleware
15+
{
16+
private readonly ILogger<CommunicationMiddleware> _logger;
17+
private readonly RequestDelegate _next;
18+
19+
public CommunicationMiddleware(ILogger<CommunicationMiddleware> logger, RequestDelegate next)
20+
{
21+
_logger = logger;
22+
_next = next;
23+
}
24+
25+
public async Task Invoke(HttpContext httpContext)
26+
{
27+
var sw = Stopwatch.StartNew();
28+
try
29+
{
30+
await _next(httpContext);
31+
32+
}
33+
catch (Exception ex) when (ex is InvalidDataException ||
34+
ex is InvalidDataContractException)
35+
{
36+
_logger.LogError("Request throw an error", ex);
37+
//httpContext.Response.Clear();
38+
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
39+
var json = JsonSerializer.Serialize(Result.Fail(HttpStatusCode.InternalServerError, ex));
40+
await httpContext.Response.WriteAsJsonAsync(json);
41+
}
42+
catch (Exception ex) when (ex is ValidationException)
43+
{
44+
_logger.LogError("Request throw an error", ex);
45+
//httpContext.Response.Clear();
46+
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
47+
var json = JsonSerializer.Serialize(Result.Fail(HttpStatusCode.InternalServerError, ex));
48+
await httpContext.Response.WriteAsJsonAsync(json);
49+
}
50+
catch (Exception ex)
51+
{
52+
_logger.LogError("Request throw an error", ex);
53+
//httpContext.Response.Clear();
54+
httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
55+
var json = JsonSerializer.Serialize(Result.Fail(HttpStatusCode.InternalServerError, ex));
56+
await httpContext.Response.WriteAsJsonAsync(json);
57+
}
58+
sw.Stop();
59+
httpContext.Response.Headers.Add("executionTime", sw.Elapsed.ToString());
60+
}
61+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using Microsoft.AspNetCore.Builder;
3+
4+
namespace ManagedCode.Communication.Extensions;
5+
6+
public static class CommunicationAppBuilderExtensions
7+
{
8+
public static IApplicationBuilder UseCommunication(this IApplicationBuilder app)
9+
{
10+
if (app == null)
11+
{
12+
throw new ArgumentNullException(nameof(app));
13+
}
14+
15+
return app.UseMiddleware<CommunicationMiddleware>();
16+
}
17+
}

ManagedCode.Communication.Extensions/ControllerExtensions.cs renamed to ManagedCode.Communication.Extensions/Extensions/ControllerExtensions.cs

File renamed without changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using ManagedCode.Communication.Surrogates;
2+
using Orleans;
3+
4+
namespace ManagedCode.Communication.Converters;
5+
6+
[RegisterConverter]
7+
public sealed class CommandSurrogateConverter : IConverter<Command, CommandSurrogate>
8+
{
9+
public Command ConvertFromSurrogate(in CommandSurrogate surrogate)
10+
{
11+
return new Command(surrogate.Id);
12+
}
13+
14+
public CommandSurrogate ConvertToSurrogate(in Command value)
15+
{
16+
return new CommandSurrogate(value.Id);
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using ManagedCode.Communication.Surrogates;
2+
using Orleans;
3+
4+
namespace ManagedCode.Communication.Converters;
5+
6+
[RegisterConverter]
7+
public sealed class CommandTSurrogateConverter<T> : IConverter<Command<T>, CommandTSurrogate<T>>
8+
{
9+
public Command<T> ConvertFromSurrogate(in CommandTSurrogate<T> surrogate)
10+
{
11+
return new Command<T>(surrogate.Id, surrogate.Value);
12+
}
13+
14+
public CommandTSurrogate<T> ConvertToSurrogate(in Command<T> value)
15+
{
16+
return new CommandTSurrogate<T>(value.Id, value.Value);
17+
}
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Collections.Generic;
2+
using Orleans;
3+
4+
namespace ManagedCode.Communication.Surrogates;
5+
6+
[Immutable]
7+
[GenerateSerializer]
8+
public struct CommandSurrogate
9+
{
10+
[Id(0)]
11+
public string? Id;
12+
13+
public CommandSurrogate(string? id)
14+
{
15+
Id = id;
16+
}
17+
18+
19+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Orleans;
2+
3+
namespace ManagedCode.Communication.Surrogates;
4+
5+
[Immutable]
6+
[GenerateSerializer]
7+
public struct CommandTSurrogate<T>
8+
{
9+
[Id(0)]
10+
public string? Id;
11+
[Id(1)]
12+
public T? Value;
13+
14+
public CommandTSurrogate(string? id, T? value)
15+
{
16+
Id = id;
17+
Value = value;
18+
}
19+
20+
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Linq;
2+
using FluentAssertions;
3+
using Xunit;
4+
5+
namespace ManagedCode.Communication.Tests.Collections;
6+
7+
public class CommandTests
8+
{
9+
[Fact]
10+
public void FromValue()
11+
{
12+
var command = Command.From(nameof(Command));
13+
command.Value.Should().Be(nameof(Command));
14+
}
15+
16+
[Fact]
17+
public void FromIdValue()
18+
{
19+
var command = Command<string>.From(nameof(CommandTests), nameof(Command));
20+
command.Id.Should().Be(nameof(CommandTests));
21+
command.Value.Should().Be(nameof(Command));
22+
}
23+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.Net;
2+
using System.Net.Http.Json;
3+
using System.Net.Mime;
4+
using System.Threading.Tasks;
5+
using FluentAssertions;
6+
using ManagedCode.Communication.Tests.TestApp;
7+
using Xunit;
8+
using Xunit.Abstractions;
9+
10+
namespace ManagedCode.Communication.Tests;
11+
12+
[Collection(nameof(TestClusterApplication))]
13+
public class MiddlewareTests
14+
{
15+
private readonly ITestOutputHelper _outputHelper;
16+
private readonly TestClusterApplication _application;
17+
18+
public MiddlewareTests(ITestOutputHelper outputHelper, TestClusterApplication application)
19+
{
20+
_outputHelper = outputHelper;
21+
_application = application;
22+
}
23+
24+
[Fact]
25+
public async Task Track()
26+
{
27+
var response = await _application.CreateClient().GetAsync($"test/test1");
28+
response.StatusCode.Should().Be(HttpStatusCode.InternalServerError);
29+
var content = await response.Content.ReadAsStringAsync();
30+
var result = await response.Content.ReadFromJsonAsync<Result>();
31+
}
32+
33+
34+
}

ManagedCode.Communication.Tests/DeserializationTests.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.ComponentModel.DataAnnotations;
34
using System.Net;
5+
using System.Text.Json;
46
using FluentAssertions;
57
using Newtonsoft.Json;
68
using Xunit;
@@ -48,7 +50,7 @@ public void DeserializeResult_WithTextJson(IResult result)
4850

4951
[Theory]
5052
[MemberData(nameof(GetValueResults))]
51-
public void DeserializeValueResult_WithTextJson<T>(IResult result)
53+
public void DeserializeValueResultT_WithTextJson<T>(IResult result)
5254
{
5355
// Act
5456
var serialized = JsonSerializer.Serialize(result);
@@ -57,11 +59,24 @@ public void DeserializeValueResult_WithTextJson<T>(IResult result)
5759
// Assert
5860
deserialized.Should().BeEquivalentTo(result);
5961
}
62+
63+
[Theory]
64+
[MemberData(nameof(GetValueResults))]
65+
public void DeserializeValueResult_WithTextJson<T>(IResult result)
66+
{
67+
// Act
68+
var serialized = JsonSerializer.Serialize(result);
69+
var deserialized = JsonSerializer.Deserialize<Result>(serialized, new JsonSerializerOptions());
70+
71+
// Assert
72+
deserialized.IsSuccess.Should().Be(result.IsSuccess);
73+
}
6074

6175
public static IEnumerable<object[]> GetResults()
6276
{
6377
yield return new object[] { Result.Succeed() };
6478
yield return new object[] { Result.Fail() };
79+
yield return new object[] { Result.Fail(new ValidationException("Test exception")) };
6580
yield return new object[] { Result.Fail(new Exception("Test exception")) };
6681
yield return new object[] { Result.Fail(Error.Create("Test error", HttpStatusCode.Found)) };
6782
}
@@ -71,6 +86,7 @@ public static IEnumerable<object[]> GetValueResults()
7186
yield return new object[] { Result<int>.Succeed(2) };
7287
yield return new object[] { Result<string>.Succeed("Test string") };
7388
yield return new object[] { Result<int>.Fail() };
89+
yield return new object[] { Result.Fail<int>(new ValidationException("Test exception")) };
7490
yield return new object[] { Result<int>.Fail(new Exception("Test exception")) };
7591
yield return new object[] { Result<int>.Fail(Error.Create("Test error", HttpStatusCode.Found)) };
7692
}

0 commit comments

Comments
 (0)