Skip to content

Commit

Permalink
Azure Service Bus interop. Closes GH-429
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremydmiller committed Sep 18, 2023
1 parent 09b55a8 commit b1ce9c5
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# Interoperability

Wolverine does not yet have the API mechanisms to enable interoperability with non-Wolverine systems, but don't fret,
that is planned!
Hey, it's a complicated world and Wolverine is a relative newcomer, so it's somewhat likely you'll find yourself needing to make a Wolverine application talk via Azure Service Bus to
a non-Wolverine application. Not to worry (too much), Wolverine has you covered with the ability to customize Wolverine to Azure Service Bus mapping.

You can follow the [backlog item for that potential work here](https://github.com/JasperFx/wolverine/issues/399).
You can create interoperability with non-Wolverine applications by writing a custom `IAzureServiceBusEnvelopeMapper`
as shown in the following sample:

snippet: sample_custom_azure_service_bus_mapper

To apply that mapper to specific endpoints, use this syntax on any type of Azure Service Bus endpoint:

snippet: sample_configuring_custom_envelope_mapper_for_azure_service_bus~~~~
57 changes: 56 additions & 1 deletion src/Transports/Azure/Wolverine.AzureServiceBus.Tests/Samples.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using Azure.Messaging.ServiceBus;
using JasperFx.Core;
using Microsoft.Extensions.Hosting;
using Oakton.Resources;
using TestMessages;
using Wolverine.AzureServiceBus.Internal;
using Wolverine.Util;

namespace Wolverine.AzureServiceBus.Tests;

Expand Down Expand Up @@ -95,4 +98,56 @@ public static async Task configure_auto_purge()

#endregion
}
}

public static async Task configure_custom_mappers()
{
#region sample_configuring_custom_envelope_mapper_for_azure_service_bus

using var host = await Host.CreateDefaultBuilder()
.UseWolverine(opts =>
{
opts.UseAzureServiceBus("some connection string")
.UseConventionalRouting()

.ConfigureListeners(l => l.InteropWith(new CustomAzureServiceBusMapper()))

.ConfigureSenders(s => s.InteropWith(new CustomAzureServiceBusMapper()));
}).StartAsync();

#endregion
}
}



#region sample_custom_azure_service_bus_mapper

public class CustomAzureServiceBusMapper : IAzureServiceBusEnvelopeMapper
{
public void MapEnvelopeToOutgoing(Envelope envelope, ServiceBusMessage outgoing)
{
outgoing.Body = new BinaryData(envelope.Data);
if (envelope.DeliverWithin != null)
{
outgoing.TimeToLive = envelope.DeliverWithin.Value;
}
}

public void MapIncomingToEnvelope(Envelope envelope, ServiceBusReceivedMessage incoming)
{
envelope.Data = incoming.Body.ToArray();

// You will have to help Wolverine out by either telling Wolverine
// what the message type is, or by reading the actual message object,
// or by telling Wolverine separately what the default message type
// is for a listening endpoint
envelope.MessageType = typeof(Message1).ToMessageTypeName();
}

public IEnumerable<string> AllHeaders()
{
yield break;
}
}

#endregion
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,15 @@ public AzureServiceBusQueueListenerConfiguration RequireSessions(int? listenerCo

return this;
}

/// <summary>
/// Utilize custom envelope mapping for Amazon Service Bus interoperability with external non-Wolverine systems
/// </summary>
/// <param name="mapper"></param>
/// <returns></returns>
public AzureServiceBusQueueListenerConfiguration InteropWith(IAzureServiceBusEnvelopeMapper mapper)
{
add(e => e.Mapper = mapper);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,15 @@ public AzureServiceBusQueueSubscriberConfiguration RequireSessions(int? listener

return this;
}

/// <summary>
/// Utilize custom envelope mapping for Amazon Service Bus interoperability with external non-Wolverine systems
/// </summary>
/// <param name="mapper"></param>
/// <returns></returns>
public AzureServiceBusQueueSubscriberConfiguration InteropWith(IAzureServiceBusEnvelopeMapper mapper)
{
add(e => e.Mapper = mapper);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,15 @@ public AzureServiceBusSubscriptionListenerConfiguration RequireSessions(int? lis

return this;
}

/// <summary>
/// Utilize custom envelope mapping for Amazon Service Bus interoperability with external non-Wolverine systems
/// </summary>
/// <param name="mapper"></param>
/// <returns></returns>
public AzureServiceBusSubscriptionListenerConfiguration InteropWith(IAzureServiceBusEnvelopeMapper mapper)
{
add(e => e.Mapper = mapper);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,15 @@ public AzureServiceBusTopicSubscriberConfiguration ConfigureTopic(Action<CreateT
add(e => configure(e.Options));
return this;
}

/// <summary>
/// Utilize custom envelope mapping for Amazon Service Bus interoperability with external non-Wolverine systems
/// </summary>
/// <param name="mapper"></param>
/// <returns></returns>
public AzureServiceBusTopicSubscriberConfiguration InteropWith(IAzureServiceBusEnvelopeMapper mapper)
{
add(e => e.Mapper = mapper);
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Azure.Messaging.ServiceBus;
using Wolverine.Transports;

namespace Wolverine.AzureServiceBus;

public interface IAzureServiceBusEnvelopeMapper : IEnvelopeMapper<ServiceBusReceivedMessage, ServiceBusMessage>
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,20 @@ protected override bool supportsMode(EndpointMode mode)
}


internal IEnvelopeMapper<ServiceBusReceivedMessage, ServiceBusMessage> BuildMapper(IWolverineRuntime runtime)
internal IAzureServiceBusEnvelopeMapper BuildMapper(IWolverineRuntime runtime)
{
if (Mapper != null) return Mapper;

var mapper = new AzureServiceBusEnvelopeMapper(this, runtime);

return mapper;
}

public abstract Task<ServiceBusSessionReceiver> AcceptNextSessionAsync(CancellationToken cancellationToken);


/// <summary>
/// If specified, applies a custom envelope mapper to this endp[oint
/// </summary>
public IAzureServiceBusEnvelopeMapper? Mapper { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Wolverine.AzureServiceBus.Internal;

internal class AzureServiceBusEnvelopeMapper : EnvelopeMapper<ServiceBusReceivedMessage, ServiceBusMessage>
internal class AzureServiceBusEnvelopeMapper : EnvelopeMapper<ServiceBusReceivedMessage, ServiceBusMessage>, IAzureServiceBusEnvelopeMapper
{
public AzureServiceBusEnvelopeMapper(Endpoint endpoint, IWolverineRuntime runtime) : base(endpoint)
{
Expand Down

0 comments on commit b1ce9c5

Please sign in to comment.