Esempio n. 1
0
    /// <summary>
    /// Adds an <see cref="ExactlyOnceMiddleware{T}"/> to the current pipeline.
    /// </summary>
    /// <param name="builder">The current <see cref="HandlerMiddlewareBuilder"/>.</param>
    /// <param name="lockKey">A unique key to identify this lock, e.g. the name of the handler.</param>
    /// <param name="lockDuration">The length of time to lock messages while handling them.</param>
    /// <typeparam name="TMessage">The type of the message that should be locked.</typeparam>
    /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
    public static HandlerMiddlewareBuilder UseExactlyOnce <TMessage>(
        this HandlerMiddlewareBuilder builder,
        string lockKey,
        TimeSpan?lockDuration = null)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }
        if (string.IsNullOrEmpty(lockKey))
        {
            throw new ArgumentException("Parameter cannot be null or empty.", nameof(lockKey));
        }

        HandleMessageMiddleware CreateMiddleware()
        {
            var messageLock = builder.ServiceResolver.ResolveService <IMessageLockAsync>();
            var logger      = builder.ServiceResolver.ResolveService <ILogger <ExactlyOnceMiddleware <TMessage> > >();

            return(new ExactlyOnceMiddleware <TMessage>(messageLock,
                                                        lockDuration ?? TimeSpan.MaxValue,
                                                        lockKey,
                                                        logger));
        }

        builder.Use(CreateMiddleware);

        return(builder);
    }
        public static HandlerMiddlewareBuilder UseMessageContextAccessor(this HandlerMiddlewareBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            var contextAccessor = builder.ServiceResolver.ResolveService <IMessageContextAccessor>();

            return(builder.Use(new MessageContextAccessorMiddleware(contextAccessor)));
        }
Esempio n. 3
0
    /// <summary>
    /// Adds an error handler to the pipeline that will call methods on the  the <see cref="IMessageMonitor"/>
    /// registered in services.
    /// </summary>
    /// <param name="builder">The <see cref="HandlerMiddlewareBuilder"/> to add the middleware to.</param>
    /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
    /// <exception cref="ArgumentNullException">When the <see cref="HandlerMiddlewareBuilder"/> is null.</exception>
    public static HandlerMiddlewareBuilder UseErrorHandler(this HandlerMiddlewareBuilder builder)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        IMessageMonitor monitor = builder.ServiceResolver.ResolveService <IMessageMonitor>();

        return(builder.Use(new ErrorHandlerMiddleware(monitor)));
    }
Esempio n. 4
0
    /// <summary>
    /// Adds a <see cref="StopwatchMiddleware"/> to the current pipeline.
    /// </summary>
    /// <param name="builder">The current <see cref="HandlerMiddlewareBuilder"/>.</param>
    /// <param name="handlerType">The type of the handler that results should be reported against.</param>
    /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="builder"/> is <see langword="null"/>.
    /// </exception>
    public static HandlerMiddlewareBuilder UseStopwatch(
        this HandlerMiddlewareBuilder builder,
        Type handlerType)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        IMessageMonitor monitor = builder.ServiceResolver.ResolveService <IMessageMonitor>();

        return(builder.Use(new StopwatchMiddleware(monitor, handlerType)));
    }
Esempio n. 5
0
    /// <summary>
    /// <para>
    /// Applies a set of default middlewares in order. Adding other middlewares before this will add them
    /// to the top of the stack, and are run first and last.
    /// Adding other middleware after this will add them to the bottom of the stack, just before the
    /// handler itself is invoked.
    /// </para>
    /// The middlewares this adds are, in order:
    /// <list type="bullet">
    /// <item>MessageContextAccessorMiddleware</item>
    /// <item>BackoffMiddleware (only if an <see cref="IMessageBackoffStrategy"/> is available)</item>
    /// <item>ErrorHandlerMiddleware</item>
    /// <item>LoggingMiddleware</item>
    /// <item>StopwatchMiddleware</item>
    /// <item>SqsPostProcessorMiddleware</item>
    /// <item>HandlerInvocationMiddleware`1</item>
    /// </list>
    /// </summary>
    /// <param name="builder">The <see cref="HandlerMiddlewareBuilder"/> builder to add these defaults to.</param>
    /// <param name="handlerType">The type of the handler that will handle messages for this middleware pipeline.
    /// This is used when recording handler execution time with the StopwatchMiddleware.</param>
    /// <typeparam name="TMessage">The type of the message that this middleware pipeline handles.</typeparam>
    /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
    public static HandlerMiddlewareBuilder UseDefaults <TMessage>(
        this HandlerMiddlewareBuilder builder,
        Type handlerType)
        where TMessage : Message
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }
        if (handlerType == null)
        {
            throw new ArgumentNullException(nameof(handlerType), "HandlerType is used here to");
        }

        builder.UseMessageContextAccessor();
        builder.UseErrorHandler();
        builder.Use <LoggingMiddleware>();
        builder.UseStopwatch(handlerType);
        builder.Use <SqsPostProcessorMiddleware>();
        builder.UseHandler <TMessage>();

        return(builder);
    }
Esempio n. 6
0
    /// <summary>
    /// Adds a <see cref="HandlerInvocationMiddleware{T}"/> to the current pipeline.
    /// </summary>
    /// <param name="builder">The current <see cref="HandlerMiddlewareBuilder"/>.</param>
    /// <param name="handler">A factory that creates <see cref="IHandlerAsync{T}"/> instances from
    /// a <see cref="HandlerResolutionContext"/>.</param>
    /// <typeparam name="TMessage">The type of the message that should be handled</typeparam>
    /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
    /// <exception cref="ArgumentNullException">
    /// <paramref name="builder"/> or <paramref name="handler"/> is <see langword="null"/>.
    /// </exception>
    public static HandlerMiddlewareBuilder UseHandler <TMessage>(
        this HandlerMiddlewareBuilder builder,
        Func <HandlerResolutionContext, IHandlerAsync <TMessage> > handler) where TMessage : Message
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }
        if (handler == null)
        {
            throw new ArgumentNullException(nameof(handler));
        }

        return(builder.Use(new HandlerInvocationMiddleware <TMessage>(handler)));
    }
Esempio n. 7
0
        /// <summary>
        /// If an <see cref="IMessageBackoffStrategy"/> has been registered in services, then this will create
        /// a <see cref="BackoffMiddleware"/> and add it to the pipeline.
        /// </summary>
        /// <param name="builder">The <see cref="HandlerMiddlewareBuilder"/> to add the middleware to.</param>
        /// <param name="backoffStrategy">The <see cref="IMessageBackoffStrategy"/> to use to determine message visibility timeouts.</param>
        /// <returns>The current <see cref="HandlerMiddlewareBuilder"/>.</returns>
        /// <exception cref="ArgumentNullException">When the <see cref="HandlerMiddlewareBuilder"/> is null.</exception>
        public static HandlerMiddlewareBuilder UseBackoff(this HandlerMiddlewareBuilder builder, IMessageBackoffStrategy backoffStrategy)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            if (backoffStrategy == null)
            {
                throw new ArgumentNullException(nameof(backoffStrategy));
            }

            var loggerFactory = builder.ServiceResolver.ResolveService <ILoggerFactory>();
            var monitor       = builder.ServiceResolver.ResolveService <IMessageMonitor>();

            return(builder.Use(new BackoffMiddleware(backoffStrategy, loggerFactory, monitor)));
        }