diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/Bindable.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/Bindable.java index 5b62928ef..aa134faf6 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/Bindable.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/Bindable.java @@ -16,6 +16,8 @@ package org.springframework.cloud.stream.binding; +import java.util.Set; + /** * Marker interface for instances that can bind/unbind groups of inputs and outputs. * @@ -45,4 +47,14 @@ public interface Bindable { */ void unbindOutputs(ChannelBindingService adapter); + /** + * Enumerates all the input binding names. + */ + Set getInputs(); + + /** + * Enumerates all the output binding names. + */ + Set getOutputs(); + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindableProxyFactory.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindableProxyFactory.java index c1cc96426..bcc6c9df7 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindableProxyFactory.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/BindableProxyFactory.java @@ -19,12 +19,12 @@ package org.springframework.cloud.stream.binding; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; @@ -102,7 +102,17 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean getInputs() { + return this.inputs.keySet(); + } + + @Override + public Set getOutputs() { + return this.outputs.keySet(); } private void createChannels(Class type) throws Exception { @@ -119,11 +129,11 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean channelHolderEntry : inputs.entrySet()) { + for (Map.Entry channelHolderEntry : this.inputs.entrySet()) { String inputChannelName = channelHolderEntry.getKey(); ChannelHolder channelHolder = channelHolderEntry.getValue(); channelBindingService.configureMessageConverters(channelHolder.getMessageChannel(), inputChannelName); @@ -282,7 +292,7 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean channelHolderEntry : outputs.entrySet()) { + for (Map.Entry channelHolderEntry : this.outputs.entrySet()) { ChannelHolder channelHolder = channelHolderEntry.getValue(); String outputChannelName = channelHolderEntry.getKey(); channelBindingService.configureMessageConverters(channelHolder.getMessageChannel(), outputChannelName); @@ -300,7 +310,7 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean channelHolderEntry : inputs.entrySet()) { + for (Map.Entry channelHolderEntry : this.inputs.entrySet()) { if (channelHolderEntry.getValue().isBindable()) { if (log.isDebugEnabled()) { log.debug(String.format("Unbinding %s:%s:%s", this.channelNamespace, this.type, channelHolderEntry.getKey())); @@ -315,7 +325,7 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean channelHolderEntry : outputs.entrySet()) { + for (Map.Entry channelHolderEntry : this.outputs.entrySet()) { if (channelHolderEntry.getValue().isBindable()) { if (log.isDebugEnabled()) { log.debug(String.format("Binding %s:%s:%s", this.channelNamespace, this.type, channelHolderEntry.getKey())); @@ -342,11 +352,11 @@ public class BindableProxyFactory implements MethodInterceptor, FactoryBean adapters, ChannelBindingServiceProperties properties) { + return new ChannelsEndpoint(adapters, properties); + } + } diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/ChannelsEndpoint.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/ChannelsEndpoint.java new file mode 100644 index 000000000..5f8b7b860 --- /dev/null +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/endpoint/ChannelsEndpoint.java @@ -0,0 +1,91 @@ +/* + * Copyright 2015 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.endpoint; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.boot.actuate.endpoint.AbstractEndpoint; +import org.springframework.cloud.stream.binding.Bindable; +import org.springframework.cloud.stream.config.BindingProperties; +import org.springframework.cloud.stream.config.ChannelBindingServiceProperties; +import org.springframework.cloud.stream.endpoint.ChannelsEndpoint.ChannelsMetaData; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * @author Dave Syer + */ +@RestController +public class ChannelsEndpoint extends AbstractEndpoint { + + private List adapters; + + private ChannelBindingServiceProperties properties; + + public ChannelsEndpoint(List adapters, + ChannelBindingServiceProperties properties) { + super("channels"); + this.adapters = adapters; + this.properties = properties; + } + + @Override + public ChannelsMetaData invoke() { + ChannelsMetaData map = new ChannelsMetaData(); + Map inputs = map.getInputs(); + Map outputs = map.getOutputs(); + for (Bindable factory : this.adapters) { + Map bindings = this.properties.getBindings(); + for (String name : factory.getInputs()) { + inputs.put(name, bindings.containsKey(name) ? bindings.get(name) + : new BindingProperties()); + } + for (String name : factory.getOutputs()) { + outputs.put(name, bindings.containsKey(name) ? bindings.get(name) + : new BindingProperties()); + } + } + return map; + } + + @JsonInclude(value = Include.NON_DEFAULT) + public static class ChannelsMetaData { + private Map inputs = new LinkedHashMap<>(); + private Map outputs = new LinkedHashMap<>(); + + public Map getInputs() { + return this.inputs; + } + + public void setInputs(Map inputs) { + this.inputs = inputs; + } + + public Map getOutputs() { + return this.outputs; + } + + public void setOutputs(Map outputs) { + this.outputs = outputs; + } + } + +} \ No newline at end of file