diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderFactoryListener.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderFactoryListener.java new file mode 100644 index 000000000..00ae25ec5 --- /dev/null +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BinderFactoryListener.java @@ -0,0 +1,34 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.stream.binder; + +import org.springframework.context.ConfigurableApplicationContext; + +/** + * This interface adds additional capabilities to the binder when it is created. + * + * @author Ilayaperumal Gopinathan + */ +public interface BinderFactoryListener { + + /** + * Applying additional capabilities to the binder when creating the new binder instance. + * @param configurationName the binder configuration name + * @param binderProducingContext the application context of the binder + */ + void apply(String configurationName, ConfigurableApplicationContext binderProducingContext); +} diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindersHealthIndicatorAutoConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindersHealthIndicatorAutoConfiguration.java new file mode 100644 index 000000000..bfda3d513 --- /dev/null +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindersHealthIndicatorAutoConfiguration.java @@ -0,0 +1,49 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.stream.binder; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; +import org.springframework.boot.actuate.health.CompositeHealthIndicator; +import org.springframework.boot.actuate.health.OrderedHealthAggregator; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Ilayaperumal Gopinathan + */ +@ConditionalOnClass(name = "org.springframework.boot.actuate.health.HealthIndicator") +@ConditionalOnEnabledHealthIndicator("binders") +@AutoConfigureBefore(EndpointAutoConfiguration.class) +@Configuration +public class BindersHealthIndicatorAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(name = "bindersHealthIndicator") + public CompositeHealthIndicator bindersHealthIndicator() { + return new CompositeHealthIndicator(new OrderedHealthAggregator()); + } + + @Bean + public BinderFactoryListener bindersHealthIndicatorListener(@Qualifier("bindersHealthIndicator") CompositeHealthIndicator compositeHealthIndicator) { + return new BindersHealthIndicatorListener(compositeHealthIndicator); + } +} diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindersHealthIndicatorListener.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindersHealthIndicatorListener.java new file mode 100644 index 000000000..86b646154 --- /dev/null +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/BindersHealthIndicatorListener.java @@ -0,0 +1,63 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.stream.binder; + +import java.util.Map; + +import org.springframework.boot.actuate.health.AbstractHealthIndicator; +import org.springframework.boot.actuate.health.CompositeHealthIndicator; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.health.OrderedHealthAggregator; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * {@link BinderFactoryListener} that provides {@link HealthIndicator} support. + * + * @author Ilayaperumal Gopinathan + */ +public class BindersHealthIndicatorListener implements BinderFactoryListener { + + private final CompositeHealthIndicator bindersHealthIndicator; + + public BindersHealthIndicatorListener(CompositeHealthIndicator bindersHealthIndicator) { + this.bindersHealthIndicator = bindersHealthIndicator; + } + + @Override + public void apply(String binderConfigurationName, ConfigurableApplicationContext binderProducingContext) { + if (this.bindersHealthIndicator != null) { + OrderedHealthAggregator healthAggregator = new OrderedHealthAggregator(); + Map indicators = binderProducingContext.getBeansOfType(HealthIndicator.class); + // if there are no health indicators in the child context, we just mark the binder's health as unknown + // this can happen due to the fact that configuration is inherited + HealthIndicator binderHealthIndicator = + indicators.isEmpty() ? new DefaultHealthIndicator() : new CompositeHealthIndicator( + healthAggregator, indicators); + this.bindersHealthIndicator.addHealthIndicator(binderConfigurationName, binderHealthIndicator); + } + } + + private static class DefaultHealthIndicator extends AbstractHealthIndicator { + + @Override + protected void doHealthCheck(Health.Builder builder) throws Exception { + builder.unknown(); + } + } +} + diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java index aafcd37d1..cf6cd2fc6 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binder/DefaultBinderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 the original author or authors. + * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.cloud.stream.binder; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -26,14 +27,7 @@ import java.util.Properties; import java.util.Set; import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.Banner.Mode; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.CompositeHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.OrderedHealthAggregator; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.stream.reflection.GenericsUtils; import org.springframework.context.ApplicationContext; @@ -47,7 +41,9 @@ import org.springframework.util.StringUtils; /** * Default {@link BinderFactory} implementation. + * * @author Marius Bogoevici + * @author Ilayaperumal Gopinathan */ public class DefaultBinderFactory implements BinderFactory, DisposableBean, ApplicationContextAware { @@ -59,9 +55,9 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl private Map defaultBinderForBindingTargetType = new HashMap<>(); - private volatile String defaultBinder; + private Collection binderFactoryListeners; - private volatile CompositeHealthIndicator bindersHealthIndicator; + private volatile String defaultBinder; public DefaultBinderFactory(Map binderConfigurations) { this.binderConfigurations = new HashMap<>(binderConfigurations); @@ -73,16 +69,14 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl this.context = (ConfigurableApplicationContext) applicationContext; } - @Autowired(required = false) - @Qualifier("bindersHealthIndicator") - public void setBindersHealthIndicator(CompositeHealthIndicator bindersHealthIndicator) { - this.bindersHealthIndicator = bindersHealthIndicator; - } - public void setDefaultBinder(String defaultBinder) { this.defaultBinder = defaultBinder; } + public void setBinderFactoryListeners(Collection binderFactoryListeners) { + this.binderFactoryListeners = binderFactoryListeners; + } + @Override public void destroy() throws Exception { for (Map.Entry entry : this.binderInstanceCache.entrySet()) { @@ -126,13 +120,15 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl if (candidatesForBindableType.size() == 1) { configurationName = candidatesForBindableType.iterator().next(); this.defaultBinderForBindingTargetType.put(bindingTargetType.getName(), configurationName); - } else if (candidatesForBindableType.size() > 1) { + } + else if (candidatesForBindableType.size() > 1) { throw new IllegalStateException( "A default binder has been requested, but there is more than one binder available for '" + bindingTargetType.getName() + "' : " + StringUtils.collectionToCommaDelimitedString(candidatesForBindableType) + ", and no default binder has been set."); - } else { + } + else { throw new IllegalStateException("A default binder has been requested, but none of the " + "registered binders can bind a '" + bindingTargetType + "': " + StringUtils.collectionToCommaDelimitedString(defaultCandidateConfigurations)); @@ -188,7 +184,7 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl Arrays.asList(binderConfiguration.getBinderType().getConfigurationClasses())); SpringApplicationBuilder springApplicationBuilder = new SpringApplicationBuilder() - .sources(configurationClasses.toArray(new Class[] {})) + .sources(configurationClasses.toArray(new Class[]{})) .bannerMode(Mode.OFF) .web(false); // If the environment is not customized and a main context is available, we will set the latter as parent. @@ -210,15 +206,10 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl springApplicationBuilder.run(args.toArray(new String[args.size()])); @SuppressWarnings("unchecked") Binder binder = binderProducingContext.getBean(Binder.class); - if (this.bindersHealthIndicator != null) { - OrderedHealthAggregator healthAggregator = new OrderedHealthAggregator(); - Map indicators = binderProducingContext.getBeansOfType(HealthIndicator.class); - // if there are no health indicators in the child context, we just mark the binder's health as unknown - // this can happen due to the fact that configuration is inherited - HealthIndicator binderHealthIndicator = - indicators.isEmpty() ? new DefaultHealthIndicator() : new CompositeHealthIndicator( - healthAggregator, indicators); - this.bindersHealthIndicator.addHealthIndicator(configurationName, binderHealthIndicator); + if (this.binderFactoryListeners != null) { + for (BinderFactoryListener binderFactoryListener : binderFactoryListeners) { + binderFactoryListener.apply(configurationName, binderProducingContext); + } } this.binderInstanceCache.put(configurationName, new BinderInstanceHolder(binder, binderProducingContext)); @@ -248,12 +239,4 @@ public class DefaultBinderFactory implements BinderFactory, DisposableBean, Appl return this.binderContext; } } - - private static class DefaultHealthIndicator extends AbstractHealthIndicator { - - @Override - protected void doHealthCheck(Health.Builder builder) throws Exception { - builder.unknown(); - } - } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingService.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingService.java index cecb2a96d..50715f111 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingService.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindingService.java @@ -152,12 +152,13 @@ public class BindingService { @SuppressWarnings("unchecked") private Binder getBinder(String channelName, Class bindableType) { - String transport = this.bindingServiceProperties.getBinder(channelName); - return binderFactory.getBinder(transport, bindableType); + String binderConfigurationName = this.bindingServiceProperties.getBinder(channelName); + return binderFactory.getBinder(binderConfigurationName, bindableType); } /** * Provided for backwards compatibility. Will be removed in a future version. + * * @return */ @Deprecated diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java index edcb7b189..91a2dc291 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java @@ -28,10 +28,12 @@ import java.util.Map; import java.util.Properties; import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.stream.binder.BinderConfiguration; import org.springframework.cloud.stream.binder.BinderFactory; +import org.springframework.cloud.stream.binder.BinderFactoryListener; import org.springframework.cloud.stream.binder.BinderType; import org.springframework.cloud.stream.binder.BinderTypeRegistry; import org.springframework.cloud.stream.binder.DefaultBinderFactory; @@ -57,15 +59,32 @@ public class BinderFactoryConfiguration { private static final String SELF_CONTAINED_APP_PROPERTY_NAME = SPRING_CLOUD_STREAM_INTERNAL_PREFIX + ".selfContained"; + private static final String BINDER_CONFIGURATIONS_BEAN_NAME = "spring.cloud.stream.binderConfigruations"; + @Value("${" + SELF_CONTAINED_APP_PROPERTY_NAME + ":}") private String selfContained; + @Autowired + private BinderTypeRegistry binderTypeRegistry; + + @Autowired + private BindingServiceProperties bindingServiceProperties; + + @Autowired(required = false) + private Collection binderFactoryListeners; + @Bean @ConditionalOnMissingBean(BinderFactory.class) - public BinderFactory binderFactory(BinderTypeRegistry binderTypeRegistry, - BindingServiceProperties bindingServiceProperties) { + public BinderFactory binderFactory() { + DefaultBinderFactory binderFactory = new DefaultBinderFactory(getBinderConfigurations()); + binderFactory.setDefaultBinder(bindingServiceProperties.getDefaultBinder()); + binderFactory.setBinderFactoryListeners(binderFactoryListeners); + return binderFactory; + } + + public Map getBinderConfigurations() { Map binderConfigurations = new HashMap<>(); - Map declaredBinders = bindingServiceProperties.getBinders(); + Map declaredBinders = this.bindingServiceProperties.getBinders(); boolean defaultCandidatesExist = false; Iterator> binderPropertiesIterator = declaredBinders.entrySet().iterator(); while (!defaultCandidatesExist && binderPropertiesIterator.hasNext()) { @@ -74,9 +93,9 @@ public class BinderFactoryConfiguration { List existingBinderConfigurations = new ArrayList<>(); for (Map.Entry binderEntry : declaredBinders.entrySet()) { BinderProperties binderProperties = binderEntry.getValue(); - if (binderTypeRegistry.get(binderEntry.getKey()) != null) { + if (this.binderTypeRegistry.get(binderEntry.getKey()) != null) { binderConfigurations.put(binderEntry.getKey(), - new BinderConfiguration(binderTypeRegistry.get(binderEntry.getKey()), + new BinderConfiguration(this.binderTypeRegistry.get(binderEntry.getKey()), binderProperties.getEnvironment(), binderProperties.isInheritEnvironment(), binderProperties.isDefaultCandidate())); existingBinderConfigurations.add(binderEntry.getKey()); @@ -84,7 +103,7 @@ public class BinderFactoryConfiguration { else { Assert.hasText(binderProperties.getType(), "No 'type' property present for custom binder " + binderEntry.getKey()); - BinderType binderType = binderTypeRegistry.get(binderProperties.getType()); + BinderType binderType = this.binderTypeRegistry.get(binderProperties.getType()); Assert.notNull(binderType, "Binder type " + binderProperties.getType() + " is not defined"); binderConfigurations.put(binderEntry.getKey(), new BinderConfiguration(binderType, binderProperties.getEnvironment(), @@ -92,22 +111,20 @@ public class BinderFactoryConfiguration { existingBinderConfigurations.add(binderEntry.getKey()); } } - for (Map.Entry configurationEntry: binderConfigurations.entrySet()) { + for (Map.Entry configurationEntry : binderConfigurations.entrySet()) { if (configurationEntry.getValue().isDefaultCandidate()) { defaultCandidatesExist = true; } } if (!defaultCandidatesExist) { - for (Map.Entry binderEntry : binderTypeRegistry.getAll().entrySet()) { + for (Map.Entry binderEntry : this.binderTypeRegistry.getAll().entrySet()) { if (!existingBinderConfigurations.contains(binderEntry.getKey())) { binderConfigurations.put(binderEntry.getKey(), new BinderConfiguration(binderEntry.getValue(), new Properties(), true, true)); } } } - DefaultBinderFactory binderFactory = new DefaultBinderFactory(binderConfigurations); - binderFactory.setDefaultBinder(bindingServiceProperties.getDefaultBinder()); - return binderFactory; + return binderConfigurations; } @Bean @@ -128,7 +145,7 @@ public class BinderFactoryConfiguration { URL url = resources.nextElement(); UrlResource resource = new UrlResource(url); for (BinderType binderType : parseBinderConfigurations(classLoader, resource)) { - binderTypes.put(binderType.getDefaultName(), binderType); + binderTypes.put(binderType.getDefaultName(), binderType); } } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceConfiguration.java index baca9be31..474fbd058 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BindingServiceConfiguration.java @@ -68,6 +68,7 @@ import org.springframework.util.CollectionUtils; /** * Configuration class that provides necessary beans for {@link MessageChannel} binding. + * * @author Dave Syer * @author David Turanski * @author Marius Bogoevici diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAutoConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAutoConfiguration.java index c756aaeb1..8398c1591 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAutoConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelBindingAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 the original author or authors. + * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,22 +16,14 @@ package org.springframework.cloud.stream.config; -import java.util.List; - import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; -import org.springframework.boot.actuate.health.CompositeHealthIndicator; -import org.springframework.boot.actuate.health.OrderedHealthAggregator; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.stream.binding.Bindable; import org.springframework.cloud.stream.binding.BindingService; -import org.springframework.cloud.stream.endpoint.ChannelsEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.integration.scheduling.PollerMetadata; import org.springframework.messaging.MessageChannel; @@ -41,34 +33,20 @@ import org.springframework.messaging.MessageChannel; * * @author Dave Syer * @author Marius Bogoevici + * @author Ilayaperumal Gopinathan */ @Configuration @ConditionalOnBean(BindingService.class) @EnableConfigurationProperties(DefaultPollerProperties.class) -@AutoConfigureBefore(EndpointAutoConfiguration.class) +@Import(ChannelsEndpointConfiguration.class) public class ChannelBindingAutoConfiguration { @Autowired private DefaultPollerProperties poller; - @Autowired(required = false) - private List adapters; - @Bean(name = PollerMetadata.DEFAULT_POLLER) @ConditionalOnMissingBean(PollerMetadata.class) public PollerMetadata defaultPoller() { return this.poller.getPollerMetadata(); } - - @Bean - public ChannelsEndpoint channelsEndpoint(BindingServiceProperties properties) { - return new ChannelsEndpoint(this.adapters, properties); - } - - @Bean - @ConditionalOnEnabledHealthIndicator("binders") - @ConditionalOnMissingBean(name = "bindersHealthIndicator") - public CompositeHealthIndicator bindersHealthIndicator() { - return new CompositeHealthIndicator(new OrderedHealthAggregator()); - } } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelsEndpointConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelsEndpointConfiguration.java new file mode 100644 index 000000000..6b8349ad3 --- /dev/null +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/ChannelsEndpointConfiguration.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.stream.config; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.cloud.stream.binding.Bindable; +import org.springframework.cloud.stream.endpoint.ChannelsEndpoint; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Dave Syer + * @author Marius Bogoevici + * @author Ilayaperumal Gopinathan + */ +@Configuration +@ConditionalOnClass(name = "org.springframework.boot.actuate.endpoint.Endpoint") +@AutoConfigureAfter(EndpointAutoConfiguration.class) +public class ChannelsEndpointConfiguration { + + @Autowired(required = false) + private List adapters; + + @Bean + public ChannelsEndpoint channelsEndpoint(BindingServiceProperties properties) { + return new ChannelsEndpoint(this.adapters, properties); + } +} diff --git a/spring-cloud-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-stream/src/main/resources/META-INF/spring.factories index 3678aa5d1..999c33304 100644 --- a/spring-cloud-stream/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-stream/src/main/resources/META-INF/spring.factories @@ -1,2 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration:\ -org.springframework.cloud.stream.config.ChannelBindingAutoConfiguration +org.springframework.cloud.stream.config.ChannelBindingAutoConfiguration,\ + org.springframework.cloud.stream.binder.BindersHealthIndicatorAutoConfiguration