public static Func <RecoverabilityConfig, ErrorContext, RecoverabilityAction> AlwaysMoveToErrors(string errorQueueAddress = "errorQueue")
 {
     return(new RetryPolicy(new[]
     {
         RecoverabilityAction.MoveToError(errorQueueAddress)
     }).Invoke);
 }
예제 #2
0
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            // early decisions and return before custom policy is invoked
            // i.e. all unrecoverable exceptions should always go to customized error queue
            foreach (var exceptionType in config.Failed.UnrecoverableExceptionTypes)
            {
                if (exceptionType.IsInstanceOfType(context.Exception))
                {
                    return(RecoverabilityAction.MoveToError("customErrorQueue"));
                }
            }

            // If it does not make sense to have this message around anymore
            // it can be discarded with a reason.
            if (context.Exception is MyBusinessTimedOutException)
            {
                return(RecoverabilityAction.Discard("Business operation timed out."));
            }

            // override delayed retry decision for custom exception
            // i.e. MyOtherBusinessException should do fixed backoff of 5 seconds
            if (context.Exception is MyOtherBusinessException &&
                context.DelayedDeliveriesPerformed < config.Delayed.MaxNumberOfRetries)
            {
                return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
            }

            // in all other cases No Immediate or Delayed Retries, go to default error queue
            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        }
예제 #3
0
    static async Task <ValidationException> Send(object message, [CallerMemberName] string key = null)
    {
        var configuration = new EndpointConfiguration("DataAnnotationsIncoming" + key);

        configuration.UseTransport <LearningTransport>();
        configuration.PurgeOnStartup(true);
        configuration.DisableFeature <TimeoutManager>();

        var resetEvent = new ManualResetEvent(false);

        configuration.RegisterComponents(components => components.RegisterSingleton(resetEvent));
        ValidationException exception = null;
        var recoverability            = configuration.Recoverability();

        recoverability.CustomPolicy(
            (config, context) =>
        {
            exception = (ValidationException)context.Exception;
            resetEvent.Set();
            return(RecoverabilityAction.MoveToError("error"));
        });
        configuration.UseDataAnnotationsValidation(outgoing: false);

        var endpoint = await Endpoint.Start(configuration);

        await endpoint.SendLocal(message);

        if (!resetEvent.WaitOne(TimeSpan.FromSeconds(2)))
        {
            throw new Exception("No Set received.");
        }

        return(exception);
    }
예제 #4
0
    protected override void Setup(FeatureConfigurationContext context)
    {
        #region DrainTempQueueSatellite

        var settings         = context.Settings;
        var qualifiedAddress = settings.LogicalAddress()
                               .CreateQualifiedAddress("New");
        var tempQueue = settings.GetTransportAddress(qualifiedAddress);
        var mainQueue = settings.LocalAddress();

        context.AddSatelliteReceiver(
            name: "DrainTempQueueSatellite",
            transportAddress: tempQueue,
            runtimeSettings: new PushRuntimeSettings(maxConcurrency: 1),
            recoverabilityPolicy: (config, errorContext) =>
        {
            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        },
            onMessage: (builder, messageContext) =>
        {
            var messageDispatcher = builder.Build <IDispatchMessages>();
            var outgoingHeaders   = messageContext.Headers;

            var outgoingMessage   = new OutgoingMessage(messageContext.MessageId, outgoingHeaders, messageContext.Body);
            var outgoingOperation = new TransportOperation(outgoingMessage, new UnicastAddressTag(mainQueue));

            Console.WriteLine($"Moving message from {tempQueue} to {mainQueue}");

            var transportOperations = new TransportOperations(outgoingOperation);
            return(messageDispatcher.Dispatch(transportOperations, messageContext.TransportTransaction, messageContext.Context));
        });

        #endregion
    }
예제 #5
0
        private static RecoverabilityAction CustomerExceptionPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var unrecover = context.Exception is UnrecoverableException;
            var customer  = context.Exception is CustomerException;

            var immediateIdx = context.ImmediateProcessingFailures;
            var immediateMax = config.Immediate.MaxNumberOfRetries;
            var delayIdx     = context.DelayedDeliveriesPerformed;
            var delayMax     = config.Delayed.MaxNumberOfRetries;

            if (!unrecover && immediateIdx < immediateMax)
            {
                Console.WriteLine($"DelayedRetry {delayIdx}, ImmediateRetry {immediateIdx}");
                return(RecoverabilityAction.ImmediateRetry());
            }

            if (!unrecover && immediateIdx == immediateMax && delayIdx < delayMax)
            {
                Console.WriteLine($"DelayedRetry {delayIdx}");
                return(RecoverabilityAction.DelayedRetry(config.Delayed.TimeIncrease));
            }

            if (customer && delayIdx == delayMax)
            {
                Console.WriteLine("Alert customer exception");
            }

            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        }
예제 #6
0
        static RecoverabilityAction OrderPlacedPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var errorCategory = ErrorCategory.Unknown;

            if (context.Message.Headers.ContainsKey("NServiceBus.EnclosedMessageTypes"))
            {
                if (context.Message.Headers["NServiceBus.EnclosedMessageTypes"].StartsWith("Messages.Commands.PlaceOrder"))
                {
                    errorCategory = FailPolicy.GetPolicy("Messages.Commands.PlaceOrder").GetCategory(context.Exception);
                }
                else if (context.Message.Headers["NServiceBus.EnclosedMessageTypes"].StartsWith("Messages.Commands.CancelOrder"))
                {
                    errorCategory = FailPolicy.GetPolicy("Messages.Commands.CancelOrder").GetCategory(context.Exception);
                }
            }

            if (errorCategory == ErrorCategory.Persistent)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
            else if (errorCategory == ErrorCategory.SemiTransient)
            {
                return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(60)));
            }

            // invocation of default recoverability policy
            return(DefaultRecoverabilityPolicy.Invoke(config, context));
        }
 public RetryEndpoint()
 {
     EndpointSetup <DefaultServer>((configure, context) =>
     {
         configure.Recoverability()
         .CustomPolicy((cfg, errorContext) => RecoverabilityAction.MoveToError(cfg.Failed.ErrorQueue));
     });
 }
            RecoverabilityAction RetryPolicy(RecoverabilityConfig config, ErrorContext context)
            {
                if (context.DelayedDeliveriesPerformed == 0)
                {
                    return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMilliseconds(10)));
                }

                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
예제 #9
0
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            if (context.Exception is MyBusinessException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }

            return(DefaultRecoverabilityPolicy.Invoke(config, context));
        }
예제 #10
0
        public void UseNServiceBusPoisonMessageHandling(string errorQueue)
        {
            endpointConfiguration.Recoverability().CustomPolicy((c, e) =>
            {
                return(RecoverabilityAction.MoveToError(errorQueue));
            });

            moveFailedMessagesToError = true;
        }
예제 #11
0
        static RecoverabilityAction RecoverabilityPolicy(RecoverabilityConfig config, ErrorContext errorContext)
        {
            if (errorContext.ImmediateProcessingFailures <= MaxNumberOfImmediateRetries)
            {
                return(RecoverabilityAction.ImmediateRetry());
            }

            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        }
        private RecoverabilityAction CreateSubjectCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            // In this custom policy, we are electing to move the PoisonedMessages to a different error queue for resolution, so they will use a different error queue to the standard one (so can be monitored easily).
            // You could add whatever logic you liked here to put different messages in different queues.

            return(config.Failed.UnrecoverableExceptionTypes.Count(exType => exType.IsInstanceOfType(context.Exception)) > 0
                ? RecoverabilityAction.MoveToError("customErrorQueue")
                : DefaultRecoverabilityPolicy.Invoke(config, context));
        }
예제 #13
0
            public EndpointWithFailingHandler()
            {
                EndpointSetup <DefaultServer>((config, context) =>
                {
                    config.Recoverability().CustomPolicy((c, ec) =>
                                                         RecoverabilityAction.MoveToError(Conventions.EndpointNamingConvention(typeof(ErrorSpy))));

                    config.SendFailedMessagesTo("error");
                });
            }
 public RetryEndpoint()
 {
     EndpointSetup <DefaultServer>((configure, context) =>
     {
         var scenarioContext = (Context)context.ScenarioContext;
         configure.EnableFeature <TimeoutManager>();
         configure.Recoverability()
         .CustomPolicy((cfg, errorContext) => RecoverabilityAction.MoveToError(cfg.Failed.ErrorQueue));
         configure.Notifications.Errors.MessageSentToErrorQueue += (sender, message) => { scenarioContext.MessageSentToErrorQueue = true; };
     });
 }
        public static RecoverabilityAction Invoke(ErrorContext errorContext, Func <IncomingMessage, Exception, int, TimeSpan> retryPolicy, RecoverabilityConfig config)
        {
            var currentRetry = errorContext.DelayedDeliveriesPerformed + 1;
            var timeIncrease = retryPolicy(errorContext.Message, errorContext.Exception, currentRetry);

            if (timeIncrease <= TimeSpan.MinValue)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
            return(RecoverabilityAction.DelayedRetry(timeIncrease));
        }
 protected override void Setup(FeatureConfigurationContext context)
 {
     context.AddSatelliteReceiver(
         name: "CustomSatellite",
         transportAddress: "targetQueue",
         runtimeSettings: PushRuntimeSettings.Default,
         recoverabilityPolicy: (config, errorContext) =>
     {
         return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
     },
         onMessage: OnMessage);
 }
예제 #17
0
        public static RecoverabilityAction UserServiceRetryPolicyInvoke(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            if (!(action is DelayedRetry))
            {
                return(action);
            }
            if (context.Exception is NullReferenceException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMinutes(3)));
        }
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            if (!(action is DelayedRetry delayedRetryAction))
            {
                return(action);
            }
            if (context.Exception is MyBusinessException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
            // Override default delivery delay.
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
        }
예제 #19
0
        public void MoveToError(FeatureConfigurationContext context)
        {
            #region SatelliteRecoverability-ErrorQueue

            context.AddSatelliteReceiver(
                name: "CustomSatellite",
                transportAddress: "targetQueue",
                requiredTransportTransactionMode: TransportTransactionMode.TransactionScope,
                runtimeSettings: PushRuntimeSettings.Default,
                recoverabilityPolicy: (config, errorContext) =>
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            },
                onMessage: OnMessage);

            #endregion
        }
            public Endpoint()
            {
                EndpointSetup <DefaultServer>((config, context) =>
                {
                    var testContext = (Context)context.ScenarioContext;

                    config.Recoverability()
                    .Immediate(immediate => immediate.NumberOfRetries(MaxImmediateRetries))
                    .Delayed(delayed => delayed.NumberOfRetries(MaxDelayedRetries).TimeIncrease(DelayedRetryDelayIncrease))
                    .CustomPolicy((cfg, errorContext) =>
                    {
                        testContext.Configuration = cfg;

                        return(RecoverabilityAction.MoveToError(cfg.Failed.ErrorQueue));
                    });
                });
            }
예제 #21
0
                protected override void Setup(FeatureConfigurationContext context)
                {
                    var satelliteLogicalAddress = context.Settings.LogicalAddress().CreateQualifiedAddress("MySatellite");
                    var satelliteAddress        = context.Settings.GetTransportAddress(satelliteLogicalAddress);

                    context.AddSatelliteReceiver("Test satellite", satelliteAddress, PushRuntimeSettings.Default,
                                                 (c, ec) => RecoverabilityAction.MoveToError(c.Failed.ErrorQueue),
                                                 (builder, messageContext) =>
                    {
                        var testContext             = builder.Build <Context>();
                        testContext.MessageReceived = true;
                        testContext.TransportTransactionAddedToContext = ReferenceEquals(messageContext.Extensions.Get <TransportTransaction>(), messageContext.TransportTransaction);
                        return(Task.FromResult(true));
                    });

                    Address = satelliteAddress;
                }
    protected override void Setup(FeatureConfigurationContext context)
    {
        var settings = context.Settings;

        tempQueue = "Samples.SagaMigration.Server.New";
        mainQueue = settings.LocalAddress();

        context.AddSatelliteReceiver(
            name: "DrainTempQueueSatellite",
            transportAddress: tempQueue,
            runtimeSettings: new PushRuntimeSettings(maxConcurrency: 1),
            recoverabilityPolicy: (config, errorContext) =>
        {
            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        },
            onMessage: OnMessage);
    }
                protected override void Setup(FeatureConfigurationContext context)
                {
                    var satelliteLogicalAddress = context.Settings.LogicalAddress().CreateQualifiedAddress("MySatellite");
                    var satelliteAddress        = context.Settings.GetTransportAddress(satelliteLogicalAddress);

#pragma warning disable 612, 618
                    context.AddSatelliteReceiver("Test satellite", satelliteAddress, TransportTransactionMode.None, PushRuntimeSettings.Default,
                                                 (c, ec) => RecoverabilityAction.MoveToError(c.Failed.ErrorQueue),
                                                 (builder, pushContext) =>
                    {
                        var testContext             = builder.Build <Context>();
                        testContext.MessageReceived = true;
                        return(Task.FromResult(true));
                    });
#pragma warning restore 612, 618

                    Address = satelliteAddress;
                }
예제 #24
0
 public RecoverabilityAction WebhookRetryPolicy(RecoverabilityConfig config, ErrorContext context)
 {
     if (context.Exception is WebhookExceptionRetryPerPolicy)
     {
         // Check that the number of delayed deliveries does not exceed configurable webhook retry count
         if (context.DelayedDeliveriesPerformed < ConfigHelper.WebhookRetryCount)
         {
             // Set delayed retry internal to that set by the configurable webhook retry internal
             return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(ConfigHelper.WebhookRetryInterval)));
         }
         // If the webhook could not be delivered within the specified number of retry attempts. Log error and send to ErrorQueue
         string errorMsg = $"Failed to send webhook after {context.DelayedDeliveriesPerformed} attempts.";
         Log.Error(errorMsg);
         return(RecoverabilityAction.MoveToError(errorMsg));
     }
     // For all other exceptions, fall back to default policy
     return(DefaultRecoverabilityPolicy.Invoke(config, context));
 }
예제 #25
0
    protected override void Setup(FeatureConfigurationContext context)
    {
        var settings         = context.Settings;
        var qualifiedAddress = settings.LogicalAddress()
                               .CreateQualifiedAddress("New");

        tempQueue = settings.GetTransportAddress(qualifiedAddress);
        mainQueue = settings.LocalAddress();

        context.AddSatelliteReceiver(
            name: "DrainTempQueueSatellite",
            transportAddress: tempQueue,
            runtimeSettings: new PushRuntimeSettings(maxConcurrency: 1),
            recoverabilityPolicy: (config, errorContext) =>
        {
            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        },
            onMessage: OnMessage);
    }
                protected override void Setup(FeatureConfigurationContext context)
                {
                    var endpointQueueName = context.Settings.EndpointQueueName();
                    var queueAddress      = new QueueAddress(endpointQueueName, null, null, "MySatellite");

                    var satelliteAddress = context.Settings.Get <TransportDefinition>().ToTransportAddress(queueAddress);

                    context.AddSatelliteReceiver("Test satellite", satelliteAddress, PushRuntimeSettings.Default,
                                                 (c, ec) => RecoverabilityAction.MoveToError(c.Failed.ErrorQueue),
                                                 (builder, messageContext, cancellationToken) =>
                    {
                        var testContext             = builder.GetService <Context>();
                        testContext.MessageReceived = true;
                        testContext.TransportTransactionAddedToContext = ReferenceEquals(messageContext.Extensions.Get <TransportTransaction>(), messageContext.TransportTransaction);
                        return(Task.FromResult(true));
                    });

                    Address = satelliteAddress;
                }
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            // early decisions and return before custom policy is invoked
            // i.e. MyBusinessException should always go to customized error queue
            if (context.Exception is MyBusinessException)
            {
                return(RecoverabilityAction.MoveToError("customErrorQueue"));
            }

            // override delayed retry decision for custom exception
            // i.e. MyOtherBusinessException should do fixed backoff of 5 seconds
            if (context.Exception is MyOtherBusinessException && context.DelayedDeliveriesPerformed <= config.Delayed.MaxNumberOfRetries)
            {
                return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
            }

            // in all other cases No Immediate or Delayed Retries, go to default error queue
            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        }
        public RecoverabilityAction Retry(RecoverabilityConfig recoverabilityConfig, ErrorContext errorContext)
        {
            if (errorContext.Exception is OptimisticConcurrencyException)
            {
                var ttl = errorContext.Message.Headers[
                    ApplicationConfiguration.Instance.GetValue <string>(
                        "ProductService:RetryPolicy:HeaderNames:UpdateStockInProduct")];

                if (Convert.ToInt32(ttl) == 0)
                {
                    return(RecoverabilityAction.MoveToError(recoverabilityConfig.Failed.ErrorQueue));
                }

                //TODO:Kudret--> Beklediğim bir senaryo, bu yüzden immediate olarak retry etsin
                return(RecoverabilityAction.ImmediateRetry());
            }

            return(DefaultRecoverabilityPolicy.Invoke(recoverabilityConfig, errorContext));
        }
예제 #29
0
        public static RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            // If not a retry then continue
            if (!(action is DelayedRetry delayedRetryAction))
            {
                return(action);
            }

            // Check for concrete exception or business custom exception
            if (context.Exception is InvalidCastException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }

            // Override default delivery delay.
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
        }
            public Endpoint()
            {
                EndpointSetup <DefaultServer>((config, context) =>
                {
                    var testContext = (Context)context.ScenarioContext;

                    config.Recoverability()
                    .CustomPolicy((cfg, errorContext) =>
                    {
                        testContext.ErrorContexts.Add(errorContext);

                        if (errorContext.DelayedDeliveriesPerformed >= 1)
                        {
                            return(RecoverabilityAction.MoveToError(cfg.Failed.ErrorQueue));
                        }

                        return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMilliseconds(1)));
                    });
                });
            }