-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #630 from leancodepl/feature/local-execution
Local execution of CQRS
- Loading branch information
Showing
46 changed files
with
2,340 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
src/CQRS/LeanCode.CQRS.AspNetCore/Local/Context/LocalCallContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using System.Security.Claims; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Http.Features; | ||
|
||
namespace LeanCode.CQRS.AspNetCore.Local.Context; | ||
|
||
internal class LocalCallContext : HttpContext, IDisposable | ||
{ | ||
private const int DefaultFeatureCollectionSize = 6; // 4 internal, 2 external (set in local executors) | ||
|
||
private readonly FeatureCollection features; | ||
|
||
private readonly ItemsFeature itemsFeature; | ||
private readonly LocalCallServiceProvidersFeature serviceProvidersFeature; | ||
private readonly LocalCallLifetimeFeature callLifetimeFeature; | ||
|
||
public override IFeatureCollection Features => features; | ||
|
||
public override ClaimsPrincipal User { get; set; } | ||
public override string TraceIdentifier { get; set; } | ||
public override HttpRequest Request { get; } | ||
public override HttpResponse Response { get; } | ||
|
||
public override IDictionary<object, object?> Items | ||
{ | ||
get => itemsFeature.Items; | ||
set => itemsFeature.Items = value; | ||
} | ||
|
||
public override IServiceProvider RequestServices | ||
{ | ||
get => serviceProvidersFeature.RequestServices; | ||
set => serviceProvidersFeature.RequestServices = value; | ||
} | ||
|
||
public override CancellationToken RequestAborted | ||
{ | ||
get => callLifetimeFeature.RequestAborted; | ||
set => callLifetimeFeature.RequestAborted = value; | ||
} | ||
|
||
public CancellationToken CallAborted => callLifetimeFeature.CallAborted; | ||
|
||
public override ConnectionInfo Connection => NullConnectionInfo.Empty; | ||
public override WebSocketManager WebSockets => NullWebSocketManager.Empty; | ||
public override ISession Session | ||
{ | ||
get => NullSession.Empty; | ||
set { } | ||
} | ||
|
||
public LocalCallContext( | ||
IServiceProvider requestServices, | ||
ClaimsPrincipal user, | ||
string? activityIdentifier, | ||
IHeaderDictionary? headers, | ||
CancellationToken cancellationToken | ||
) | ||
{ | ||
features = new(DefaultFeatureCollectionSize); | ||
|
||
User = user; | ||
TraceIdentifier = activityIdentifier ?? ""; | ||
Request = new LocalHttpRequest(this, headers); | ||
Response = new NullHttpResponse(this); | ||
|
||
itemsFeature = new(); | ||
serviceProvidersFeature = new(requestServices); | ||
callLifetimeFeature = new(cancellationToken); | ||
|
||
features.Set<IItemsFeature>(itemsFeature); | ||
features.Set<IServiceProvidersFeature>(serviceProvidersFeature); | ||
features.Set<IHttpRequestLifetimeFeature>(callLifetimeFeature); | ||
features.Set<IEndpointFeature>(NullEndpointFeature.Empty); | ||
} | ||
|
||
public override void Abort() => callLifetimeFeature.Abort(); | ||
|
||
public void Dispose() => callLifetimeFeature.Dispose(); | ||
} |
27 changes: 27 additions & 0 deletions
27
src/CQRS/LeanCode.CQRS.AspNetCore/Local/Context/LocalCallLifetimeFeature.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using Microsoft.AspNetCore.Http.Features; | ||
|
||
namespace LeanCode.CQRS.AspNetCore.Local.Context; | ||
|
||
internal class LocalCallLifetimeFeature : IHttpRequestLifetimeFeature, IDisposable | ||
{ | ||
private readonly CancellationTokenSource source; | ||
private CancellationToken requestAborted; | ||
|
||
public CancellationToken RequestAborted | ||
{ | ||
get => requestAborted; | ||
set => requestAborted = value; | ||
} | ||
|
||
public CancellationToken CallAborted => source.Token; | ||
|
||
public LocalCallLifetimeFeature(CancellationToken cancellationToken) | ||
{ | ||
source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); | ||
requestAborted = source.Token; | ||
} | ||
|
||
public void Abort() => source.Cancel(); | ||
|
||
public void Dispose() => source.Dispose(); | ||
} |
13 changes: 13 additions & 0 deletions
13
src/CQRS/LeanCode.CQRS.AspNetCore/Local/Context/LocalCallServiceProvidersFeature.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using Microsoft.AspNetCore.Http.Features; | ||
|
||
namespace LeanCode.CQRS.AspNetCore.Local.Context; | ||
|
||
internal class LocalCallServiceProvidersFeature : IServiceProvidersFeature | ||
{ | ||
public IServiceProvider RequestServices { get; set; } | ||
|
||
public LocalCallServiceProvidersFeature(IServiceProvider requestServices) | ||
{ | ||
RequestServices = requestServices; | ||
} | ||
} |
104 changes: 104 additions & 0 deletions
104
src/CQRS/LeanCode.CQRS.AspNetCore/Local/Context/LocalHttpRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
using Microsoft.AspNetCore.Http; | ||
|
||
namespace LeanCode.CQRS.AspNetCore.Local.Context; | ||
|
||
internal class LocalHttpRequest : HttpRequest | ||
{ | ||
public override HttpContext HttpContext { get; } | ||
public override IHeaderDictionary Headers { get; } | ||
|
||
public override bool HasFormContentType => false; | ||
|
||
public override string Method | ||
{ | ||
get => ""; | ||
set { } | ||
} | ||
|
||
public override string Scheme | ||
{ | ||
get => ""; | ||
set { } | ||
} | ||
|
||
public override bool IsHttps | ||
{ | ||
get => false; | ||
set { } | ||
} | ||
|
||
public override HostString Host | ||
{ | ||
get => default; | ||
set { } | ||
} | ||
|
||
public override PathString PathBase | ||
{ | ||
get => PathString.Empty; | ||
set { } | ||
} | ||
|
||
public override PathString Path | ||
{ | ||
get => PathString.Empty; | ||
set { } | ||
} | ||
|
||
public override QueryString QueryString | ||
{ | ||
get => QueryString.Empty; | ||
set { } | ||
} | ||
|
||
public override IQueryCollection Query | ||
{ | ||
get => QueryCollection.Empty; | ||
set { } | ||
} | ||
|
||
public override string Protocol | ||
{ | ||
get => ""; | ||
set { } | ||
} | ||
|
||
public override IRequestCookieCollection Cookies | ||
{ | ||
get => NullRequestCookieCollection.Empty; | ||
set { } | ||
} | ||
|
||
public override long? ContentLength | ||
{ | ||
get => null; | ||
set { } | ||
} | ||
|
||
public override string? ContentType | ||
{ | ||
get => null; | ||
set { } | ||
} | ||
|
||
public override Stream Body | ||
{ | ||
get => Stream.Null; | ||
set { } | ||
} | ||
|
||
public override IFormCollection Form | ||
{ | ||
get => FormCollection.Empty; | ||
set { } | ||
} | ||
|
||
public LocalHttpRequest(HttpContext httpContext, IHeaderDictionary? headers) | ||
{ | ||
HttpContext = httpContext; | ||
Headers = headers ?? new HeaderDictionary(); | ||
} | ||
|
||
public override Task<IFormCollection> ReadFormAsync(CancellationToken cancellationToken = default) => | ||
Task.FromResult<IFormCollection>(FormCollection.Empty); | ||
} |
51 changes: 51 additions & 0 deletions
51
src/CQRS/LeanCode.CQRS.AspNetCore/Local/Context/NullConnectionInfo.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
using System.Net; | ||
using System.Security.Cryptography.X509Certificates; | ||
using Microsoft.AspNetCore.Http; | ||
|
||
namespace LeanCode.CQRS.AspNetCore.Local.Context; | ||
|
||
internal class NullConnectionInfo : ConnectionInfo | ||
{ | ||
public static readonly NullConnectionInfo Empty = new(); | ||
|
||
public override string Id | ||
{ | ||
get => ""; | ||
set { } | ||
} | ||
|
||
public override IPAddress? RemoteIpAddress | ||
{ | ||
get => null; | ||
set { } | ||
} | ||
|
||
public override int RemotePort | ||
{ | ||
get => 0; | ||
set { } | ||
} | ||
|
||
public override IPAddress? LocalIpAddress | ||
{ | ||
get => null; | ||
set { } | ||
} | ||
|
||
public override int LocalPort | ||
{ | ||
get => 0; | ||
set { } | ||
} | ||
|
||
public override X509Certificate2? ClientCertificate | ||
{ | ||
get => null; | ||
set { } | ||
} | ||
|
||
private NullConnectionInfo() { } | ||
|
||
public override Task<X509Certificate2?> GetClientCertificateAsync(CancellationToken cancellationToken = default) => | ||
Task.FromResult<X509Certificate2?>(null); | ||
} |
17 changes: 17 additions & 0 deletions
17
src/CQRS/LeanCode.CQRS.AspNetCore/Local/Context/NullEndpointFeature.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Http.Features; | ||
|
||
namespace LeanCode.CQRS.AspNetCore.Local.Context; | ||
|
||
internal class NullEndpointFeature : IEndpointFeature | ||
{ | ||
public static readonly NullEndpointFeature Empty = new(); | ||
|
||
public Endpoint? Endpoint | ||
{ | ||
get => null; | ||
set { } | ||
} | ||
|
||
private NullEndpointFeature() { } | ||
} |
60 changes: 60 additions & 0 deletions
60
src/CQRS/LeanCode.CQRS.AspNetCore/Local/Context/NullHeaderDictionary.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System.Collections; | ||
using System.Collections.ObjectModel; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.Primitives; | ||
|
||
namespace LeanCode.CQRS.AspNetCore.Local.Context; | ||
|
||
internal class NullHeaderDictionary : IHeaderDictionary | ||
{ | ||
public static readonly NullHeaderDictionary Empty = new(); | ||
|
||
public StringValues this[string key] | ||
{ | ||
get => StringValues.Empty; | ||
set { } | ||
} | ||
|
||
public long? ContentLength | ||
{ | ||
get => null; | ||
set { } | ||
} | ||
|
||
public ICollection<string> Keys { get; } = new ReadOnlyCollection<string>([ ]); | ||
|
||
public ICollection<StringValues> Values { get; } = new ReadOnlyCollection<StringValues>([ ]); | ||
|
||
public int Count => 0; | ||
|
||
public bool IsReadOnly => true; | ||
|
||
private NullHeaderDictionary() { } | ||
|
||
public void Add(string key, StringValues value) { } | ||
|
||
public void Add(KeyValuePair<string, StringValues> item) { } | ||
|
||
public void Clear() { } | ||
|
||
public bool Contains(KeyValuePair<string, StringValues> item) => false; | ||
|
||
public bool ContainsKey(string key) => false; | ||
|
||
public void CopyTo(KeyValuePair<string, StringValues>[] array, int arrayIndex) { } | ||
|
||
public bool Remove(string key) => false; | ||
|
||
public bool Remove(KeyValuePair<string, StringValues> item) => false; | ||
|
||
public bool TryGetValue(string key, out StringValues value) | ||
{ | ||
value = StringValues.Empty; | ||
return false; | ||
} | ||
|
||
public IEnumerator<KeyValuePair<string, StringValues>> GetEnumerator() => | ||
Enumerable.Empty<KeyValuePair<string, StringValues>>().GetEnumerator(); | ||
|
||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | ||
} |
Oops, something went wrong.