/// <summary> /// Adds a web host for the given <paramref name="listenUrl"/> using the given <paramref name="startup"/> action /// </summary> public static void AddWebHost(this OptionsConfigurer configurer, string listenUrl, Action <IAppBuilder> startup) { if (!configurer.Has <RebusWebHost>()) { configurer.Register(c => { var rebusLoggerFactory = c.Get <IRebusLoggerFactory>(); return(new RebusWebHost(rebusLoggerFactory)); }); configurer.Decorate(c => { // make the Injectionist track the web host c.Get <RebusWebHost>(); // it will be initialized when resolving the bus return(c.Get <IBus>()); }); } configurer.Decorate(c => { var rebusWebHost = c.Get <RebusWebHost>(); rebusWebHost.AddEndpoint(listenUrl, startup); return(rebusWebHost); }); }
/// <summary> /// Makes Rebus "legacy compatible", i.e. enables wire-level compatibility with older Rebus versions. WHen this is enabled, /// all endpoints need to be old Rebus endpoints or new Rebus endpoints with this feature enabled /// </summary> public static void EnableLegacyCompatibility(this OptionsConfigurer configurer) { configurer.Register <ISerializer>(c => { var specialSettings = LegacySubscriptionMessagesBinder.JsonSerializerSettings; var legacyEncoding = Encoding.UTF7; var jsonSerializer = new JsonSerializer(specialSettings, legacyEncoding); return(jsonSerializer); }); configurer.Decorate(c => { var pipeline = c.Get <IPipeline>(); // map headers of incoming message from v1 to v2 pipeline = new PipelineStepConcatenator(pipeline) .OnReceive(new MapLegacyHeadersIncomingStep(), PipelineAbsolutePosition.Front); // unpack object[] of transport message pipeline = new PipelineStepInjector(pipeline) .OnReceive(new UnpackLegacyMessageIncomingStep(), PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep)); // pack into object[] pipeline = new PipelineStepInjector(pipeline) .OnSend(new PackLegacyMessageOutgoingStep(), PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep)); pipeline = new PipelineStepInjector(pipeline) .OnSend(new MapLegacyHeadersOutgoingStep(), PipelineRelativePosition.Before, typeof(SendOutgoingMessageStep)); //pipeline = new PipelineStepInjector(pipeline) // .OnReceive(new HandleLegacySubscriptionRequestIncomingStep(c.Get<ISubscriptionStorage>(), c.Get<LegacySubscriptionMessageSerializer>()), PipelineRelativePosition.Before, typeof(MapLegacyHeadersIncomingStep)); return(pipeline); }); configurer.Decorate(c => { var transport = c.Get <ITransport>(); if (transport is MsmqTransport) { c.Get <IRebusLoggerFactory>() .GetCurrentClassLogger() .Info("MSMQ transport detected - changing to UTF7 for serialized message header encoding"); ((MsmqTransport)transport).UseLegacyHeaderSerialization(); } return(transport); }); }
/// <summary> /// Configures Rebus to execute handlers inside a <see cref="TransactionScope"/> /// </summary> public static OptionsConfigurer HandleMessagesInsideTransactionScope(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => new PipelineStepInjector(c.Get <IPipeline>()) .OnReceive(new TransactionScopeIncomingStep(), PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep))); return(configurer); }
public static void ValidateOneWayClient(this OptionsConfigurer options) { options.Decorate(c => { // only validate this if a transport has been configured - otherwise, Rebus' normal validation will let the user know :) if (c.Has <ITransport>()) { var transport = c.Get <ITransport>(); var address = transport.Address; // if the transport address is not NULL, it has been configured with an input queue! if (address != null) { throw new InvalidOperationException( $@" Tried to configure the transport with input queue name '{address}', but it's not possible for a one-way client to have an input queue! Please either use one of the .Transport(t => t.Use***AsOneWayClient(..)) configuration methods when you're using Configure.OneWayClient() to configure Rebus or pass a handler activator by calling Configure.With(activator) to configure Rebus, where activator is either the BuiltinHandlerActivator or a container adapter "); } } return(c.Get <Options>()); }); }
/// <summary> /// Enables the data bus /// </summary> public static StandardConfigurer <IDataBusStorage> EnableDataBus(this OptionsConfigurer configurer) { if (configurer == null) { throw new ArgumentNullException(nameof(configurer)); } configurer.Register <IDataBus>(c => { var dataBusStorage = GetDataBusStorage(c); return(new DefaultDataBus(dataBusStorage)); }); configurer.Decorate <IPipeline>(c => { var dataBusStorage = GetDataBusStorage(c); var pipeline = c.Get <IPipeline>(); var step = new DataBusIncomingStep(dataBusStorage); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep))); }); return(StandardConfigurer <IDataBusStorage> .GetConfigurerFrom(configurer)); }
/// <summary> /// Configures the simple retry strategy, using the specified error queue address and number of delivery attempts /// </summary> /// <param name="optionsConfigurer">(extension method target)</param> /// <param name="errorQueueAddress">Specifies the name of the error queue</param> /// <param name="maxDeliveryAttempts">Specifies how many delivery attempts should be made before forwarding a failed message to the error queue</param> /// <param name="secondLevelRetriesEnabled">Specifies whether second level retries should be enabled - when enabled, the message will be dispatched wrapped in an <see cref="IFailed{TMessage}"/> after the first <paramref name="maxDeliveryAttempts"/> delivery attempts, allowing a different handler to handle the message. Dispatch of the <see cref="IFailed{TMessage}"/> is subject to the same <paramref name="maxDeliveryAttempts"/> delivery attempts</param> /// <param name="errorDetailsHeaderMaxLength">Specifies a MAX length of the error details to be enclosed as the <see cref="Headers.ErrorDetails"/> header. As the enclosed error details can sometimes become very long (especially when using many delivery attempts), depending on the transport's capabilities it might sometimes be necessary to truncate the error details</param> public static void SimpleRetryStrategy(this OptionsConfigurer optionsConfigurer, string errorQueueAddress = SimpleRetryStrategySettings.DefaultErrorQueueName, int maxDeliveryAttempts = SimpleRetryStrategySettings.DefaultNumberOfDeliveryAttempts, bool secondLevelRetriesEnabled = false, int errorDetailsHeaderMaxLength = int.MaxValue) { if (optionsConfigurer == null) { throw new ArgumentNullException(nameof(optionsConfigurer)); } optionsConfigurer.Register(c => new SimpleRetryStrategySettings(errorQueueAddress, maxDeliveryAttempts, secondLevelRetriesEnabled, errorDetailsHeaderMaxLength)); if (secondLevelRetriesEnabled) { optionsConfigurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var errorTracker = c.Get <IErrorTracker>(); var incomingStep = new FailedMessageWrapperStep(errorTracker); var outgoingStep = new VerifyCannotSendFailedMessageWrapperStep(); return(new PipelineStepInjector(pipeline) .OnReceive(incomingStep, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep)) .OnSend(outgoingStep, PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep))); }); } }
public static void EnableOpenTelemetry(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new OutgoingDiagnosticsStep(); return(new PipelineStepInjector(pipeline).OnSend(step, PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep))); }); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new IncomingDiagnosticsStep(); return(new PipelineStepInjector(pipeline).OnReceive(step, PipelineRelativePosition.Before, typeof(DeserializeIncomingMessageStep))); }); }
static void EnableThrowingStep(OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnReceive(new ThrowingStep(), PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep))); }); }
/// <summary> /// Enables compression of outgoing messages if the size exceeds the specified number of bytes /// (defaults to <see cref="DefaultBodyThresholdBytes"/>) /// </summary> public static void EnableCompression(this OptionsConfigurer configurer, int bodySizeThresholdBytes = DefaultBodyThresholdBytes) { if (configurer == null) { throw new ArgumentNullException(nameof(configurer)); } configurer.Decorate <ISerializer>(c => new ZippingSerializerDecorator(c.Get <ISerializer>(), new Zipper(), bodySizeThresholdBytes)); }
public static void OnPipelineCompletion <TMessage>(this OptionsConfigurer configurer, Action <TMessage> onReceived) { configurer.Decorate <IPipeline>(ctx => { IPipeline pipeline = ctx.Get <IPipeline>(); return(new PipelineStepConcatenator(pipeline) .OnReceive(new TrackPipelineCompletionStep <TMessage>(null, onReceived), PipelineAbsolutePosition.Front)); }); }
/// <summary> /// Enables compression of outgoing messages if the size exceeds the specified number of bytes /// (defaults to <see cref="DefaultBodyThresholdBytes"/>) /// </summary> public static void EnableCompression(this OptionsConfigurer configurer, int bodySizeThresholdBytes = DefaultBodyThresholdBytes) { configurer.Register(c => new Zipper()); configurer.Register(c => new UnzipMessagesIncomingStep(c.Get <Zipper>())); configurer.Register(c => new ZipMessagesOutgoingStep(c.Get <Zipper>(), bodySizeThresholdBytes)); configurer.Decorate <IPipeline>(c => new PipelineStepInjector(c.Get <IPipeline>()) .OnReceive(c.Get <UnzipMessagesIncomingStep>(), PipelineRelativePosition.Before, typeof(DeserializeIncomingMessageStep)) .OnSend(c.Get <ZipMessagesOutgoingStep>(), PipelineRelativePosition.After, typeof(SerializeOutgoingMessageStep))); }
public static void AddInProcessMessageInspector(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new InProcessMessageInspectorStep(); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.Before, typeof(DeserializeIncomingMessageStep))); }); }
public static void ExposeErrorTracker(this OptionsConfigurer configurer) => configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var errorTracker = c.Get <IErrorTracker>(); var step = new ExposeErrorTrackerStep(errorTracker); return(new PipelineStepConcatenator(pipeline) .OnReceive(step, PipelineAbsolutePosition.Front)); });
public static void EnableSynchronousRequestReply(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new ReplyHandlerStep(Messages); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.Before, typeof(ActivateHandlersStep))); }); }
/// <summary> /// Configures Rebus to encrypt outgoing messages and be able to decrypt incoming messages. Please note that it's only the message bodies that are /// encrypted, thus everything included in the message headers will be visible to eavesdroppers. /// </summary> public static void EnableEncryption(this OptionsConfigurer configurer, string key) { configurer.Register(c => new Encryptor(key)); configurer.Register(c => new EncryptMessagesOutgoingStep(c.Get <Encryptor>())); configurer.Register(c => new DecryptMessagesIncomingStep(c.Get <Encryptor>())); configurer.Decorate <IPipeline>(c => new PipelineStepInjector(c.Get <IPipeline>()) .OnReceive(c.Get <DecryptMessagesIncomingStep>(), PipelineRelativePosition.Before, typeof(DeserializeIncomingMessageStep)) .OnSend(c.Get <EncryptMessagesOutgoingStep>(), PipelineRelativePosition.After, typeof(SerializeOutgoingMessageStep))); }
public static void AddNewRelicIncomingStep(this OptionsConfigurer optionsConfiguration) { optionsConfiguration.Decorate <IPipeline>(context => { var onWorkflowItemCompletedStep = new NewRelicTraceIncomingStep(); var pipeline = context.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnReceive(onWorkflowItemCompletedStep, PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep))); }); }
public static void AutomaticallyFlowUserContext(this OptionsConfigurer configurer, Container container) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new UserFlowStep(container); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep)) .OnSend(step, PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep))); }); }
public static void EnableMyCustomStep(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new MyCustomStep(); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.After, typeof(ActivateHandlersStep))); }); }
/// <inheritdoc cref="EnableCustomEncryption" /> public static StandardConfigurer <IAsyncEncryptor> EnableCustomAsyncEncryption(this OptionsConfigurer configurer) { configurer.Register(c => new EncryptMessagesOutgoingStep(c.Get <IAsyncEncryptor>())); configurer.Register(c => new DecryptMessagesIncomingStep(c.Get <IAsyncEncryptor>())); configurer.Decorate <IPipeline>(c => new PipelineStepInjector(c.Get <IPipeline>()) .OnReceive(c.Get <DecryptMessagesIncomingStep>(), PipelineRelativePosition.Before, typeof(DeserializeIncomingMessageStep)) .OnSend(c.Get <EncryptMessagesOutgoingStep>(), PipelineRelativePosition.After, typeof(SerializeOutgoingMessageStep))); return(StandardConfigurer <IAsyncEncryptor> .GetConfigurerFrom(configurer)); }
/// <summary> /// Configures Rebus to execute handlers inside a <see cref="TransactionScope"/> /// </summary> public static void HandleMessagesInsideTransactionScope(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var stepToInject = new TransactionScopeIncomingStep(); return(new PipelineStepInjector(pipeline) .OnReceive(stepToInject, PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep))); }); }
public static void UseApplicationInsight(this OptionsConfigurer configurer, Container container) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new ApplicationInsightsStep(container); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.After, typeof(FailFastStep)) ); }); }
public static void TransferCorrelationIdFromHttpContextToOutgoingRebusMessages(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = new HttpContextCorrelationIdOutgoingMessagesStep(); return(new PipelineStepInjector(pipeline) .OnSend(step, PipelineRelativePosition.Before, typeof(FlowCorrelationIdStep))); }); }
/// <summary> /// Enables message auditing whereby Rebus will forward to the audit queue a copy of each properly handled message and /// each published message /// </summary> public static StandardConfigurer <ISagaSnapshotStorage> EnableSagaAuditing(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var sagaSnapshotStorage = GetSagaSnapshotStorage(c); var transport = GetTransport(c); return(new PipelineStepInjector(pipeline) .OnReceive(new SaveSagaDataSnapshotStep(sagaSnapshotStorage, transport), PipelineRelativePosition.Before, typeof(LoadSagaDataStep))); }); return(configurer.GetConfigurer <ISagaSnapshotStorage>()); }
/// <summary> /// Decorates the current <see cref="IFailFastChecker"/> with a filter that causes Rebus to fail fast on exceptions of type /// <typeparamref name="TException"/> (optionally also requiring it to satisfy the when <paramref name="when"/>) /// </summary> public static void FailFastOn <TException>(this OptionsConfigurer configurer, Func <TException, bool> when = null) where TException : Exception { if (configurer == null) { throw new ArgumentNullException(nameof(configurer)); } configurer.Decorate <IFailFastChecker>(c => { var failFastChecker = c.Get <IFailFastChecker>(); return(new FailFastOnSpecificExceptionTypeAndPredicate <TException>(failFastChecker, when)); }); }
private static OptionsConfigurer ConfigurePipeline(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(ctx => { IPipeline pipeline = ctx.Get <IPipeline>(); CorrelateOutgoingMessageStep outgoingStep = ctx.Get <CorrelateOutgoingMessageStep>(); CorrelateIncomingMessageStep incomingStep = ctx.Get <CorrelateIncomingMessageStep>(); return(new PipelineStepInjector(pipeline) .OnSend(outgoingStep, PipelineRelativePosition.Before, typeof(FlowCorrelationIdStep)) .OnReceive(incomingStep, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep))); }); return(configurer); }
/// <summary> /// Enables message auditing whereby Rebus will forward to the audit queue a copy of each properly handled message and /// each published message /// </summary> public static void EnableMessageAuditing(this OptionsConfigurer configurer, string auditQueue) { if (configurer == null) { throw new ArgumentNullException(nameof(configurer)); } if (string.IsNullOrWhiteSpace(auditQueue)) { throw new ArgumentNullException(nameof(auditQueue)); } configurer.Register(c => new AuditingHelper(c.Get <ITransport>(), auditQueue, c.Get <IRebusTime>())); configurer.Register(c => new OutgoingAuditingStep(c.Get <AuditingHelper>(), c.Get <ITransport>())); configurer.Decorate <IPipeline>(c => new PipelineStepInjector(c.Get <IPipeline>()) .OnSend(c.Get <OutgoingAuditingStep>(), PipelineRelativePosition.After, typeof(SendOutgoingMessageStep))); configurer.Register(c => new IncomingAuditingStep(c.Get <AuditingHelper>(), c.Get <ITransport>(), c.Get <IRebusTime>())); configurer.Decorate <IPipeline>(c => new PipelineStepInjector(c.Get <IPipeline>()) .OnReceive(c.Get <IncomingAuditingStep>(), PipelineRelativePosition.Before, typeof(DeserializeIncomingMessageStep))); }
public static void UseDistributeTracingFlow(this OptionsConfigurer configurer) { configurer.Decorate <IPipeline>(c => { var outgoingStep = new SetTraceParentOutgoingStep(); var incomingStep = new GetTraceParentIncomingStep(); var pipeline = c.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnReceive(incomingStep, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep)) .OnSend(outgoingStep, PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep))); }); }
/// <summary> /// Configures Rebus to execute handlers inside a <see cref="TransactionScope"/>, using the transaction options /// given by <paramref name="transactionOptions"/> for the transaction scope /// </summary> public static void HandleMessagesInsideTransactionScope(this OptionsConfigurer configurer, TransactionOptions transactionOptions) { if (configurer == null) { throw new ArgumentNullException(nameof(configurer)); } configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var stepToInject = new TransactionScopeIncomingStep(transactionOptions); return(new PipelineStepInjector(pipeline) .OnReceive(stepToInject, PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep))); }); }
public static OptionsConfigurer RegisterOutgoingStep(this OptionsConfigurer configurer, IOutgoingStep stepToInject, PipelineRelativePosition position = PipelineRelativePosition.Before, Type anchorStep = null) { anchorStep = anchorStep ?? typeof(SendOutgoingMessageStep); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); return(new PipelineStepInjector(pipeline) .OnSend(stepToInject, position, anchorStep)); }); return(configurer); }
/// <summary> /// Initiates the configuration of the handler ordering - call <see cref="ReorderingConfiguration.First{THandler}"/> in /// order to specify the handler that will be put first in the pipeline if it is present /// </summary> public static ReorderingConfiguration SpecifyOrderOfHandlers(this OptionsConfigurer configurer) { var configuration = new ReorderingConfiguration(); configurer.Register(c => new HandlerReorderingStep(configuration)); configurer.Decorate <IPipeline>(c => { var pipeline = c.Get <IPipeline>(); var step = c.Get <HandlerReorderingStep>(); return(new PipelineStepInjector(pipeline) .OnReceive(step, PipelineRelativePosition.Before, typeof(DispatchIncomingMessageStep))); }); return(configuration); }