-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(connector): add optional debugging targets
- Loading branch information
1 parent
caf5bf6
commit 8de2829
Showing
4 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
src/Thinktecture.Relay.Connector/DependencyInjection/RelayConnectorBuilderExtensions.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,55 @@ | ||
using Thinktecture.Relay.Acknowledgement; | ||
using Thinktecture.Relay.Connector.DependencyInjection; | ||
using Thinktecture.Relay.Connector.Targets; | ||
using Thinktecture.Relay.Transport; | ||
|
||
// ReSharper disable once CheckNamespace; (extension methods on IServiceCollection namespace) | ||
namespace Microsoft.Extensions.DependencyInjection; | ||
|
||
/// <summary> | ||
/// Extension methods for the <see cref="IRelayConnectorBuilder{TRequest,TResponse,TAcknowledge}"/>. | ||
/// </summary> | ||
public static class RelayConnectorBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Adds the <see cref="PingTarget{TRequest,TResponse}"/>. | ||
/// </summary> | ||
/// <remarks>The default target key is "$ping".</remarks> | ||
/// <param name="builder">The <see cref="IRelayConnectorBuilder{TRequest,TResponse,TAcknowledge}"/>.</param> | ||
/// <param name="targetKey">The target key for the <see cref="PingTarget{TRequest,TResponse}"/>.</param> | ||
/// <typeparam name="TRequest">The type of request.</typeparam> | ||
/// <typeparam name="TResponse">The type of response.</typeparam> | ||
/// <typeparam name="TAcknowledge">The type of acknowledge.</typeparam> | ||
/// <returns>The <see cref="IRelayConnectorBuilder{TRequest,TResponse,TAcknowledge}"/>.</returns> | ||
public static IRelayConnectorBuilder<TRequest, TResponse, TAcknowledge> AddPingTarget<TRequest, TResponse, | ||
TAcknowledge>(this IRelayConnectorBuilder<TRequest, TResponse, TAcknowledge> builder, string targetKey = "$ping") | ||
where TRequest : IClientRequest | ||
where TResponse : ITargetResponse, new() | ||
where TAcknowledge : IAcknowledgeRequest | ||
{ | ||
builder.AddTarget<TRequest, TResponse, TAcknowledge, PingTarget<TRequest, TResponse>>(targetKey); | ||
|
||
return builder; | ||
} | ||
|
||
/// <summary> | ||
/// Adds the <see cref="EchoTarget{TRequest,TResponse}"/>. | ||
/// </summary> | ||
/// <remarks>The default target key is "$echo" and should only be added for debugging purposes.</remarks> | ||
/// <param name="builder">The <see cref="IRelayConnectorBuilder{TRequest,TResponse,TAcknowledge}"/>.</param> | ||
/// <param name="targetKey">The target key for the <see cref="EchoTarget{TRequest,TResponse}"/>.</param> | ||
/// <typeparam name="TRequest">The type of request.</typeparam> | ||
/// <typeparam name="TResponse">The type of response.</typeparam> | ||
/// <typeparam name="TAcknowledge">The type of acknowledge.</typeparam> | ||
/// <returns>The <see cref="IRelayConnectorBuilder{TRequest,TResponse,TAcknowledge}"/>.</returns> | ||
public static IRelayConnectorBuilder<TRequest, TResponse, TAcknowledge> AddEchoTarget<TRequest, TResponse, | ||
TAcknowledge>(this IRelayConnectorBuilder<TRequest, TResponse, TAcknowledge> builder, string targetKey = "$echo") | ||
where TRequest : IClientRequest | ||
where TResponse : ITargetResponse, new() | ||
where TAcknowledge : IAcknowledgeRequest | ||
{ | ||
builder.AddTarget<TRequest, TResponse, TAcknowledge, EchoTarget<TRequest, TResponse>>(targetKey); | ||
|
||
return builder; | ||
} | ||
} |
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,83 @@ | ||
using System; | ||
using System.IO; | ||
using System.Net; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Thinktecture.Relay.Transport; | ||
|
||
namespace Thinktecture.Relay.Connector.Targets; | ||
|
||
/// <inheritdoc /> | ||
public class EchoTarget<TRequest, TResponse> : IRelayTargetFunc<TRequest, TResponse> | ||
where TRequest : IClientRequest | ||
where TResponse : ITargetResponse, new() | ||
{ | ||
private class CopyStream(Stream source, long length) : Stream | ||
{ | ||
private long _length = Math.Max(0, length); | ||
|
||
public override void Flush() | ||
=> throw new NotImplementedException(); | ||
|
||
public override int Read(byte[] buffer, int offset, int count) | ||
{ | ||
if (Position == _length) return 0; | ||
|
||
var read = 0; | ||
|
||
while (read < count && Position < _length) | ||
{ | ||
var remaining = Math.Min(_length - Position, count); | ||
var available = source.Read(buffer, offset, (int)remaining); | ||
if (available == 0) | ||
{ | ||
source.Position = 0; | ||
} | ||
|
||
offset += available; | ||
read += available; | ||
count -= available; | ||
|
||
Position += available; | ||
} | ||
|
||
return read; | ||
} | ||
|
||
public override long Seek(long offset, SeekOrigin origin) | ||
=> throw new NotSupportedException(); | ||
|
||
public override void SetLength(long value) | ||
=> _length = value; | ||
|
||
public override void Write(byte[] buffer, int offset, int count) | ||
=> throw new NotSupportedException(); | ||
|
||
public override bool CanRead => true; | ||
|
||
public override bool CanSeek => false; | ||
|
||
public override bool CanWrite => false; | ||
|
||
public override long Length => _length; | ||
|
||
public override long Position { get; set; } | ||
} | ||
|
||
/// <inheritdoc /> | ||
public Task<TResponse> HandleAsync(TRequest request, CancellationToken cancellationToken = default) | ||
{ | ||
if (!request.HttpMethod.Equals("POST", StringComparison.OrdinalIgnoreCase) || request.BodyContent is null) | ||
return Task.FromResult(request.CreateResponse<TResponse>(HttpStatusCode.NoContent)); | ||
|
||
var result = request.CreateResponse<TResponse>(HttpStatusCode.OK); | ||
|
||
result.BodyContent = int.TryParse(request.Url, out var size) | ||
? new CopyStream(request.BodyContent, size) | ||
: request.BodyContent; | ||
result.BodySize = result.BodyContent.Length; | ||
result.BodyContent.Position = 0; | ||
|
||
return Task.FromResult(result); | ||
} | ||
} |
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,33 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Net; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Thinktecture.Relay.Transport; | ||
|
||
namespace Thinktecture.Relay.Connector.Targets; | ||
|
||
/// <inheritdoc /> | ||
public class PingTarget<TRequest, TResponse> : IRelayTargetFunc<TRequest, TResponse> | ||
where TRequest : IClientRequest | ||
where TResponse : ITargetResponse, new() | ||
{ | ||
/// <inheritdoc /> | ||
public Task<TResponse> HandleAsync(TRequest request, CancellationToken cancellationToken = default) | ||
{ | ||
if (!request.HttpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase)) | ||
return Task.FromResult(request.CreateResponse<TResponse>(HttpStatusCode.NotFound)); | ||
|
||
var result = request.CreateResponse<TResponse>(HttpStatusCode.OK); | ||
|
||
result.HttpHeaders = new Dictionary<string, string[]>() | ||
{ | ||
{ "Content-Type", ["text/plain"] }, | ||
}; | ||
result.BodyContent = new MemoryStream("PONG"u8.ToArray()); | ||
result.BodySize = result.BodyContent.Length; | ||
|
||
return Task.FromResult(result); | ||
} | ||
} |
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