public async Task TestBindingPartitionedConsumer() { var searchDirectories = GetSearchDirectories("MockBinder"); var provider = CreateStreamsContainerWithISinkBinding( searchDirectories, "spring.cloud.stream.bindings.input.destination=partIn", "spring.cloud.stream.bindings.input.consumer.partitioned=true", "spring.cloud.stream.instanceCount=2", "spring.cloud.stream.instanceIndex=0") .BuildServiceProvider(); var factory = provider.GetService <IBinderFactory>(); Assert.NotNull(factory); var binder = factory.GetBinder(null); var mockBinder = Mock.Get <IBinder>(binder); var sink = provider.GetService <ISink>(); IConsumerOptions captured = null; mockBinder.Setup((b) => b.BindConsumer("partIn", null, sink.Input, It.IsAny <IConsumerOptions>())).Callback <string, string, object, IConsumerOptions>((a, b, c, d) => { captured = d; }); await provider.GetRequiredService <ILifecycleProcessor>().OnRefresh(); // Only starts Autostart mockBinder.Verify((b) => b.BindConsumer("partIn", null, sink.Input, It.IsAny <IConsumerOptions>())); Assert.Equal(0, captured.InstanceIndex); Assert.Equal(2, captured.InstanceCount); }
public ICollection <IBinding> BindConsumer <T>(T inputChannel, string name) { var bindings = new List <IBinding>(); var binder = GetBinder <T>(name); IConsumerOptions consumerOptions = Options.GetConsumerOptions(name); ValidateOptions(consumerOptions); var bindingTarget = Options.GetBindingDestination(name); if (consumerOptions.Multiplex) { bindings.Add(DoBindConsumer(inputChannel, name, binder, consumerOptions, bindingTarget)); } else { var bindingTargets = bindingTarget == null ? new string[0] : bindingTarget.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var target in bindingTargets) { var binding = DoBindConsumer(inputChannel, name, binder, consumerOptions, target); bindings.Add(binding); } } _consumerBindings[name] = new List <IBinding>(bindings); return(bindings); }
public IBinding BindConsumer(string name, string group, T inboundTarget, IConsumerOptions consumerOptions) { if (string.IsNullOrEmpty(group) && consumerOptions.IsPartitioned) { throw new ArgumentException("A consumer group is required for a partitioned subscription"); } return(DoBindConsumer(name, group, inboundTarget, consumerOptions)); }
private bool IsNativeEncodingNotSet(IProducerOptions producerOptions, IConsumerOptions consumerOptions, bool input) { if (input) { return(consumerOptions == null || !consumerOptions.UseNativeDecoding); } else { return(producerOptions == null || !producerOptions.UseNativeEncoding); } }
public DefaultConsumerMessageChannelBinding( AbstractMessageChannelBinder binder, string name, string group, IMessageChannel inputChannel, ILifecycle lifecycle, IConsumerOptions options, IConsumerDestination consumerDestination) : base(name, group, inputChannel, lifecycle) { this.binder = binder; this.options = options; destination = consumerDestination; }
public DefaultPollableChannelBinding( AbstractMessageChannelBinder binder, string name, string group, IPollableSource <IMessageHandler> inboundBindTarget, ILifecycle lifecycle, IConsumerOptions options, IConsumerDestination consumerDestination) : base(name, group, inboundBindTarget, lifecycle) { _binder = binder; _options = options; _destination = consumerDestination; }
public void CleanAutoDeclareContext(IConsumerDestination destination, IConsumerOptions consumerProperties) { lock (_autoDeclareContext) { destination.Name.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(name => { name = name.Trim(); RemoveSingleton(name + ".binding"); RemoveSingleton(name); var dlq = name + ".dlq"; RemoveSingleton(dlq + ".binding"); RemoveSingleton(dlq); }); } }
public DefaultConsumerMessageChannelBinding( AbstractMessageChannelBinder binder, string name, string group, IMessageChannel inputChannel, ILifecycle lifecycle, IConsumerOptions options, IConsumerDestination consumerDestination, ILogger logger = null) : base(name, group, inputChannel, lifecycle) { _binder = binder; _options = options; _destination = consumerDestination; _logger = logger; }
private RabbitConfig.IBinding DeclareConsumerBindings( string name, string routingKey, IConsumerOptions options, IExchange exchange, bool partitioned, Queue queue) { var consumerProperties = Options.GetRabbitConsumerOptions(options.BindingName); if (partitioned) { return(PartitionedBinding(name, exchange, queue, routingKey, consumerProperties, options.InstanceIndex)); } else { return(NotPartitionedBinding(exchange, queue, routingKey, consumerProperties)); } }
private void CaptureConsumerResources(string name, string group, IConsumerOptions options) { string[] names = null; var consumerOptions = BindingsOptions.GetRabbitConsumerOptions(options.BindingName); if (group != null) { if (consumerOptions.QueueNameGroupOnly.GetValueOrDefault()) { _queues.Add(consumerOptions.Prefix + group); } else { if (options.Multiplex) { names = name.Split(','); foreach (var nayme in names) { _queues.Add(consumerOptions.Prefix + nayme.Trim() + "." + group); } } else { _queues.Add(consumerOptions.Prefix + name + "." + group); } } } if (names != null) { foreach (var nayme in names) { _exchanges.Add(consumerOptions.Prefix + nayme.Trim()); } } else { _exchanges.Add(consumerOptions.Prefix + name.Trim()); } _prefixes.Add(consumerOptions.Prefix); DeadLetters(consumerOptions); }
private void ValidateOptions(IConsumerOptions consumerOptions) { if (consumerOptions.Concurrency <= 0) { throw new InvalidOperationException("Concurrency should be greater than zero."); } if (consumerOptions.InstanceCount <= -1) { throw new InvalidOperationException("Instance count should be greater than or equal to -1."); } if (consumerOptions.InstanceIndex <= -1) { throw new InvalidOperationException("Instance index should be greater than or equal to -1."); } if (consumerOptions.MaxAttempts <= 0) { throw new InvalidOperationException("Max attempts should be greater than zero."); } if (consumerOptions.BackOffInitialInterval <= 0) { throw new InvalidOperationException("Backoff initial interval should be greater than zero."); } if (consumerOptions.BackOffMaxInterval <= 0) { throw new InvalidOperationException("Backoff max interval should be greater than zero."); } if (consumerOptions.BackOffMultiplier <= 0) { throw new InvalidOperationException("Backoff multiplier should be greater than zero."); } }
protected virtual PolledConsumerResources CreatePolledConsumerResources(string name, string group, IConsumerDestination destination, IConsumerOptions consumerOptions) { throw new InvalidOperationException("This binder does not support pollable consumers"); }
protected virtual IRecoveryCallback GetPolledConsumerRecoveryCallback(ErrorInfrastructure errorInfrastructure, IConsumerOptions options) { return(errorInfrastructure.Recoverer); }
protected virtual string GetErrorBridgeName(IConsumerDestination destination, string group, IConsumerOptions consumerOptions) { return(GetErrorsBaseName(destination, group, consumerOptions) + ".bridge"); }
private void DestroyErrorInfrastructure(IConsumerDestination destination, string group, IConsumerOptions options) { try { var recoverer = GetErrorRecovererName(destination, group, options); DestroyBean(recoverer); var errorChannelName = GetErrorsBaseName(destination, group, options); var errorMessageHandlerName = GetErrorMessageHandlerName(destination, group, options); var errorBridgeHandlerName = GetErrorBridgeName(destination, group, options); if (_destinationRegistry.Lookup(errorChannelName) is ISubscribableChannel channel) { if (_destinationRegistry.Lookup(errorBridgeHandlerName) is IMessageHandler bridgeHandler) { channel.Unsubscribe(bridgeHandler); DestroyBean(errorBridgeHandlerName); } if (_destinationRegistry.Lookup(errorMessageHandlerName) is IMessageHandler handler) { channel.Unsubscribe(handler); DestroyBean(errorMessageHandlerName); } DestroyBean(errorChannelName); } } catch (Exception) { // Log ... context is shutting down. } }
public IBinding DoBindConsumer <T>(T inputTarget, string name, IBinder binder, IConsumerOptions consumerOptions, string bindingTarget) { if (Options.BindingRetryInterval <= 0) { return(binder.BindConsumer(bindingTarget, Options.GetGroup(name), inputTarget, consumerOptions)); } else { return(DoBindConsumerWithRetry(inputTarget, name, binder, consumerOptions, bindingTarget)); } }
public IConsumerDestination ProvisionConsumerDestination(string name, string group, IConsumerOptions properties) { var destination = ProvisionDestination(name, false); if (InputDestination != null) { InputDestination.Channel = destination; } return(new SpringIntegrationConsumerDestination(name, destination)); }
protected override IMessageHandler GetErrorMessageHandler(IConsumerDestination destination, string group, IConsumerOptions consumerOptions) { return(new ErrorMessageHandler(this)); }
public IBinding DoBindConsumerWithRetry <T>(T inputChan, string name, IBinder binder, IConsumerOptions consumerOptions, string bindingTarget) { // TODO: Java code never stops retrying the bind do { try { return(binder.BindConsumer(bindingTarget, Options.GetGroup(name), inputChan, consumerOptions)); } catch (Exception) { // log Thread.Sleep(Options.BindingRetryInterval * 1000); } }while (true); }
public IBinding BindConsumer(string name, string group, object inboundTarget, IConsumerOptions consumerOptions) { if (BindConsumerFunc != null) { return(BindConsumerFunc(name, group, inboundTarget, consumerOptions)); } return(null); }
public IBinding BindConsumer(string name, string group, object inboundTarget, IConsumerOptions consumerOptions) { throw new InvalidOperationException(); }
protected RetryTemplate BuildRetryTemplate(IConsumerOptions options) { return(new PollyRetryTemplate(GetRetryableExceptions(options.RetryableExceptions), options.MaxAttempts, options.DefaultRetryable, options.BackOffInitialInterval, options.BackOffMaxInterval, options.BackOffMultiplier, _logger)); }
private IConsumerDestination DoProvisionConsumerDestination(string name, string group, IConsumerOptions options) { var consumerProperties = Options.GetRabbitConsumerOptions(options.BindingName); var anonymous = string.IsNullOrEmpty(group); Base64UrlNamingStrategy anonQueueNameGenerator = null; if (anonymous) { anonQueueNameGenerator = new Base64UrlNamingStrategy(consumerProperties.AnonymousGroupPrefix ?? string.Empty); } string baseQueueName; if (consumerProperties.QueueNameGroupOnly.GetValueOrDefault()) { baseQueueName = anonymous ? anonQueueNameGenerator.GenerateName() : group; } else { baseQueueName = GetGroupedName(name, anonymous ? anonQueueNameGenerator.GenerateName() : group); } // logger.info("declaring queue for inbound: " + baseQueueName + ", bound to: " + name); var prefix = consumerProperties.Prefix; var exchangeName = ApplyPrefix(prefix, name); var exchange = BuildExchange(consumerProperties, exchangeName); if (consumerProperties.DeclareExchange.GetValueOrDefault()) { DeclareExchange(exchangeName, exchange); } var queueName = ApplyPrefix(prefix, baseQueueName); var partitioned = !anonymous && options.IsPartitioned; var durable = !anonymous && consumerProperties.DurableSubscription.Value; Queue queue; if (anonymous) { var anonQueueName = queueName; queue = new AnonymousQueue(new GivenNamingStrategy(() => anonQueueName), GetQueueArgs(queueName, consumerProperties, false)); } else { if (partitioned) { var partitionSuffix = "-" + options.InstanceIndex; queueName += partitionSuffix; } if (durable) { queue = new Queue(queueName, true, false, false, GetQueueArgs(queueName, consumerProperties, false)); } else { queue = new Queue(queueName, false, false, true, GetQueueArgs(queueName, consumerProperties, false)); } } RabbitConfig.IBinding binding = null; if (consumerProperties.BindQueue.GetValueOrDefault()) { DeclareQueue(queueName, queue); var routingKeys = BindingRoutingKeys(consumerProperties); if (routingKeys == null || routingKeys.Count == 0) { binding = DeclareConsumerBindings(name, null, options, exchange, partitioned, queue); } else { foreach (var routingKey in routingKeys) { binding = DeclareConsumerBindings(name, routingKey, options, exchange, partitioned, queue); } } } if (durable) { AutoBindDLQ(ApplyPrefix(consumerProperties.Prefix, baseQueueName), queueName, consumerProperties); } return(new RabbitConsumerDestination(queue.QueueName, binding)); }
public virtual IBinding BindConsumer(string name, string group, object inboundTarget, IConsumerOptions consumerOptions) { return(DoBindConsumer(name, group, (T)inboundTarget, consumerOptions)); }
public IConsumerDestination ProvisionConsumerDestination(string name, string group, IConsumerOptions options) { var consumerProperties = Options.GetRabbitConsumerOptions(options.BindingName); IConsumerDestination consumerDestination; if (!options.Multiplex) { consumerDestination = DoProvisionConsumerDestination(name, group, options); } else { var consumerDestinationNames = new List <string>(); var trimmed = name.Split(',', StringSplitOptions.RemoveEmptyEntries).Select((s) => s.Trim()); foreach (var destination in trimmed) { if (options.IsPartitioned && options.InstanceIndexList.Count > 0) { foreach (var index in options.InstanceIndexList) { var temporaryOptions = options.Clone() as ConsumerOptions; temporaryOptions.InstanceIndex = index; consumerDestinationNames.Add(DoProvisionConsumerDestination(destination, group, temporaryOptions).Name); } } else { consumerDestinationNames.Add(DoProvisionConsumerDestination(destination, group, options).Name); } } consumerDestination = new RabbitConsumerDestination(string.Join(',', consumerDestinationNames), null); } return(consumerDestination); }
public virtual IBinding BindConsumer(string name, string group, IPollableSource <IMessageHandler> inboundTarget, IConsumerOptions consumerOptions) { if (!(inboundTarget is DefaultPollableMessageSource bindingTarget)) { throw new InvalidOperationException(nameof(inboundTarget)); } var destination = _provisioningProvider.ProvisionConsumerDestination(name, group, consumerOptions); if (consumerOptions.HeaderMode == HeaderMode.EmbeddedHeaders) { bindingTarget.AddInterceptor(0, _embeddedHeadersChannelInterceptor); } var resources = CreatePolledConsumerResources(name, group, destination, consumerOptions); var messageSource = resources.Source; bindingTarget.Source = messageSource; if (resources.ErrorInfrastructure != null) { if (resources.ErrorInfrastructure.ErrorChannel != null) { bindingTarget.ErrorChannel = resources.ErrorInfrastructure.ErrorChannel; } var ems = GetErrorMessageStrategy(); if (ems != null) { bindingTarget.ErrorMessageStrategy = ems; } } if (consumerOptions.MaxAttempts > 1) { bindingTarget.RetryTemplate = BuildRetryTemplate(consumerOptions); bindingTarget.RecoveryCallback = GetPolledConsumerRecoveryCallback(resources.ErrorInfrastructure, consumerOptions); } PostProcessPollableSource(bindingTarget); if (resources.Source is ILifecycle) { ((ILifecycle)resources.Source).Start(); } var binding = new DefaultPollableChannelBinding( this, name, group, inboundTarget, resources.Source is ILifecycle ? (ILifecycle)resources.Source : null, consumerOptions, destination); return(binding); }
protected override IMessageProducer CreateConsumerEndpoint(IConsumerDestination destination, string group, IConsumerOptions consumerOptions) { IErrorMessageStrategy errorMessageStrategy = new DefaultErrorMessageStrategy(); var siBinderInputChannel = ((SpringIntegrationConsumerDestination)destination).Channel; var messageListenerContainer = new TestMessageListeningContainer(); var endpoint = new TestMessageProducerSupportEndpoint(ApplicationContext, messageListenerContainer); var groupName = !string.IsNullOrEmpty(group) ? group : "anonymous"; var errorInfrastructure = RegisterErrorInfrastructure(destination, groupName, consumerOptions); if (consumerOptions.MaxAttempts > 1) { endpoint.RetryTemplate = BuildRetryTemplate(consumerOptions); endpoint.RecoveryCallback = errorInfrastructure.Recoverer; } else { endpoint.ErrorMessageStrategy = errorMessageStrategy; endpoint.ErrorChannel = errorInfrastructure.ErrorChannel; } endpoint.Init(); siBinderInputChannel.Subscribe(messageListenerContainer); return(endpoint); }
public IBinding BindConsumer(string name, string group, object inboundTarget, IConsumerOptions consumerOptions) { return(null); }
protected override PolledConsumerResources CreatePolledConsumerResources(string name, string group, IConsumerDestination destination, IConsumerOptions consumerOptions) { return(new PolledConsumerResources(MessageSourceDelegate, RegisterErrorInfrastructure(destination, group, consumerOptions))); }
protected abstract IBinding DoBindConsumer(string name, string group, T inputTarget, IConsumerOptions consumerOptions);