-
Notifications
You must be signed in to change notification settings - Fork 10
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 #24 from KatoStoelen/send-only-interfaces
Implement send-only interfaces
- Loading branch information
Showing
7 changed files
with
234 additions
and
5 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
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
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
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
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
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,69 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using NServiceBus; | ||
using NServiceBus.Router; | ||
using NServiceBus.Configuration.AdvancedExtensibility; | ||
using NServiceBus.Raw; | ||
using NServiceBus.Transport; | ||
|
||
class SendOnlyInterface<T> : Interface where T : TransportDefinition, new() | ||
{ | ||
public SendOnlyInterface(string endpointName, string interfaceName, Action<TransportExtensions<T>> transportCustomization, Func<IRawEndpoint, IRuleCreationContext> ruleCreationContextFactory) | ||
{ | ||
this.ruleCreationContextFactory = ruleCreationContextFactory; | ||
Name = interfaceName; | ||
|
||
config = RawEndpointConfiguration.CreateSendOnly(endpointName); | ||
var transport = config.UseTransport<T>(); | ||
SetTransportSpecificFlags(transport.GetSettings()); | ||
transportCustomization?.Invoke(transport); | ||
} | ||
|
||
public string Name { get; } | ||
|
||
static void SetTransportSpecificFlags(NServiceBus.Settings.SettingsHolder settings) | ||
{ | ||
settings.Set("RabbitMQ.RoutingTopologySupportsDelayedDelivery", true); | ||
} | ||
|
||
public async Task Initialize(InterfaceChains interfaces, RootContext rootContext) | ||
{ | ||
startable = await RawEndpoint.Create(config).ConfigureAwait(false); | ||
config = null; | ||
var ruleCreationContext = ruleCreationContextFactory(startable); | ||
interfaces.InitializeInterface(Name, ruleCreationContext); | ||
} | ||
|
||
public async Task StartReceiving() | ||
{ | ||
receiver = await startable.Start().ConfigureAwait(false); | ||
} | ||
|
||
public async Task StopReceiving() | ||
{ | ||
if (receiver != null) | ||
{ | ||
stoppable = await receiver.StopReceiving().ConfigureAwait(false); | ||
} | ||
else | ||
{ | ||
stoppable = null; | ||
} | ||
} | ||
|
||
public async Task Stop() | ||
{ | ||
if (stoppable != null) | ||
{ | ||
await stoppable.Stop().ConfigureAwait(false); | ||
stoppable = null; | ||
} | ||
} | ||
|
||
RawEndpointConfiguration config; | ||
IStartableRawEndpoint startable; | ||
IReceivingRawEndpoint receiver; | ||
IStoppableRawEndpoint stoppable; | ||
|
||
Func<IRawEndpoint, IRuleCreationContext> ruleCreationContextFactory; | ||
} |
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,99 @@ | ||
namespace NServiceBus.Router | ||
{ | ||
using System; | ||
using Raw; | ||
using Routing; | ||
using Transport; | ||
using Unicast.Subscriptions.MessageDrivenSubscriptions; | ||
|
||
/// <summary> | ||
/// Configures the switch port. | ||
/// </summary> | ||
/// <typeparam name="T">Type of transport.</typeparam> | ||
public class SendOnlyInterfaceConfiguration<T> | ||
where T : TransportDefinition, new() | ||
{ | ||
Action<TransportExtensions<T>> customization; | ||
string overriddenEndpointName; | ||
|
||
/// <summary> | ||
/// Interface's extensibility settings. | ||
/// </summary> | ||
public SettingsHolder Settings { get; } = new SettingsHolder(); | ||
|
||
/// <summary> | ||
/// Name of the interface. | ||
/// </summary> | ||
public string Name { get; } | ||
|
||
/// <summary> | ||
/// Router's configuration. | ||
/// </summary> | ||
public RouterConfiguration RouterConfiguration { get; } | ||
|
||
internal SendOnlyInterfaceConfiguration(string name, Action<TransportExtensions<T>> customization, RouterConfiguration routerConfiguration) | ||
{ | ||
Name = name; | ||
this.customization = customization; | ||
RouterConfiguration = routerConfiguration; | ||
} | ||
|
||
/// <summary> | ||
/// Adds a global (applicable to all interfaces) routing rule. | ||
/// </summary> | ||
/// <typeparam name="TRule">Type of the rule.</typeparam> | ||
/// <param name="constructor">Delegate that constructs a new instance of the rule.</param> | ||
/// <param name="condition">Condition which must be true for the rule to be added to the chain.</param> | ||
public void AddRule<TRule>(Func<IRuleCreationContext, TRule> constructor, Func<IRuleCreationContext, bool> condition = null) | ||
where TRule : IRule | ||
{ | ||
RouterConfiguration.AddRule(constructor, context => | ||
{ | ||
if (condition == null) | ||
{ | ||
return context.InterfaceName == Name; | ||
} | ||
return condition(context) && context.InterfaceName == Name; | ||
}); | ||
} | ||
|
||
/// <summary> | ||
/// Configures the port to use specified subscription persistence. | ||
/// </summary> | ||
[Obsolete("Use EnableMessageDrivenPublishSubscribe instead.")] | ||
public void UseSubscriptionPersistence(ISubscriptionStorage subscriptionStorage) | ||
{ | ||
this.EnableMessageDrivenPublishSubscribe(subscriptionStorage); | ||
} | ||
|
||
/// <summary> | ||
/// Overrides the interface endpoint name. | ||
/// </summary> | ||
/// <param name="interfaceEndpointName">Endpoint name to use for this interface instead of Router's name</param> | ||
public void OverrideEndpointName(string interfaceEndpointName) | ||
{ | ||
overriddenEndpointName = interfaceEndpointName; | ||
} | ||
|
||
/// <summary> | ||
/// Distribution policy of the port. | ||
/// </summary> | ||
public RawDistributionPolicy DistributionPolicy { get; } = new RawDistributionPolicy(); | ||
|
||
/// <summary> | ||
/// Physical routing settings of the port. | ||
/// </summary> | ||
public EndpointInstances EndpointInstances { get; } = new EndpointInstances(); | ||
|
||
internal Interface Create(string endpointName, RuntimeTypeGenerator typeGenerator, SettingsHolder routerSettings) | ||
{ | ||
IRuleCreationContext ContextFactory(IRawEndpoint e) | ||
{ | ||
Settings.Merge(routerSettings); | ||
return new RuleCreationContext(Name, EndpointInstances, DistributionPolicy, e, typeGenerator, Settings); | ||
} | ||
|
||
return new SendOnlyInterface<T>(overriddenEndpointName ?? endpointName, Name, customization, ContextFactory); | ||
} | ||
} | ||
} |