private static IActiveMqBuilder AddAnonymousProducer <TProducer>(this IActiveMqBuilder builder, AnonymousProducerConfiguration producerConfiguration, ServiceLifetime producerLifetime) where TProducer : class
        {
            if (builder.Services.Any(x => x.ServiceType == typeof(TProducer)))
            {
                var message =
                    $"There has already been registered Anonymous Producer with the type '{typeof(TProducer).FullName}'. " +
                    "Typed Anonymous Producer must be unique. " +
                    "Consider using inheritance to create multiple unique types with the same API surface.";
                throw new InvalidOperationException(message);
            }

            builder.Services.AddSingleton(provider =>
            {
                var sendObservable = provider.GetServices <SendObservable>().Single(x => x.Name == builder.Name);
                var logger         = provider.GetService <ILogger <TypedActiveMqAnonymousProducer <TProducer> > >();
                return(new TypedActiveMqAnonymousProducer <TProducer>(logger, async token =>
                {
                    var connection = await provider.GetConnection(builder.Name, token).ConfigureAwait(false);
                    return await connection.CreateAnonymousProducerAsync(producerConfiguration, token).ConfigureAwait(false);
                }, sendObservable));
            });
            builder.Services.AddSingleton <IActiveMqProducer>(provider => provider.GetRequiredService <TypedActiveMqAnonymousProducer <TProducer> >());
            builder.Services.Add(ServiceDescriptor.Describe(typeof(TProducer),
                                                            provider => ActivatorUtilities.CreateInstance <TProducer>(provider, provider.GetRequiredService <TypedActiveMqAnonymousProducer <TProducer> >()),
                                                            producerLifetime));
            return(builder);
        }
Example #2
0
        public static IActiveMqBuilder AddLeaderElection(this IActiveMqBuilder builder, LeaderElectionOptions options = null)
        {
            options ??= new LeaderElectionOptions();
            if (string.IsNullOrWhiteSpace(options.ElectionAddress))
            {
                throw new ArgumentException($"{nameof(LeaderElectionOptions.ElectionAddress)} must be provided.", nameof(LeaderElectionOptions.ElectionAddress));
            }

            if (options.ElectionMessageInterval <= TimeSpan.Zero)
            {
                throw new ArgumentException($"{nameof(LeaderElectionOptions.ElectionMessageInterval)} must greater than 0.", nameof(LeaderElectionOptions.ElectionAddress));
            }
            if (options.HandOverAfterMissedElectionMessages <= 0)
            {
                throw new ArgumentException($"{nameof(LeaderElectionOptions.HandOverAfterMissedElectionMessages)} must greater than 0.", nameof(LeaderElectionOptions.ElectionAddress));
            }

            builder.AddConsumer(options.ElectionAddress, RoutingType.Anycast, async(message, consumer, serviceProvider, cancellationToken) =>
            {
                var leaderElection = serviceProvider.GetService <LeaderElection>();
                leaderElection.OnElectionMessage();
                await consumer.AcceptAsync(message).ConfigureAwait(false);
            });
            builder.AddProducer <ElectionMessageProducer>(options.ElectionAddress, RoutingType.Anycast, ServiceLifetime.Singleton);
            builder.Services.AddSingleton(provider => ActivatorUtilities.CreateInstance <LeaderElection>(provider, options));
            builder.Services.AddSingleton <ILeaderElection>(provider => provider.GetRequiredService <LeaderElection>());
            return(builder);
        }
Example #3
0
 public static IActiveMqBuilder AddTypedConsumer <TMessage, TConsumer>(this IActiveMqBuilder builder, RoutingType routingType)
     where TConsumer : class, ITypedConsumer <TMessage>
 {
     builder.Services.TryAddScoped <TConsumer>();
     builder.AddConsumer(typeof(TMessage).Name, routingType, HandleMessage <TMessage, TConsumer>);
     return(builder);
 }
 public static IActiveMqBuilder AddReceiveObserver <TReceiveObserver>(this IActiveMqBuilder builder) where TReceiveObserver : class, IReceiveObserver
 {
     builder.Services.Configure <ActiveMqOptions>(builder.Name, options => options.ReceiveObserverRegistrations.Add(new ReceiveObserverRegistration
     {
         Type = typeof(TReceiveObserver)
     }));
     return(builder);
 }
        /// <summary>
        /// Adds the <see cref="IProducer"/> and configures a binding between the <typeparam name="TProducer" /> and named <see cref="IProducer"/> instance.
        /// </summary>
        /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
        /// <param name="address">The address name.</param>
        /// <param name="producerOptions">The <see cref="IProducer"/> configuration.</param>
        /// <param name="producerLifetime">The lifetime with which to register the <typeparam name="TProducer" /> in the container.</param>
        /// <typeparam name="TProducer">The type of the typed producer. The type specified will be registered in the service collection as
        /// a transient service by default.</typeparam>
        /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
        public static IActiveMqBuilder AddProducer <TProducer>(this IActiveMqBuilder builder, string address, ProducerOptions producerOptions, ServiceLifetime producerLifetime = ServiceLifetime.Transient)
            where TProducer : class
        {
            var producerConfiguration = producerOptions.ToConfiguration();

            producerConfiguration.Address = address;

            return(builder.AddProducer <TProducer>(producerConfiguration, producerLifetime));
        }
 public static IActiveMqBuilder AddReceiveObserver <TReceiveObserver>(this IActiveMqBuilder builder, Func <IServiceProvider, IReceiveObserver> implementationFactory) where TReceiveObserver : class, IReceiveObserver
 {
     builder.Services.Configure <ActiveMqOptions>(builder.Name, options => options.ReceiveObserverRegistrations.Add(new ReceiveObserverRegistration
     {
         Type = typeof(TReceiveObserver),
         ImplementationFactory = implementationFactory
     }));
     return(builder);
 }
Example #7
0
        public static IActiveMqBuilder AddTypedConsumer <TMessage, TConsumer>(this IActiveMqBuilder builder, RoutingType routingType, string queue)
            where TConsumer : class, ITypedConsumer <TMessage>
        {
            builder.Services.TryAddScoped <TConsumer>();
            var address   = typeof(TMessage).Name;
            var queueName = $"{address}/{queue}";

            builder.AddConsumer(address, routingType, queueName, HandleMessage <TMessage, TConsumer>);
            return(builder);
        }
        /// <summary>
        /// Adds the <see cref="IProducer"/> and configures a binding between the <typeparam name="TProducer" /> and named <see cref="IProducer"/> instance.
        /// </summary>
        /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
        /// <param name="address">The address name.</param>
        /// <param name="routingType">The routing type of the address.</param>
        /// <param name="producerLifetime">The lifetime with which to register the <typeparam name="TProducer" /> in the container.</param>
        /// <typeparam name="TProducer">The type of the typed producer. The type specified will be registered in the service collection as
        /// a transient service by default.</typeparam>
        /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
        public static IActiveMqBuilder AddProducer <TProducer>(this IActiveMqBuilder builder, string address, RoutingType routingType, ServiceLifetime producerLifetime = ServiceLifetime.Transient) where TProducer : class
        {
            var producerConfiguration = new ProducerConfiguration
            {
                Address     = address,
                RoutingType = routingType,
            };

            return(builder.AddProducer <TProducer>(producerConfiguration, producerLifetime));
        }
 public static IActiveMqBuilder AddSendObserver <TSendObserver>(this IActiveMqBuilder builder) where TSendObserver : class, ISendObserver
 {
     builder.Services.Configure <ActiveMqOptions>(builder.Name, options =>
     {
         options.SendObserverRegistrations.Add(new SendObserverRegistration
         {
             Type = typeof(TSendObserver),
         });
     });
     return(builder);
 }
Example #10
0
 public static IActiveMqBuilder AddMetrics(this IActiveMqBuilder builder, Action <ActiveMqMetricsOptions> configureOptions)
 {
     builder.Services.AddSingleton(provider =>
     {
         var activeMqMetricsOptions = new ActiveMqMetricsOptions();
         configureOptions.Invoke(activeMqMetricsOptions);
         var metrics = provider.GetRequiredService <IMetrics>();
         return(new ActiveMqMetricsRecorder(builder.Name, activeMqMetricsOptions, metrics));
     });
     return(builder.AddSendObserver <ActiveMqMetricsRecorder>(provider => provider.GetMetricsRecorder(builder.Name))
            .AddReceiveObserver <ActiveMqMetricsRecorder>(provider => provider.GetMetricsRecorder(builder.Name)));
 }
        /// <summary>
        /// Adds the <see cref="IAnonymousProducer"/> and configures a binding between the <typeparam name="TProducer" /> and named <see cref="IProducer"/> instance.
        /// </summary>
        /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
        /// <param name="producerOptions">The <see cref="IAnonymousProducer"/> configuration.</param>
        /// <param name="producerLifetime">The lifetime with which to register the <typeparam name="TProducer" /> in the container.</param>
        /// <typeparam name="TProducer">The type of the typed producer. The type specified will be registered in the service collection as
        /// a transient service by default.</typeparam>
        /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
        public static IActiveMqBuilder AddAnonymousProducer <TProducer>(this IActiveMqBuilder builder, ProducerOptions producerOptions, ServiceLifetime producerLifetime = ServiceLifetime.Transient) where TProducer : class
        {
            var anonymousProducerConfiguration = new AnonymousProducerConfiguration
            {
                MessagePriority        = producerOptions.MessagePriority,
                MessageDurabilityMode  = producerOptions.MessageDurabilityMode,
                MessageIdPolicy        = producerOptions.MessageIdPolicy,
                SetMessageCreationTime = producerOptions.SetMessageCreationTime
            };

            return(builder.AddAnonymousProducer <TProducer>(anonymousProducerConfiguration, producerLifetime));
        }
        private static IActiveMqBuilder AddProducer <TProducer>(this IActiveMqBuilder builder, ProducerConfiguration producerConfiguration, ServiceLifetime producerLifetime) where TProducer : class
        {
            if (builder.Services.Any(x => x.ServiceType == typeof(TProducer)))
            {
                var message =
                    $"There has already been registered Producer with the type '{typeof(TProducer).FullName}'. " +
                    "Typed Producer must be unique. " +
                    "Consider using inheritance to create multiple unique types with the same API surface.";
                throw new InvalidOperationException(message);
            }

            builder.Services.Configure <ActiveMqOptions>(builder.Name, options =>
            {
                if (!options.AddressConfigurations.TryGetValue(producerConfiguration.Address, out var routingTypes))
                {
                    routingTypes = new HashSet <RoutingType>();
                    options.AddressConfigurations.Add(producerConfiguration.Address, routingTypes);
                }

                if (producerConfiguration.RoutingType.HasValue)
                {
                    routingTypes.Add(producerConfiguration.RoutingType.Value);
                }
                else
                {
                    routingTypes.Add(RoutingType.Anycast);
                    routingTypes.Add(RoutingType.Multicast);
                }
            });

            builder.Services.AddSingleton(provider =>
            {
                var sendObservable           = provider.GetServices <SendObservable>().Single(x => x.Name == builder.Name);
                var logger                   = provider.GetService <ILogger <TypedActiveMqProducer <TProducer> > >();
                var contextualSendObservable = new ContextualSendObservable(sendObservable)
                {
                    Address     = producerConfiguration.Address,
                    RoutingType = producerConfiguration.RoutingType
                };
                return(new TypedActiveMqProducer <TProducer>(logger, async token =>
                {
                    var connection = await provider.GetConnection(builder.Name, token);
                    return await connection.CreateProducerAsync(producerConfiguration, token).ConfigureAwait(false);
                }, contextualSendObservable));
            });
            builder.Services.AddSingleton <IActiveMqProducer>(provider => provider.GetRequiredService <TypedActiveMqProducer <TProducer> >());
            builder.Services.Add(ServiceDescriptor.Describe(typeof(TProducer),
                                                            provider => ActivatorUtilities.CreateInstance <TProducer>(provider, provider.GetRequiredService <TypedActiveMqProducer <TProducer> >()),
                                                            producerLifetime));
            return(builder);
        }
        /// <summary>
        /// Adds the <see cref="IConsumer"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
        /// <param name="address">The address name.</param>
        /// <param name="routingType">The routing type of the address.</param>
        /// <param name="queue">The queue name.</param>
        /// <param name="consumerOptions">The <see cref="IConsumer"/> configuration.</param>
        /// <param name="queueOptions">The queue configuration that will be used when queue declaration is enabled.</param>
        /// <param name="handler">A delegate that will be invoked when messages arrive.</param>
        /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
        public static IActiveMqBuilder AddConsumer(this IActiveMqBuilder builder, string address, RoutingType routingType, string queue, ConsumerOptions consumerOptions, QueueOptions queueOptions,
                                                   Func <Message, IConsumer, IServiceProvider, CancellationToken, Task> handler)
        {
            builder.Services.Configure <ActiveMqOptions>(builder.Name, options =>
            {
                options.QueueConfigurations.Add(new QueueConfiguration
                {
                    Address            = address,
                    RoutingType        = routingType,
                    Name               = queue,
                    Exclusive          = queueOptions.Exclusive,
                    FilterExpression   = queueOptions.FilterExpression,
                    GroupBuckets       = queueOptions.GroupBuckets,
                    GroupRebalance     = queueOptions.GroupRebalance,
                    MaxConsumers       = queueOptions.MaxConsumers,
                    AutoCreateAddress  = queueOptions.AutoCreateAddress,
                    PurgeOnNoConsumers = queueOptions.PurgeOnNoConsumers
                });
                if (options.AddressConfigurations.TryGetValue(address, out var routingTypes))
                {
                    routingTypes.Add(routingType);
                }
                else
                {
                    options.AddressConfigurations[address] = new HashSet <RoutingType> {
                        routingType
                    };
                }
            });
            for (int i = 0; i < consumerOptions.ConcurrentConsumers; i++)
            {
                builder.AddConsumer(new ConsumerConfiguration
                {
                    Address          = address,
                    Queue            = queue,
                    Credit           = consumerOptions.Credit,
                    FilterExpression = consumerOptions.FilterExpression,
                    NoLocalFilter    = consumerOptions.NoLocalFilter,
                }, observable =>
                {
                    observable.Address     = address;
                    observable.RoutingType = routingType;
                    observable.Queue       = queue;
                }, handler);
            }

            return(builder);
        }
 private static void AddConsumer(this IActiveMqBuilder builder,
                                 ConsumerConfiguration consumerConfiguration,
                                 Action <ContextualReceiveObservable> configureContextualReceiveObservableAction,
                                 Func <Message, IConsumer, IServiceProvider, CancellationToken, Task> handler)
 {
     builder.Services.AddSingleton(provider =>
     {
         var receiveObservable           = provider.GetServices <ReceiveObservable>().Single(x => x.Name == builder.Name);
         var contextualReceiveObservable = new ContextualReceiveObservable(receiveObservable);
         configureContextualReceiveObservableAction(contextualReceiveObservable);
         return(new ActiveMqConsumer(provider, contextualReceiveObservable, async token =>
         {
             var connection = await provider.GetConnection(builder.Name, token);
             return await connection.CreateConsumerAsync(consumerConfiguration, token).ConfigureAwait(false);
         }, handler));
     });
 }
        /// <summary>
        /// Adds the <see cref="IConsumer"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
        /// <param name="address">The address name.</param>
        /// <param name="routingType">The routing type of the address.</param>
        /// <param name="consumerOptions">The <see cref="IConsumer"/> configuration.</param>
        /// <param name="handler">A delegate that will be invoked when messages arrive.</param>
        /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
        public static IActiveMqBuilder AddConsumer(this IActiveMqBuilder builder, string address, RoutingType routingType, ConsumerOptions consumerOptions,
                                                   Func <Message, IConsumer, IServiceProvider, CancellationToken, Task> handler)
        {
            for (int i = 0; i < consumerOptions.ConcurrentConsumers; i++)
            {
                builder.AddConsumer(new ConsumerConfiguration
                {
                    Address          = address,
                    RoutingType      = routingType,
                    Credit           = consumerOptions.Credit,
                    FilterExpression = consumerOptions.FilterExpression,
                    NoLocalFilter    = consumerOptions.NoLocalFilter
                }, observable =>
                {
                    observable.Address     = address;
                    observable.RoutingType = routingType;
                }, handler);
            }

            return(builder);
        }
 /// <summary>
 /// Adds action to configure to configure a <see cref="ConnectionFactory"/>.
 /// </summary>
 /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
 /// <param name="configureFactoryAction">A delegate that is used to configure a <see cref="ConnectionFactory"/>.</param>
 /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
 public static IActiveMqBuilder ConfigureConnectionFactory(this IActiveMqBuilder builder, Action <IServiceProvider, ConnectionFactory> configureFactoryAction)
 {
     builder.Services.Configure <ActiveMqOptions>(builder.Name, options => options.ConnectionFactoryActions.Add(configureFactoryAction));
     return(builder);
 }
 /// <summary>
 /// Configures an address declaration. If an address declaration is enabled, the client will declare addresses on the broker according to the provided confided configuration.
 /// If the address doesn't exist, it will be created. If the address does exist, it will be updated accordingly.
 /// </summary>
 /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
 /// <param name="enableAddressDeclaration">Specified if an address declaration is enabled.</param>
 /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
 public static IActiveMqBuilder EnableAddressDeclaration(this IActiveMqBuilder builder, bool enableAddressDeclaration = true)
 {
     builder.Services.Configure <ActiveMqOptions>(builder.Name, options => options.EnableAddressDeclaration = enableAddressDeclaration);
     return(builder);
 }
        /// <summary>
        /// Adds the <see cref="IAnonymousProducer"/> and configures a binding between the <typeparam name="TProducer" /> and named <see cref="IProducer"/> instance.
        /// </summary>
        /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
        /// <param name="producerLifetime">The lifetime with which to register the <typeparam name="TProducer" /> in the container.</param>
        /// <typeparam name="TProducer">The type of the typed producer. The type specified will be registered in the service collection as
        /// a transient service by default.</typeparam>
        /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
        public static IActiveMqBuilder AddAnonymousProducer <TProducer>(this IActiveMqBuilder builder, ServiceLifetime producerLifetime = ServiceLifetime.Transient) where TProducer : class
        {
            var anonymousProducerConfiguration = new AnonymousProducerConfiguration();

            return(builder.AddAnonymousProducer <TProducer>(anonymousProducerConfiguration, producerLifetime));
        }
 /// <summary>
 /// Adds the <see cref="IConsumer"/>.
 /// </summary>
 /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
 /// <param name="address">The address name.</param>
 /// <param name="routingType">The routing type of the address.</param>
 /// <param name="queue">The queue name.</param>
 /// <param name="queueOptions">The queue configuration that will be used when queue declaration is enabled.</param>
 /// <param name="handler">A delegate that will be invoked when messages arrive.</param>
 /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
 public static IActiveMqBuilder AddConsumer(this IActiveMqBuilder builder, string address, RoutingType routingType, string queue, QueueOptions queueOptions,
                                            Func <Message, IConsumer, IServiceProvider, CancellationToken, Task> handler)
 {
     return(builder.AddConsumer(address, routingType, queue, new ConsumerOptions(), queueOptions, handler));
 }