diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/InputBindingLifecycle.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/InputBindingLifecycle.java index 6b5e0f912..e84eff42a 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/InputBindingLifecycle.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/InputBindingLifecycle.java @@ -16,10 +16,12 @@ package org.springframework.cloud.stream.binding; +import java.util.ArrayList; import java.util.Collection; import java.util.Map; import org.springframework.cloud.stream.binder.Binding; +import org.springframework.util.CollectionUtils; /** * Coordinates binding/unbinding of input binding targets in accordance to the lifecycle @@ -32,7 +34,7 @@ public class InputBindingLifecycle extends AbstractBindingLifecycle { @SuppressWarnings("unused") //It is actually used reflectively since at the moment we do not want to expose it via public method - private Collection> inputBindings; + private Collection> inputBindings = new ArrayList>(); public InputBindingLifecycle(BindingService bindingService, Map bindables) { super(bindingService, bindables); @@ -49,7 +51,10 @@ public class InputBindingLifecycle extends AbstractBindingLifecycle { @Override void doStartWithBindable(Bindable bindable) { - this.inputBindings = bindable.createAndBindInputs(bindingService); + Collection> bindableBindings = bindable.createAndBindInputs(bindingService); + if (!CollectionUtils.isEmpty(bindableBindings)) { + this.inputBindings.addAll(bindableBindings); + } } @Override diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/OutputBindingLifecycle.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/OutputBindingLifecycle.java index 38cd421a5..f8640de84 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/OutputBindingLifecycle.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/binding/OutputBindingLifecycle.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2017 the original author or authors. + * Copyright 2015-2018 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,10 +16,12 @@ package org.springframework.cloud.stream.binding; +import java.util.ArrayList; import java.util.Collection; import java.util.Map; import org.springframework.cloud.stream.binder.Binding; +import org.springframework.util.CollectionUtils; /** * Coordinates binding/unbinding of output binding targets in accordance to the lifecycle @@ -33,7 +35,7 @@ public class OutputBindingLifecycle extends AbstractBindingLifecycle { @SuppressWarnings("unused") //It is actually used reflectively since at the moment we do not want to expose it via public method - private Collection> outputBindings; + private Collection> outputBindings = new ArrayList>(); public OutputBindingLifecycle(BindingService bindingService, Map bindables) { super(bindingService, bindables); @@ -50,7 +52,10 @@ public class OutputBindingLifecycle extends AbstractBindingLifecycle { @Override void doStartWithBindable(Bindable bindable) { - this.outputBindings = bindable.createAndBindOutputs(bindingService); + Collection> bindableBindings = bindable.createAndBindOutputs(bindingService); + if (!CollectionUtils.isEmpty(bindableBindings)) { + this.outputBindings.addAll(bindableBindings); + } } @Override diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/BindingLifecycleTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/BindingLifecycleTests.java new file mode 100644 index 000000000..037198018 --- /dev/null +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binding/BindingLifecycleTests.java @@ -0,0 +1,96 @@ +/* + * Copyright 2018 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.binding; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; + +import org.springframework.beans.DirectFieldAccessor; +import org.springframework.cloud.stream.binder.Binding; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +/** + * + * @author Oleg Zhurakousky + * + */ +public class BindingLifecycleTests { + + @Test + public void testInputBindingLifecycle() { + Map bindables = new HashMap<>(); + + Bindable bindableWithTwo = new Bindable() { + public Collection> createAndBindInputs(BindingService adapter) { + return Arrays.asList(mock(Binding.class), mock(Binding.class)); + } + }; + Bindable bindableWithThree = new Bindable() { + public Collection> createAndBindInputs(BindingService adapter) { + return Arrays.asList(mock(Binding.class), mock(Binding.class), mock(Binding.class)); + } + }; + Bindable bindableEmpty = new Bindable() {}; + + bindables.put("two", bindableWithTwo); + bindables.put("empty", bindableEmpty); + bindables.put("three", bindableWithThree); + + InputBindingLifecycle lifecycle = new InputBindingLifecycle(mock(BindingService.class), bindables); + lifecycle.start(); + + Collection> lifecycleInputBindings = + (Collection>) new DirectFieldAccessor(lifecycle).getPropertyValue("inputBindings"); + assertTrue(lifecycleInputBindings.size() == 5); + lifecycle.stop(); + } + + @Test + public void testOutputBindingLifecycle() { + Map bindables = new HashMap<>(); + + Bindable bindableWithTwo = new Bindable() { + public Collection> createAndBindOutputs(BindingService adapter) { + return Arrays.asList(mock(Binding.class), mock(Binding.class)); + } + }; + Bindable bindableWithThree = new Bindable() { + public Collection> createAndBindOutputs(BindingService adapter) { + return Arrays.asList(mock(Binding.class), mock(Binding.class), mock(Binding.class)); + } + }; + Bindable bindableEmpty = new Bindable() {}; + + bindables.put("two", bindableWithTwo); + bindables.put("empty", bindableEmpty); + bindables.put("three", bindableWithThree); + + OutputBindingLifecycle lifecycle = new OutputBindingLifecycle(mock(BindingService.class), bindables); + lifecycle.start(); + + Collection> lifecycleOutputBindings = + (Collection>) new DirectFieldAccessor(lifecycle).getPropertyValue("outputBindings"); + assertTrue(lifecycleOutputBindings.size() == 5); + lifecycle.stop(); + } +}