Separate error channel tests, some cleanup

This commit is contained in:
Marius Bogoevici
2016-03-01 16:16:41 -05:00
parent cae56385e0
commit 5e2e4ecd67
8 changed files with 102 additions and 18 deletions

View File

@@ -31,7 +31,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.integration.config.EnableIntegration;
/**
* Enables the binding of {@link Input} and {@link Output} - annotated components to a broker, according to the list
* Enables the binding of components annotated with {@link Input} and {@link Output} to a broker, according to the list
* of interfaces passed as value to the annotation.
*
* @author Dave Syer

View File

@@ -44,11 +44,11 @@ public class BindableAdapter implements Bindable {
@Override
public Set<String> getInputs() {
return Collections.unmodifiableSet(Collections.EMPTY_SET);
return Collections.emptySet();
}
@Override
public Set<String> getOutputs() {
return Collections.unmodifiableSet(Collections.EMPTY_SET);
return Collections.emptySet();
}
}

View File

@@ -23,17 +23,19 @@ import java.util.Set;
import org.springframework.integration.channel.PublishSubscribeChannel;
/**
* A {@link Bindable} component that represents an error channel.
* A {@link Bindable} component that wraps a generic channel. Useful for binding channels outside the
* {@link org.springframework.cloud.stream.annotation.Input} and {@link org.springframework.cloud.stream.annotation.Output}
* annotated interfaces.
*
* @author Ilayaperumal Gopinathan
*/
public class BindableErrorChannel extends BindableAdapter {
public class SingleChannelBindable extends BindableAdapter {
private final String name;
private final PublishSubscribeChannel errorChannel;
public BindableErrorChannel(String name, PublishSubscribeChannel errorChannel) {
public SingleChannelBindable(String name, PublishSubscribeChannel errorChannel) {
this.name = name;
this.errorChannel = errorChannel;
}

View File

@@ -33,7 +33,6 @@ import org.springframework.boot.context.properties.ConfigurationPropertiesBindin
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.stream.binder.BinderFactory;
import org.springframework.cloud.stream.binding.BindableChannelFactory;
import org.springframework.cloud.stream.binding.BindableErrorChannel;
import org.springframework.cloud.stream.binding.BinderAwareChannelResolver;
import org.springframework.cloud.stream.binding.BinderAwareRouterBeanPostProcessor;
import org.springframework.cloud.stream.binding.ChannelBindingService;
@@ -45,6 +44,7 @@ import org.springframework.cloud.stream.binding.MessageChannelConfigurer;
import org.springframework.cloud.stream.binding.MessageConverterConfigurer;
import org.springframework.cloud.stream.binding.MessageHistoryTrackerConfigurer;
import org.springframework.cloud.stream.binding.OutputBindingLifecycle;
import org.springframework.cloud.stream.binding.SingleChannelBindable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
@@ -146,6 +146,13 @@ public class ChannelBindingServiceConfiguration {
return new BindingPropertiesConverter();
}
@Bean
@ConditionalOnProperty("spring.cloud.stream.bindings." + ERROR_CHANNEL_NAME + ".destination")
public SingleChannelBindable errorChannelBindable(
@Qualifier(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME) PublishSubscribeChannel errorChannel) {
return new SingleChannelBindable(ERROR_CHANNEL_NAME, errorChannel);
}
// IMPORTANT: Nested class to avoid instantiating all of the above early
@Configuration
protected static class PostProcessorConfiguration {
@@ -206,12 +213,4 @@ public class ChannelBindingServiceConfiguration {
};
}
}
@Bean
@ConditionalOnProperty("spring.cloud.stream.bindings." + ERROR_CHANNEL_NAME + ".destination")
public BindableErrorChannel bindableErrorChannel(
@Qualifier(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME) PublishSubscribeChannel errorChannel) {
return new BindableErrorChannel(ERROR_CHANNEL_NAME, errorChannel);
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2016 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 static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Matchers.same;
import java.util.Properties;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.cloud.stream.utils.MockBinderRegistryConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.messaging.MessageChannel;
/**
* @author Marius Bogoevici
*/
public class ErrorBindingTests {
@Test
public void testErrorChannelNotBoundByDefault() {
ConfigurableApplicationContext applicationContext = SpringApplication.run(TestProcessor.class, "--server.port=0");
BinderFactory<?> binderFactory = applicationContext.getBean(BinderFactory.class);
@SuppressWarnings("unchecked")
Binder<MessageChannel> binder = (Binder<MessageChannel>) binderFactory.getBinder(null);
Mockito.verify(binder).bindConsumer(eq("input"), isNull(String.class), any(MessageChannel.class), any(Properties.class));
Mockito.verify(binder).bindProducer(eq("output"), any(MessageChannel.class), any(Properties.class));
Mockito.verifyNoMoreInteractions(binder);
applicationContext.close();
}
@Test
public void testErrorChannelBoundIfConfigured() {
ConfigurableApplicationContext applicationContext =
SpringApplication.run(TestProcessor.class, "--spring.cloud.stream.bindings.error.destination=foo", "--server.port=0");
BinderFactory<?> binderFactory = applicationContext.getBean(BinderFactory.class);
@SuppressWarnings("unchecked")
Binder<MessageChannel> binder = (Binder<MessageChannel>) binderFactory.getBinder(null);
MessageChannel errorChannel = applicationContext.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME,
MessageChannel.class);
Mockito.verify(binder).bindConsumer(eq("input"), isNull(String.class), any(MessageChannel.class), any(Properties.class));
Mockito.verify(binder).bindProducer(eq("output"), any(MessageChannel.class), any(Properties.class));
Mockito.verify(binder).bindProducer(eq("foo"), same(errorChannel), any(Properties.class));
Mockito.verifyNoMoreInteractions(binder);
applicationContext.close();
}
@EnableBinding(Processor.class)
@EnableAutoConfiguration
@Import(MockBinderRegistryConfiguration.class)
public static class TestProcessor {
}
}

View File

@@ -64,7 +64,6 @@ public class SourceBindingTestsWithBindingTargets {
public void testSourceOutputChannelBound() {
verify(binder).bindProducer(eq("testtock"), eq(testSource.output()), Mockito.<Properties>any());
//Check error channel binding
verify(binder).bindProducer(eq("error-test"), eq(errorChannel), Mockito.<Properties>any());
verifyNoMoreInteractions(binder);
}

View File

@@ -29,6 +29,6 @@ public class MockBinderConfiguration {
@Bean
public Binder<?> binder() {
return Mockito.mock(Binder.class);
return Mockito.mock(Binder.class, Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS));
}
}

View File

@@ -1,2 +1 @@
spring.cloud.stream.bindings.output.destination=testtock
spring.cloud.stream.bindings.error.destination=error-test