Split test-binder from core spring-cloud-stream

* Remove all SI test-binder based components from core spring-cloud-stream-module
* Create a new module - spring-cloud-stream-test-binder that contains the test-binder
  and all it's related components
* Migrate tests from core module that use the test-binder into a separate module
  called spring-cloud-stream-integration-tests
* Remove the test-jar dependency using the classifier approach
* Update Spring Cloud Stream BOM with the new test-binder dependency
* Update Schema-Registry tests that use the old approach (using the test-jar with the classifier)
  with the new test-binder dependency

Resolves https://github.com/spring-cloud/spring-cloud-stream/issues/2565
This commit is contained in:
Soby Chacko
2022-11-22 18:28:49 -05:00
committed by Oleg Zhurakousky
parent 58ef5b0479
commit bc094e0ec4
44 changed files with 1382 additions and 1317 deletions

View File

@@ -25,11 +25,8 @@
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<artifactId>spring-cloud-stream-test-binder</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
<classifier>test-binder</classifier>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>

View File

@@ -16,7 +16,9 @@
<modules>
<module>spring-cloud-stream</module>
<module>spring-cloud-stream-test-binder</module>
<module>spring-cloud-stream-binder-test</module>
<module>spring-cloud-stream-integration-tests</module>
</modules>
</project>

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-integration-tests</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-stream-integration-tests</name>
<description>Spring Cloud Stream Integration Tests using Test Binder</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-core</artifactId>
<version>4.0.0-SNAPSHOT</version>
</parent>
<properties>
<kotlin.version>1.7.20-Beta</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-binder</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<source>src/main/java</source>
<source>src/test/kotlin</source>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -19,8 +19,9 @@ package org.springframework.cloud.stream.binder;
import java.util.Iterator;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.WebApplicationType;
@@ -46,42 +47,43 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Oleg Zhurakousky
* @since 1.2.2
*/
public class AbstractMessageChannelBinderTests {
@Disabled("This test has issues that needs to be looked into")
public class BasicAbstractMessageChannelBinderTests {
private ApplicationContext context;
private static ApplicationContext context;
@Before
public void prepare() {
this.context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration())
.web(WebApplicationType.NONE).run();
@BeforeAll
public static void prepare() {
context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration())
.web(WebApplicationType.NONE).run();
}
@Test
@SuppressWarnings("unchecked")
public void testEndpointLifecycle() throws Exception {
// @checkstyle:off
AbstractMessageChannelBinder<ConsumerProperties, ProducerProperties, ProvisioningProvider<ConsumerProperties, ProducerProperties>> binder = this.context
.getBean(AbstractMessageChannelBinder.class);
AbstractMessageChannelBinder<ConsumerProperties, ProducerProperties, ProvisioningProvider<ConsumerProperties, ProducerProperties>> binder = context
.getBean(AbstractMessageChannelBinder.class);
// @checkstyle:on
ConsumerProperties consumerProperties = new ConsumerProperties();
consumerProperties.setMaxAttempts(1); // to force error infrastructure creation
Binding<MessageChannel> consumerBinding = binder.bindConsumer("foo", "fooGroup",
new DirectChannel(), consumerProperties);
new DirectChannel(), consumerProperties);
DirectFieldAccessor consumerBindingAccessor = new DirectFieldAccessor(
consumerBinding);
consumerBinding);
MessageProducer messageProducer = (MessageProducer) consumerBindingAccessor
.getPropertyValue("lifecycle");
.getPropertyValue("lifecycle");
assertThat(((Lifecycle) messageProducer).isRunning()).isTrue();
assertThat(messageProducer.getOutputChannel()).isNotNull();
SubscribableChannel errorChannel = (SubscribableChannel) consumerBindingAccessor
.getPropertyValue("lifecycle.errorChannel");
.getPropertyValue("lifecycle.errorChannel");
assertThat(errorChannel).isNotNull();
Set<MessageHandler> handlers = TestUtils.getPropertyValue(errorChannel,
"dispatcher.handlers", Set.class);
"dispatcher.handlers", Set.class);
assertThat(handlers.size()).isEqualTo(2);
Iterator<MessageHandler> iterator = handlers.iterator();
assertThat(iterator.next()).isInstanceOf(BridgeHandler.class);
@@ -101,7 +103,7 @@ public class AbstractMessageChannelBinderTests {
ProducerProperties producerProps = new ProducerProperties();
producerProps.setErrorChannelEnabled(true);
Binding<MessageChannel> producerBinding = binder.bindProducer("bar",
new DirectChannel(), producerProps);
new DirectChannel(), producerProps);
assertThat(this.context.containsBean("bar.errors")).isTrue();
assertThat(this.context.containsBean("bar.errors.bridge")).isTrue();
producerBinding.unbind();
@@ -114,25 +116,25 @@ public class AbstractMessageChannelBinderTests {
public void testEndpointBinderHasRecoverer() throws Exception {
// @checkstyle:off
ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration())
.web(WebApplicationType.NONE).run();
TestChannelBinderConfiguration.getCompleteConfiguration())
.web(WebApplicationType.NONE).run();
AbstractMessageChannelBinder<ConsumerProperties, ProducerProperties, ProvisioningProvider<ConsumerProperties, ProducerProperties>> binder = context
.getBean(AbstractMessageChannelBinder.class);
.getBean(AbstractMessageChannelBinder.class);
// @checkstyle:on
Binding<MessageChannel> consumerBinding = binder.bindConsumer("foo", "fooGroup",
new DirectChannel(), new ConsumerProperties());
new DirectChannel(), new ConsumerProperties());
DirectFieldAccessor consumerBindingAccessor = new DirectFieldAccessor(
consumerBinding);
consumerBinding);
SubscribableChannel errorChannel = (SubscribableChannel) consumerBindingAccessor
.getPropertyValue("lifecycle.errorChannel");
.getPropertyValue("lifecycle.errorChannel");
assertThat(errorChannel).isNull();
errorChannel = (SubscribableChannel) consumerBindingAccessor
.getPropertyValue("lifecycle.recoveryCallback.channel");
.getPropertyValue("lifecycle.recoveryCallback.channel");
assertThat(errorChannel).isNotNull();
Set<MessageHandler> handlers = TestUtils.getPropertyValue(errorChannel,
"dispatcher.handlers", Set.class);
"dispatcher.handlers", Set.class);
assertThat(handlers.size()).isEqualTo(2);
Iterator<MessageHandler> iterator = handlers.iterator();
assertThat(iterator.next()).isInstanceOf(BridgeHandler.class);

View File

@@ -57,7 +57,7 @@ public class BinderErrorChannelTests {
BinderErrorChannel channel = new BinderErrorChannel();
DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(channel);
AbstractDispatcher dispatcher = (AbstractDispatcher) fieldAccessor
.getPropertyValue("dispatcher");
.getPropertyValue("dispatcher");
assertThat(dispatcher).isNotNull();
assertThat(channel.subscribers()).isEqualTo(0);

View File

@@ -41,13 +41,13 @@ public class ErrorBindingTests {
@Test
public void testConfigurationWithDefaultErrorHandler() {
ApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ErrorBindingTests.ErrorConfigurationDefault.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.handle-in-0.consumer.max-attempts=1",
"--spring.cloud.function.definition=handle",
"--spring.cloud.stream.default.error-handler-definition=errorHandler",
"--spring.jmx.enabled=false");
TestChannelBinderConfiguration.getCompleteConfiguration(
ErrorBindingTests.ErrorConfigurationDefault.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.handle-in-0.consumer.max-attempts=1",
"--spring.cloud.function.definition=handle",
"--spring.cloud.stream.default.error-handler-definition=errorHandler",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
source.send(new GenericMessage<byte[]>("Hello".getBytes()));
@@ -55,20 +55,20 @@ public class ErrorBindingTests {
source.send(new GenericMessage<byte[]>("Hello".getBytes()));
ErrorConfigurationDefault errorConfiguration = context
.getBean(ErrorConfigurationDefault.class);
.getBean(ErrorConfigurationDefault.class);
assertThat(errorConfiguration.counter).isEqualTo(6);
}
@Test
void testConfigurationWithBindingSpecificErrorHandler() {
ApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ErrorBindingTests.ErrorConfigurationWithCustomErrorHandler.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.handle-in-0.consumer.max-attempts=1",
"--spring.cloud.function.definition=handle",
"--spring.cloud.stream.bindings.handle-in-0.error-handler-definition=errorHandler",
"--spring.jmx.enabled=false");
TestChannelBinderConfiguration.getCompleteConfiguration(
ErrorBindingTests.ErrorConfigurationWithCustomErrorHandler.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.handle-in-0.consumer.max-attempts=1",
"--spring.cloud.function.definition=handle",
"--spring.cloud.stream.bindings.handle-in-0.error-handler-definition=errorHandler",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
source.send(new GenericMessage<byte[]>("Hello".getBytes()));
@@ -76,7 +76,7 @@ public class ErrorBindingTests {
source.send(new GenericMessage<byte[]>("Hello".getBytes()));
ErrorConfigurationWithCustomErrorHandler errorConfiguration = context
.getBean(ErrorConfigurationWithCustomErrorHandler.class);
.getBean(ErrorConfigurationWithCustomErrorHandler.class);
assertThat(errorConfiguration.counter).isEqualTo(6);
}

View File

@@ -77,20 +77,20 @@ public class PollableConsumerTests {
@BeforeAll
public void before() {
this.messageConverter = new CompositeMessageConverterFactory()
.getMessageConverterForAllRegistered();
.getMessageConverterForAllRegistered();
}
@Test
void testDefaultMessageSource() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setMaxAttempts(2);
properties.setBackOffInitialInterval(0);
binder.bindPollableConsumer("foo", "bar", pollableSource, properties);
@@ -106,23 +106,23 @@ public class PollableConsumerTests {
void testSimple() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
pollableSource.addInterceptor(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
return MessageBuilder
.withPayload(((String) message.getPayload()).toUpperCase())
.copyHeaders(message.getHeaders()).build();
.withPayload(((String) message.getPayload()).toUpperCase())
.copyHeaders(message.getHeaders()).build();
}
});
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setMaxAttempts(2);
properties.setBackOffInitialInterval(0);
binder.bindPollableConsumer("foo", "bar", pollableSource, properties);
@@ -130,7 +130,7 @@ public class PollableConsumerTests {
assertThat(pollableSource.poll(received -> {
assertThat(received.getPayload()).isEqualTo("POLLED DATA");
assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeType.valueOf("text/plain"));
.isEqualTo(MimeType.valueOf("text/plain"));
if (count.incrementAndGet() == 1) {
throw new RuntimeException("test retry");
}
@@ -142,16 +142,16 @@ public class PollableConsumerTests {
void testConvertSimple() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
binder.setMessageSourceDelegate(
() -> new GenericMessage<>("{\"foo\":\"bar\"}".getBytes()));
() -> new GenericMessage<>("{\"foo\":\"bar\"}".getBytes()));
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setMaxAttempts(1);
properties.setBackOffInitialInterval(0);
binder.bindPollableConsumer("foo", "bar", pollableSource, properties);
@@ -175,20 +175,20 @@ public class PollableConsumerTests {
void testConvertSimpler() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
BindingServiceProperties bsps = this.context
.getBean(BindingServiceProperties.class);
.getBean(BindingServiceProperties.class);
BindingProperties props = new BindingProperties();
props.setContentType("text/plain");
bsps.setBindings(Collections.singletonMap("foo", props));
binder.setMessageSourceDelegate(() -> new GenericMessage<>("foo".getBytes()));
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setMaxAttempts(1);
properties.setBackOffInitialInterval(0);
binder.bindPollableConsumer("foo", "bar", pollableSource, properties);
@@ -212,16 +212,16 @@ public class PollableConsumerTests {
void testConvertList() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
binder.setMessageSourceDelegate(() -> new GenericMessage<>(
"[{\"foo\":\"bar\"},{\"foo\":\"baz\"}]".getBytes()));
"[{\"foo\":\"bar\"},{\"foo\":\"baz\"}]".getBytes()));
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setMaxAttempts(1);
properties.setBackOffInitialInterval(0);
@@ -243,16 +243,16 @@ public class PollableConsumerTests {
void testConvertMap() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
binder.setMessageSourceDelegate(
() -> new GenericMessage<>("{\"qux\":{\"foo\":\"bar\"}}".getBytes()));
() -> new GenericMessage<>("{\"qux\":{\"foo\":\"bar\"}}".getBytes()));
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setMaxAttempts(1);
properties.setBackOffInitialInterval(0);
binder.bindPollableConsumer("foo", "bar", pollableSource, properties);
@@ -271,16 +271,16 @@ public class PollableConsumerTests {
void testEmbedded() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
binder.setMessageSourceDelegate(() -> {
MessageValues original = new MessageValues("foo".getBytes(),
Collections.singletonMap(MessageHeaders.CONTENT_TYPE,
"application/octet-stream"));
Collections.singletonMap(MessageHeaders.CONTENT_TYPE,
"application/octet-stream"));
byte[] payload = new byte[0];
try {
payload = EmbeddedHeaderUtils.embedHeaders(original,
MessageHeaders.CONTENT_TYPE);
MessageHeaders.CONTENT_TYPE);
}
catch (Exception e) {
fail(e.getMessage());
@@ -288,19 +288,19 @@ public class PollableConsumerTests {
return new GenericMessage<>(payload);
});
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setHeaderMode(HeaderMode.embeddedHeaders);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
pollableSource.addInterceptor(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
return MessageBuilder
.withPayload(
new String((byte[]) message.getPayload()).toUpperCase())
.copyHeaders(message.getHeaders()).build();
.withPayload(
new String((byte[]) message.getPayload()).toUpperCase())
.copyHeaders(message.getHeaders()).build();
}
});
@@ -308,7 +308,7 @@ public class PollableConsumerTests {
assertThat(pollableSource.poll(received -> {
assertThat(received.getPayload()).isEqualTo("FOO");
assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo("application/octet-stream");
.isEqualTo("application/octet-stream");
})).isTrue();
}
@@ -316,32 +316,32 @@ public class PollableConsumerTests {
void testErrors() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
pollableSource.addInterceptor(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
return MessageBuilder
.withPayload(((String) message.getPayload()).toUpperCase())
.copyHeaders(message.getHeaders()).build();
.withPayload(((String) message.getPayload()).toUpperCase())
.copyHeaders(message.getHeaders()).build();
}
});
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setMaxAttempts(2);
properties.setBackOffInitialInterval(0);
properties.getRetryableExceptions().put(IllegalStateException.class, false);
binder.bindPollableConsumer("foo", "bar", pollableSource, properties);
final CountDownLatch latch = new CountDownLatch(1);
this.context.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME,
SubscribableChannel.class).subscribe(m -> {
latch.countDown();
});
SubscribableChannel.class).subscribe(m -> {
latch.countDown();
});
final AtomicInteger count = new AtomicInteger();
assertThat(pollableSource.poll(received -> {
count.incrementAndGet();
@@ -351,7 +351,7 @@ public class PollableConsumerTests {
Message<?> lastError = binder.getLastError();
assertThat(lastError).isNotNull();
assertThat(((Exception) lastError.getPayload()).getCause().getMessage())
.isEqualTo("test recoverer");
.isEqualTo("test recoverer");
assertThat(pollableSource.poll(received -> {
count.incrementAndGet();
throw new IllegalStateException("no retries");
@@ -360,37 +360,37 @@ public class PollableConsumerTests {
lastError = binder.getLastError();
assertThat(lastError).isNotNull();
assertThat(((Exception) lastError.getPayload()).getCause().getMessage())
.isEqualTo("no retries");
.isEqualTo("no retries");
}
@Test
void testErrorsNoRetry() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
pollableSource.addInterceptor(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
return MessageBuilder
.withPayload(((String) message.getPayload()).toUpperCase())
.copyHeaders(message.getHeaders()).build();
.withPayload(((String) message.getPayload()).toUpperCase())
.copyHeaders(message.getHeaders()).build();
}
});
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setMaxAttempts(1);
binder.bindPollableConsumer("foo", "bar", pollableSource, properties);
final CountDownLatch latch = new CountDownLatch(1);
this.context.getBean(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME,
SubscribableChannel.class).subscribe(m -> {
latch.countDown();
});
SubscribableChannel.class).subscribe(m -> {
latch.countDown();
});
final AtomicInteger count = new AtomicInteger();
assertThat(pollableSource.poll(received -> {
count.incrementAndGet();
@@ -403,10 +403,10 @@ public class PollableConsumerTests {
void testRequeue() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
AcknowledgmentCallback callback = mock(AcknowledgmentCallback.class);
pollableSource.addInterceptor(new ChannelInterceptor() {
@@ -414,10 +414,10 @@ public class PollableConsumerTests {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
return MessageBuilder.fromMessage(message)
.setHeader(
IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK,
callback)
.build();
.setHeader(
IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK,
callback)
.build();
}
});
@@ -443,17 +443,17 @@ public class PollableConsumerTests {
void testRequeueWithNoAcknowledgementCallback() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
pollableSource.addInterceptor(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
return MessageBuilder.fromMessage(message)
.build();
.build();
}
});
@@ -476,10 +476,10 @@ public class PollableConsumerTests {
void testRequeueFromErrorFlow() {
TestChannelBinder binder = createBinder();
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
AcknowledgmentCallback callback = mock(AcknowledgmentCallback.class);
pollableSource.addInterceptor(new ChannelInterceptor() {
@@ -487,10 +487,10 @@ public class PollableConsumerTests {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
return MessageBuilder.fromMessage(message)
.setHeader(
IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK,
callback)
.build();
.setHeader(
IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK,
callback)
.build();
}
});
@@ -518,19 +518,19 @@ public class PollableConsumerTests {
void testAutoStartupOff() {
TestChannelBinder binder = createBinder();
binder.setMessageSourceDelegate(new LifecycleMessageSource(
() -> new GenericMessage<>("{\"foo\":\"bar\"}".getBytes())));
() -> new GenericMessage<>("{\"foo\":\"bar\"}".getBytes())));
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setAutoStartup(false);
Binding<PollableSource<MessageHandler>> pollableSourceBinding = binder
.bindPollableConsumer("foo", "bar", pollableSource, properties);
.bindPollableConsumer("foo", "bar", pollableSource, properties);
assertThat(pollableSourceBinding.isRunning()).isFalse();
}
@@ -540,27 +540,27 @@ public class PollableConsumerTests {
void testAutoStartupOn() {
TestChannelBinder binder = createBinder();
binder.setMessageSourceDelegate(new LifecycleMessageSource(
() -> new GenericMessage<>("{\"foo\":\"bar\"}".getBytes())));
() -> new GenericMessage<>("{\"foo\":\"bar\"}".getBytes())));
MessageConverterConfigurer configurer = this.context
.getBean(MessageConverterConfigurer.class);
.getBean(MessageConverterConfigurer.class);
DefaultPollableMessageSource pollableSource = new DefaultPollableMessageSource(
this.messageConverter);
this.messageConverter);
configurer.configurePolledMessageSource(pollableSource, "foo");
ExtendedConsumerProperties<Object> properties = new ExtendedConsumerProperties<>(
null);
null);
properties.setAutoStartup(true);
Binding<PollableSource<MessageHandler>> pollableSourceBinding = binder
.bindPollableConsumer("foo", "bar", pollableSource, properties);
.bindPollableConsumer("foo", "bar", pollableSource, properties);
assertThat(pollableSourceBinding.isRunning()).isTrue();
}
private TestChannelBinder createBinder(String... args) {
this.context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration())
.web(WebApplicationType.NONE).run(args);
TestChannelBinderConfiguration.getCompleteConfiguration())
.web(WebApplicationType.NONE).run(args);
TestChannelBinder binder = this.context.getBean(TestChannelBinder.class);
return binder;
}

View File

@@ -64,8 +64,8 @@ public class ContentTypeTckTests {
@Test
void stringToMapMessageStreamListener() {
ApplicationContext context = new SpringApplicationBuilder(
StringToMapMessageConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
StringToMapMessageConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
@@ -77,327 +77,327 @@ public class ContentTypeTckTests {
@Test
void pojoToPojo() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
PojoToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void pojoToString() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToStringConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
PojoToStringConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
.isEqualTo("oleg");
}
@Test
void pojoToStringOutboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToStringConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-out-0.contentType=text/plain",
"--spring.jmx.enabled=false");
PojoToStringConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-out-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
.isEqualTo("oleg");
}
@Test
void pojoToByteArray() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
PojoToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
.isEqualTo("oleg");
}
@Test
void pojoToByteArrayOutboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToByteArrayConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false");
PojoToByteArrayConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
.isEqualTo("oleg");
}
@Test
void stringToPojoInboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
StringToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-on-0.contentType=text/plain",
"--spring.jmx.enabled=false");
StringToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-on-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void typelessToPojoInboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void typelessToPojoInboundContentTypeBindingJson() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=application/json",
"--spring.jmx.enabled=false");
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=application/json",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void typelessMessageToPojoInboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessMessageToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
TypelessMessageToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void typelessMessageToPojoInboundContentTypeBindingJson() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessMessageToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.echo-in-0.contentType=application/json",
"--spring.jmx.enabled=false");
TypelessMessageToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.echo-in-0.contentType=application/json",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void typelessToPojoWithTextHeaderContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(MessageBuilder.withPayload(jsonPayload.getBytes())
.setHeader(MessageHeaders.CONTENT_TYPE, MimeType.valueOf("text/plain"))
.build());
.setHeader(MessageHeaders.CONTENT_TYPE, MimeType.valueOf("text/plain"))
.build());
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void typelessToPojoOutboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToMessageConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-out-0.contentType=text/plain",
"--spring.jmx.enabled=false");
TypelessToMessageConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-out-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(MessageBuilder.withPayload(jsonPayload.getBytes())
.setHeader("contentType", new MimeType("text", "plain")).build());
.setHeader("contentType", new MimeType("text", "plain")).build());
Message<byte[]> outputMessage = target.receive();
System.out.println(new String(outputMessage.getPayload()));
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
assertThat(outputMessage.getPayload())
.isEqualTo(jsonPayload.getBytes());
.isEqualTo(jsonPayload.getBytes());
}
@Test
void outboundMessageWithTextContentTypeOnly() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToMessageTextOnlyContentTypeConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
TypelessToMessageTextOnlyContentTypeConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(MessageBuilder.withPayload(jsonPayload.getBytes())
.setHeader("contentType", new MimeType("text")).build());
.setHeader("contentType", new MimeType("text")).build());
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString())
.startsWith("text/");
.startsWith("text/");
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void stringToPojoInboundContentTypeHeader() {
ApplicationContext context = new SpringApplicationBuilder(
StringToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
StringToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes(),
new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE,
MimeTypeUtils.TEXT_PLAIN))));
new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE,
MimeTypeUtils.TEXT_PLAIN))));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void byteArrayToPojoInboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
ByteArrayToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
ByteArrayToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void byteArrayToPojoInboundContentTypeHeader() {
ApplicationContext context = new SpringApplicationBuilder(
StringToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
StringToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes(),
new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE,
MimeTypeUtils.TEXT_PLAIN))));
new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE,
MimeTypeUtils.TEXT_PLAIN))));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void byteArrayToByteArray() {
ApplicationContext context = new SpringApplicationBuilder(
ByteArrayToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
ByteArrayToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void byteArrayToByteArrayInboundOutboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
ByteArrayToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.input.contentType=text/plain",
"--spring.cloud.stream.bindings.output.contentType=text/plain",
"--spring.jmx.enabled=false");
ByteArrayToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.input.contentType=text/plain",
"--spring.cloud.stream.bindings.output.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void pojoMessageToStringMessage() {
ApplicationContext context = new SpringApplicationBuilder(
PojoMessageToStringMessageConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
PojoMessageToStringMessageConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
.isEqualTo("oleg");
}
@Test
void customMessageConverter_defaultContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
StringToStringConfiguration.class, CustomConverters.class)
.web(WebApplicationType.NONE)
.run("--spring.cloud.stream.default.contentType=foo/bar",
"--spring.jmx.enabled=false");
StringToStringConfiguration.class, CustomConverters.class)
.web(WebApplicationType.NONE)
.run("--spring.cloud.stream.default.contentType=foo/bar",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
@@ -405,9 +405,9 @@ public class ContentTypeTckTests {
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage).isNotNull();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("FooBarMessageConverter");
.isEqualTo("FooBarMessageConverter");
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo("foo/bar");
.isEqualTo("foo/bar");
}
// Failure tests
@@ -415,38 +415,38 @@ public class ContentTypeTckTests {
@Test
void _jsonToPojoWrongDefaultContentTypeProperty() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.default.contentType=text/plain",
"--spring.jmx.enabled=false");
PojoToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.default.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
TestChannelBinder binder = context.getBean(TestChannelBinder.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
assertThat(binder.getLastError().getPayload() instanceof MessagingException)
.isTrue();
.isTrue();
}
@Test
@Disabled
void _toStringDefaultContentTypePropertyUnknownContentType() {
ApplicationContext context = new SpringApplicationBuilder(
StringToStringConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.default.contentType=foo/bar",
"--spring.jmx.enabled=false");
StringToStringConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.default.contentType=foo/bar",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
TestChannelBinder binder = context.getBean(TestChannelBinder.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
assertThat(
binder.getLastError().getPayload() instanceof MessageConversionException)
.isTrue();
binder.getLastError().getPayload() instanceof MessageConversionException)
.isTrue();
}
@Test
void toCollectionWithParameterizedType() {
ApplicationContext context = new SpringApplicationBuilder(
CollectionWithParameterizedTypes.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
CollectionWithParameterizedTypes.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "[{\"person\":{\"name\":\"jon\"},\"id\":123},{\"person\":{\"name\":\"jane\"},\"id\":456}]";
@@ -459,61 +459,61 @@ public class ContentTypeTckTests {
@Test
void testWithMapInputParameter() {
ApplicationContext context = new SpringApplicationBuilder(
MapInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
MapInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void testWithMapPayloadParameter() {
ApplicationContext context = new SpringApplicationBuilder(
MapInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
MapInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
void testWithListInputParameter() {
ApplicationContext context = new SpringApplicationBuilder(
ListInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--debug");
ListInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--debug");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "[\"foo\",\"bar\"]";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
.isEqualTo(jsonPayload);
}
@Test
@Disabled // TODO fix it. We can recognize MessageHeaders and parse it out of the message properly
void testWithMessageHeadersInputParameter() {
ApplicationContext context = new SpringApplicationBuilder(
MessageHeadersInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
MessageHeadersInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isNotEqualTo(jsonPayload);
.isNotEqualTo(jsonPayload);
assertThat(outputMessage.getHeaders().containsKey(MessageHeaders.ID)).isTrue();
assertThat(outputMessage.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE))
.isTrue();
.isTrue();
}
@@ -587,8 +587,8 @@ public class ContentTypeTckTests {
@Bean
public Function<Object, Person> echo(JsonMapper mapper) {
return value -> value instanceof byte[]
? mapper.fromJson((byte[]) value, Person.class)
: mapper.fromJson((String) value, Person.class);
? mapper.fromJson((byte[]) value, Person.class)
: mapper.fromJson((String) value, Person.class);
}
}
@@ -599,8 +599,8 @@ public class ContentTypeTckTests {
@Bean
public Function<Message<?>, Person> echo(JsonMapper mapper) {
return message -> message.getPayload() instanceof byte[]
? mapper.fromJson((byte[]) message.getPayload(), Person.class)
: mapper.fromJson((String) message.getPayload(), Person.class);
? mapper.fromJson((byte[]) message.getPayload(), Person.class)
: mapper.fromJson((String) message.getPayload(), Person.class);
}
}
@@ -611,7 +611,7 @@ public class ContentTypeTckTests {
@Bean
public Function<Object, Message<?>> echo() {
return value -> MessageBuilder.withPayload(value.toString())
.setHeader("contentType", new MimeType("text", "plain")).build();
.setHeader("contentType", new MimeType("text", "plain")).build();
}
}
@@ -623,7 +623,7 @@ public class ContentTypeTckTests {
public Function<?, Message<?>> echo() {
return value -> {
return MessageBuilder.withPayload(value.toString())
.setHeader("expected-content-type", "text/*").build();
.setHeader("expected-content-type", "text/*").build();
};
}
}
@@ -669,8 +669,8 @@ public class ContentTypeTckTests {
@Bean
public Function<Message<Person>, Message<String>> echo() {
return value -> MessageBuilder.withPayload(value.getPayload().toString())
.setHeader("expected-content-type", MimeTypeUtils.TEXT_PLAIN_VALUE)
.build();
.setHeader("expected-content-type", MimeTypeUtils.TEXT_PLAIN_VALUE)
.build();
}
}
@@ -736,7 +736,7 @@ public class ContentTypeTckTests {
@Bean
public AlwaysStringKryoMessageConverter kryoOverrideMessageConverter() {
return new AlwaysStringKryoMessageConverter(
MimeType.valueOf("application/x-java-object"));
MimeType.valueOf("application/x-java-object"));
}
/**
@@ -746,7 +746,7 @@ public class ContentTypeTckTests {
*
*/
public static class AlwaysStringKryoMessageConverter
extends AbstractMessageConverter {
extends AbstractMessageConverter {
public AlwaysStringKryoMessageConverter(MimeType supportedMimeType) {
super(supportedMimeType);
@@ -759,13 +759,13 @@ public class ContentTypeTckTests {
@Override
protected Object convertFromInternal(Message<?> message, Class<?> targetClass,
@Nullable Object conversionHint) {
@Nullable Object conversionHint) {
return this.getClass().getSimpleName();
}
@Override
protected Object convertToInternal(Object payload,
@Nullable MessageHeaders headers, @Nullable Object conversionHint) {
@Nullable MessageHeaders headers, @Nullable Object conversionHint) {
return ((String) payload).getBytes(StandardCharsets.UTF_8);
}
@@ -784,13 +784,13 @@ public class ContentTypeTckTests {
@Override
protected Object convertFromInternal(Message<?> message, Class<?> targetClass,
@Nullable Object conversionHint) {
@Nullable Object conversionHint) {
return this.getClass().getSimpleName();
}
@Override
protected Object convertToInternal(Object payload,
@Nullable MessageHeaders headers, @Nullable Object conversionHint) {
@Nullable MessageHeaders headers, @Nullable Object conversionHint) {
return ((String) payload).getBytes(StandardCharsets.UTF_8);
}

View File

@@ -45,18 +45,18 @@ public class ErrorHandlingTests {
@Test
void testGlobalErrorWithMessage() {
ApplicationContext context = new SpringApplicationBuilder(GlobalErrorHandlerWithErrorMessageConfig.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
source.send(new GenericMessage<>("foo".getBytes()));
GlobalErrorHandlerWithErrorMessageConfig config = context
.getBean(GlobalErrorHandlerWithErrorMessageConfig.class);
.getBean(GlobalErrorHandlerWithErrorMessageConfig.class);
assertThat(config.globalErroInvoked).isTrue();
}
@Test
void testGlobalErrorWithThrowable() {
ApplicationContext context = new SpringApplicationBuilder(GlobalErrorHandlerWithThrowableConfig.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
source.send(new GenericMessage<>("foo".getBytes()));
GlobalErrorHandlerWithThrowableConfig config = context.getBean(GlobalErrorHandlerWithThrowableConfig.class);

View File

@@ -57,7 +57,7 @@ import org.springframework.cloud.stream.config.BindingProperties;
import org.springframework.cloud.stream.config.BindingServiceConfiguration;
import org.springframework.cloud.stream.config.BindingServiceProperties;
import org.springframework.cloud.stream.reflection.GenericsUtils;
import org.springframework.cloud.stream.utils.MockBinderConfiguration;
import org.springframework.cloud.stream.utils.IntegrationTestsMockBinderConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -108,15 +108,15 @@ public class BindingServiceTests {
MessageChannel inputChannel = new DirectChannel();
Binding<MessageChannel> mockBinding = Mockito.mock(Binding.class);
when(binder.bindConsumer(eq("foo"), isNull(), same(inputChannel),
any(ConsumerProperties.class))).thenReturn(mockBinding);
any(ConsumerProperties.class))).thenReturn(mockBinding);
Collection<Binding<MessageChannel>> bindings = service.bindConsumer(inputChannel,
inputChannelName);
inputChannelName);
assertThat(bindings).hasSize(1);
Binding<MessageChannel> binding = bindings.iterator().next();
assertThat(binding).isSameAs(mockBinding);
service.unbindConsumers(inputChannelName);
verify(binder).bindConsumer(eq("foo"), isNull(), same(inputChannel),
any(ConsumerProperties.class));
any(ConsumerProperties.class));
verify(binding).unbind();
binderFactory.destroy();
}
@@ -143,12 +143,12 @@ public class BindingServiceTests {
Binding<MessageChannel> mockBinding2 = Mockito.mock(Binding.class);
when(binder.bindConsumer(eq("foo"), isNull(), same(inputChannel),
any(ConsumerProperties.class))).thenReturn(mockBinding1);
any(ConsumerProperties.class))).thenReturn(mockBinding1);
when(binder.bindConsumer(eq("bar"), isNull(), same(inputChannel),
any(ConsumerProperties.class))).thenReturn(mockBinding2);
any(ConsumerProperties.class))).thenReturn(mockBinding2);
Collection<Binding<MessageChannel>> bindings = service.bindConsumer(inputChannel,
"input");
"input");
assertThat(bindings).hasSize(2);
Iterator<Binding<MessageChannel>> iterator = bindings.iterator();
@@ -161,9 +161,9 @@ public class BindingServiceTests {
service.unbindConsumers("input");
verify(binder).bindConsumer(eq("foo"), isNull(), same(inputChannel),
any(ConsumerProperties.class));
any(ConsumerProperties.class));
verify(binder).bindConsumer(eq("bar"), isNull(), same(inputChannel),
any(ConsumerProperties.class));
any(ConsumerProperties.class));
verify(binding1).unbind();
verify(binding2).unbind();
@@ -257,10 +257,10 @@ public class BindingServiceTests {
Binding<MessageChannel> mockBinding1 = Mockito.mock(Binding.class);
when(binder.bindConsumer(eq("foo,bar"), isNull(), same(inputChannel),
any(ConsumerProperties.class))).thenReturn(mockBinding1);
any(ConsumerProperties.class))).thenReturn(mockBinding1);
Collection<Binding<MessageChannel>> bindings = service.bindConsumer(inputChannel,
"input");
"input");
assertThat(bindings).hasSize(1);
Iterator<Binding<MessageChannel>> iterator = bindings.iterator();
@@ -271,7 +271,7 @@ public class BindingServiceTests {
service.unbindConsumers("input");
verify(binder).bindConsumer(eq("foo,bar"), isNull(), same(inputChannel),
any(ConsumerProperties.class));
any(ConsumerProperties.class));
verify(binding1).unbind();
binderFactory.destroy();
@@ -294,16 +294,16 @@ public class BindingServiceTests {
MessageChannel inputChannel = new DirectChannel();
Binding<MessageChannel> mockBinding = Mockito.mock(Binding.class);
when(binder.bindConsumer(eq("foo"), eq("fooGroup"), same(inputChannel),
any(ConsumerProperties.class))).thenReturn(mockBinding);
any(ConsumerProperties.class))).thenReturn(mockBinding);
Collection<Binding<MessageChannel>> bindings = service.bindConsumer(inputChannel,
inputChannelName);
inputChannelName);
assertThat(bindings).hasSize(1);
Binding<MessageChannel> binding = bindings.iterator().next();
assertThat(binding).isSameAs(mockBinding);
service.unbindConsumers(inputChannelName);
verify(binder).bindConsumer(eq("foo"), eq(props.getGroup()), same(inputChannel),
any(ConsumerProperties.class));
any(ConsumerProperties.class));
verify(binding).unbind();
binderFactory.destroy();
}
@@ -330,32 +330,32 @@ public class BindingServiceTests {
}
catch (IllegalStateException e) {
assertThat(e)
.hasMessageContaining("Partition count should be greater than zero.");
.hasMessageContaining("Partition count should be greater than zero.");
}
}
@Test
void testDefaultPropertyBehavior() {
ConfigurableApplicationContext run = SpringApplication.run(
DefaultConsumerPropertiesTestSink.class,
"--server.port=0",
"--spring.cloud.stream.output-bindings=output1",
"--spring.cloud.stream.input-bindings=inputFooBarBuzz",
"--spring.cloud.stream.default.contentType=text/plain",
"--spring.cloud.stream.bindings.input1.contentType=application/json",
"--spring.cloud.stream.default.group=foo",
"--spring.cloud.stream.bindings.input2.group=bar",
"--spring.cloud.stream.default.consumer.concurrency=5",
"--spring.cloud.stream.bindings.input2.consumer.concurrency=1",
"--spring.cloud.stream.bindings.input1.consumer.partitioned=true",
"--spring.cloud.stream.default.producer.partitionCount=10",
"--spring.cloud.stream.bindings.output2.producer.partitionCount=1",
"--spring.cloud.stream.bindings.inputXyz.contentType=application/json",
"--spring.cloud.stream.bindings.inputFooBar.contentType=application/avro",
"--spring.cloud.stream.bindings.input_snake_case.contentType=application/avro");
DefaultConsumerPropertiesTestSink.class,
"--server.port=0",
"--spring.cloud.stream.output-bindings=output1",
"--spring.cloud.stream.input-bindings=inputFooBarBuzz",
"--spring.cloud.stream.default.contentType=text/plain",
"--spring.cloud.stream.bindings.input1.contentType=application/json",
"--spring.cloud.stream.default.group=foo",
"--spring.cloud.stream.bindings.input2.group=bar",
"--spring.cloud.stream.default.consumer.concurrency=5",
"--spring.cloud.stream.bindings.input2.consumer.concurrency=1",
"--spring.cloud.stream.bindings.input1.consumer.partitioned=true",
"--spring.cloud.stream.default.producer.partitionCount=10",
"--spring.cloud.stream.bindings.output2.producer.partitionCount=1",
"--spring.cloud.stream.bindings.inputXyz.contentType=application/json",
"--spring.cloud.stream.bindings.inputFooBar.contentType=application/avro",
"--spring.cloud.stream.bindings.input_snake_case.contentType=application/avro");
BindingServiceProperties bindingServiceProperties = run.getBeanFactory()
.getBean(BindingServiceProperties.class);
.getBean(BindingServiceProperties.class);
Map<String, BindingProperties> bindings = bindingServiceProperties.getBindings();
assertThat(bindings.get("input1").getContentType()).isEqualTo("application/json");
@@ -367,18 +367,18 @@ public class BindingServiceTests {
assertThat(bindings.get("input1").getConsumer().isPartitioned()).isEqualTo(true);
assertThat(bindings.get("input2").getConsumer().isPartitioned()).isEqualTo(false);
assertThat(bindings.get("output1-out-0").getProducer().getPartitionCount())
.isEqualTo(10);
.isEqualTo(10);
assertThat(bindings.get("output2").getProducer().getPartitionCount())
.isEqualTo(1);
.isEqualTo(1);
assertThat(bindings.get("inputXyz").getContentType())
.isEqualTo("application/json");
.isEqualTo("application/json");
assertThat(bindings.get("inputFooBar").getContentType())
.isEqualTo("application/avro");
.isEqualTo("application/avro");
assertThat(bindings.get("inputFooBarBuzz-in-0").getContentType())
.isEqualTo("text/plain");
.isEqualTo("text/plain");
assertThat(bindings.get("input_snake_case").getContentType())
.isEqualTo("application/avro");
.isEqualTo("application/avro");
run.close();
}
@@ -405,7 +405,7 @@ public class BindingServiceTests {
}
catch (IllegalStateException e) {
assertThat(e)
.hasMessageContaining("Concurrency should be greater than zero.");
.hasMessageContaining("Concurrency should be greater than zero.");
}
}
@@ -417,9 +417,9 @@ public class BindingServiceTests {
properties.put("spring.cloud.stream.bindings.output.destination", "fooOutput");
properties.put("spring.cloud.stream.bindings.output.binder", "mockError");
BindingServiceProperties bindingServiceProperties = createBindingServiceProperties(
properties);
properties);
BindingService bindingService = new BindingService(bindingServiceProperties,
createMockBinderFactory(), new ObjectMapper());
createMockBinderFactory(), new ObjectMapper());
bindingService.bindConsumer(new DirectChannel(), "input");
try {
bindingService.bindProducer(new DirectChannel(), "output");
@@ -440,12 +440,12 @@ public class BindingServiceTests {
properties.put("spring.cloud.stream.binders.mock1.type", "mock");
properties.put("spring.cloud.stream.binders.kafka1.type", "kafka");
BindingServiceProperties bindingServiceProperties = createBindingServiceProperties(
properties);
properties);
BinderFactory binderFactory = new BindingServiceConfiguration()
.binderFactory(createMockBinderTypeRegistry(), bindingServiceProperties, Mockito.mock(ObjectProvider.class),
Mockito.mock(BinderChildContextInitializer.class));
.binderFactory(createMockBinderTypeRegistry(), bindingServiceProperties, Mockito.mock(ObjectProvider.class),
Mockito.mock(BinderChildContextInitializer.class));
BindingService bindingService = new BindingService(bindingServiceProperties,
binderFactory, new ObjectMapper());
binderFactory, new ObjectMapper());
bindingService.bindConsumer(new DirectChannel(), "input");
bindingService.bindProducer(new DirectChannel(), "output");
}
@@ -461,12 +461,12 @@ public class BindingServiceTests {
properties.put("spring.cloud.stream.binders.mock1.type", "mock");
properties.put("spring.cloud.stream.binders.kafka1.type", "kafka");
BindingServiceProperties bindingServiceProperties = createBindingServiceProperties(
properties);
properties);
BinderFactory binderFactory = new BindingServiceConfiguration()
.binderFactory(createMockBinderTypeRegistry(), bindingServiceProperties, Mockito.mock(ObjectProvider.class),
Mockito.mock(BinderChildContextInitializer.class));
.binderFactory(createMockBinderTypeRegistry(), bindingServiceProperties, Mockito.mock(ObjectProvider.class),
Mockito.mock(BinderChildContextInitializer.class));
BindingService bindingService = new BindingService(bindingServiceProperties,
binderFactory, new ObjectMapper());
binderFactory, new ObjectMapper());
bindingService.bindConsumer(new DirectChannel(), "input");
try {
bindingService.bindProducer(new DirectChannel(), "output");
@@ -480,7 +480,7 @@ public class BindingServiceTests {
@Test
void testResolveBindableType() {
Class<?> bindableType = GenericsUtils.getParameterType(FooBinder.class,
Binder.class, 0);
Binder.class, 0);
assertThat(bindableType).isSameAs(SomeBindableType.class);
}
@@ -510,9 +510,9 @@ public class BindingServiceTests {
}
return mockBinding;
}).when(binder).bindProducer(eq("foo"), same(outputChannel),
any(ProducerProperties.class));
any(ProducerProperties.class));
Binding<MessageChannel> binding = service.bindProducer(outputChannel,
outputChannelName);
outputChannelName);
assertThat(fail.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(binding).isNotNull();
Binding delegate = TestUtils.getPropertyValue(binding, "delegate", Binding.class);
@@ -524,7 +524,7 @@ public class BindingServiceTests {
assertThat(delegate).isSameAs(mockBinding);
service.unbindProducers(outputChannelName);
verify(binder, times(2)).bindProducer(eq("foo"), same(outputChannel),
any(ProducerProperties.class));
any(ProducerProperties.class));
verify(delegate).unbind();
binderFactory.destroy();
scheduler.destroy();
@@ -534,12 +534,12 @@ public class BindingServiceTests {
@Test
void testBindingAutostartup() throws Exception {
ApplicationContext context = new SpringApplicationBuilder(FooConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.input-in-0.consumer.auto-startup=false");
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.input-in-0.consumer.auto-startup=false");
BindingService bindingService = context.getBean(BindingService.class);
Field cbField = ReflectionUtils.findField(BindingService.class,
"consumerBindings");
"consumerBindings");
cbField.setAccessible(true);
Map<String, Object> cbMap = (Map<String, Object>) cbField.get(bindingService);
Binding<?> inputBinding = ((List<Binding<?>>) cbMap.get("input-in-0")).get(0);
@@ -563,25 +563,25 @@ public class BindingServiceTests {
private DefaultBinderFactory createMockBinderFactory() {
BinderTypeRegistry binderTypeRegistry = createMockBinderTypeRegistry();
return new DefaultBinderFactory(
Collections.singletonMap("mock",
new BinderConfiguration("mock", new HashMap<>(), true, true)),
binderTypeRegistry, null);
Collections.singletonMap("mock",
new BinderConfiguration("mock", new HashMap<>(), true, true)),
binderTypeRegistry, null);
}
private DefaultBinderTypeRegistry createMockBinderTypeRegistry() {
return new DefaultBinderTypeRegistry(Collections.singletonMap("mock",
new BinderType("mock", new Class[] { MockBinderConfiguration.class })));
new BinderType("mock", new Class[] { IntegrationTestsMockBinderConfiguration.class })));
}
private BindingServiceProperties createBindingServiceProperties(
HashMap<String, String> properties) {
HashMap<String, String> properties) {
BindingServiceProperties bindingServiceProperties = new BindingServiceProperties();
org.springframework.boot.context.properties.bind.Binder propertiesBinder;
propertiesBinder = new org.springframework.boot.context.properties.bind.Binder(
new MapConfigurationPropertySource(properties));
new MapConfigurationPropertySource(properties));
propertiesBinder.bind("spring.cloud.stream",
org.springframework.boot.context.properties.bind.Bindable
.ofInstance(bindingServiceProperties));
org.springframework.boot.context.properties.bind.Bindable
.ofInstance(bindingServiceProperties));
return bindingServiceProperties;
}
@@ -614,19 +614,19 @@ public class BindingServiceTests {
}
public static class FooBinder
implements Binder<SomeBindableType, ConsumerProperties, ProducerProperties> {
implements Binder<SomeBindableType, ConsumerProperties, ProducerProperties> {
@Override
public Binding<SomeBindableType> bindConsumer(String name, String group,
SomeBindableType inboundBindTarget,
ConsumerProperties consumerProperties) {
SomeBindableType inboundBindTarget,
ConsumerProperties consumerProperties) {
throw new UnsupportedOperationException();
}
@Override
public Binding<SomeBindableType> bindProducer(String name,
SomeBindableType outboundBindTarget,
ProducerProperties producerProperties) {
SomeBindableType outboundBindTarget,
ProducerProperties producerProperties) {
throw new UnsupportedOperationException();
}

View File

@@ -43,11 +43,11 @@ public class ExplicitBindingTests {
@Test
void testExplicitBindings() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.input-bindings=fooin;barin",
"--spring.cloud.stream.output-bindings=fooout;barout")) {
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.input-bindings=fooin;barin",
"--spring.cloud.stream.output-bindings=fooout;barout")) {
assertThat(context.getBean("fooin-in-0", MessageChannel.class)).isNotNull();
assertThat(context.getBean("barin-in-0", MessageChannel.class)).isNotNull();
@@ -59,10 +59,10 @@ public class ExplicitBindingTests {
@Test
void testExplicitBindingsWithExistingConsumer() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(ConsumerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.output-bindings=consume")) {
TestChannelBinderConfiguration.getCompleteConfiguration(ConsumerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.output-bindings=consume")) {
assertThat(context.getBean("consume-in-0", MessageChannel.class)).isNotNull();
assertThat(context.getBean("consume-out-0", MessageChannel.class)).isNotNull();
@@ -73,11 +73,11 @@ public class ExplicitBindingTests {
@Test
void testExplicitBindingsWithExistingSupplier() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.input-bindings=supply",
"--spring.cloud.stream.bindings.supply-out-0.producer.poller.fixed-delay=3000")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.input-bindings=supply",
"--spring.cloud.stream.bindings.supply-out-0.producer.poller.fixed-delay=3000")) {
assertThat(context.getBean("supply-in-0", MessageChannel.class)).isNotNull();

View File

@@ -56,15 +56,15 @@ public class BindingHandlerAdviseTests {
@Test
void testValidatedValueValue() {
ValidatedProps validatedProps = new SpringApplicationBuilder(SampleConfiguration.class)
.web(WebApplicationType.NONE).run("--props.value=2", "--spring.jmx.enabled=false")
.getBean(ValidatedProps.class);
.web(WebApplicationType.NONE).run("--props.value=2", "--spring.jmx.enabled=false")
.getBean(ValidatedProps.class);
assertThat(validatedProps.getValue()).isEqualTo(2);
}
@Test
void nonValidatedConfigProperties() {
new SpringApplicationBuilder(NonValidatedConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
.run("--spring.jmx.enabled=false");
// simply should not fail
}

View File

@@ -44,9 +44,9 @@ public class BindingServiceConfigurationTests {
@Test
void testErroChannelDistributesMessagesInCaseOfException() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration
TestChannelBinderConfiguration
.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run()) {
.web(WebApplicationType.NONE).run()) {
AtomicInteger counter = new AtomicInteger();
PublishSubscribeChannel channel = context.getBean("errorChannel", PublishSubscribeChannel.class);
//channel.setIgnoreFailures(true);
@@ -70,14 +70,14 @@ public class BindingServiceConfigurationTests {
@Test
void valdateImportedConfiguartionHandlerPostProcessing() {
ApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration
.getCompleteConfiguration(RootConfiguration.class))
.web(WebApplicationType.NONE).run();
TestChannelBinderConfiguration
.getCompleteConfiguration(RootConfiguration.class))
.web(WebApplicationType.NONE).run();
Map<String, AbstractReplyProducingMessageHandler> beansOfType = context
.getBeansOfType(AbstractReplyProducingMessageHandler.class);
.getBeansOfType(AbstractReplyProducingMessageHandler.class);
for (AbstractReplyProducingMessageHandler handler : beansOfType.values()) {
assertThat(handler.getNotPropagatedHeaders().contains("contentType"))
.isTrue();
.isTrue();
}
}

View File

@@ -47,14 +47,14 @@ public class RetryTemplateTests {
@Test
void testSingleCustomRetryTemplate() throws Exception {
ApplicationContext context = new SpringApplicationBuilder(
SingleCustomRetryTemplateConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
SingleCustomRetryTemplateConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
AbstractBinder binder = context.getBean(AbstractBinder.class);
Field f = AbstractBinder.class.getDeclaredField("consumerBindingRetryTemplates");
f.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, RetryTemplate> consumerBindingRetryTemplates = (Map<String, RetryTemplate>) f
.get(binder);
.get(binder);
assertThat(consumerBindingRetryTemplates).hasSize(1);
}
@@ -62,23 +62,23 @@ public class RetryTemplateTests {
@Test
void testSpecificCustomRetryTemplate() throws Exception {
ApplicationContext context = new SpringApplicationBuilder(
SpecificCustomRetryTemplateConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.processor-in-0.consumer.retry-template-name=retryTemplateTwo");
SpecificCustomRetryTemplateConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.processor-in-0.consumer.retry-template-name=retryTemplateTwo");
RetryTemplate retryTemplateTwo = context.getBean("retryTemplateTwo",
RetryTemplate.class);
RetryTemplate.class);
BindingServiceProperties bindingServiceProperties = context
.getBean(BindingServiceProperties.class);
.getBean(BindingServiceProperties.class);
ConsumerProperties consumerProperties = bindingServiceProperties
.getConsumerProperties("processor-in-0");
.getConsumerProperties("processor-in-0");
AbstractBinder binder = context.getBean(AbstractBinder.class);
Method m = AbstractBinder.class.getDeclaredMethod("buildRetryTemplate",
ConsumerProperties.class);
ConsumerProperties.class);
m.setAccessible(true);
RetryTemplate retryTemplate = (RetryTemplate) m.invoke(binder,
consumerProperties);
consumerProperties);
assertThat(retryTemplate).isEqualTo(retryTemplateTwo);
}

View File

@@ -44,16 +44,16 @@ public class ActuatorBindingsTest {
@Test
void test_2253() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(Bindings.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=consume",
"--spring.jackson.visibility.field=ANY" // see https://github.com/spring-cloud/spring-cloud-stream/issues/2253
// we need the above just to verify that such action does not
// interfere with instance of ObjectMapper inside of BindingsLifecycleController
)) {
TestChannelBinderConfiguration.getCompleteConfiguration(Bindings.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=consume",
"--spring.jackson.visibility.field=ANY" // see https://github.com/spring-cloud/spring-cloud-stream/issues/2253
// we need the above just to verify that such action does not
// interfere with instance of ObjectMapper inside of BindingsLifecycleController
)) {
BindingsLifecycleController controller = context
.getBean(BindingsLifecycleController.class);
.getBean(BindingsLifecycleController.class);
List<Map<?, ?>> bindings = controller.queryStates();
assertThat(bindings.size()).isEqualTo(1);
assertThat(bindings.get(0).get("bindingName")).isEqualTo("consume-in-0");

View File

@@ -52,21 +52,21 @@ public class DynamicDestinationFunctionTests {
@Disabled
void testEmptyConfiguration() {
TestChannelBinderConfiguration.applicationContextRunner(SampleConfiguration.class)
.withPropertyValues(
"spring.jmx.enabled=false",
"spring.cloud.stream.bindings.fooDestination.producer.partitionKeyExtractorName=keyExtractor")
.run(context -> {
InputDestination input = context.getBean(InputDestination.class);
input.send(new GenericMessage<String>("fooDestination"));
.withPropertyValues(
"spring.jmx.enabled=false",
"spring.cloud.stream.bindings.fooDestination.producer.partitionKeyExtractorName=keyExtractor")
.run(context -> {
InputDestination input = context.getBean(InputDestination.class);
input.send(new GenericMessage<String>("fooDestination"));
BindingServiceProperties serviceProperties = context.getBean(BindingServiceProperties.class);
assertThat("keyExtractor").isEqualTo(
serviceProperties.getProducerProperties("fooDestination").getPartitionKeyExtractorName());
BindingServiceProperties serviceProperties = context.getBean(BindingServiceProperties.class);
assertThat("keyExtractor").isEqualTo(
serviceProperties.getProducerProperties("fooDestination").getPartitionKeyExtractorName());
OutputDestination output = context.getBean(OutputDestination.class);
Object result = output.receive(1000).getPayload();
assertThat(result).isEqualTo("fooDestination");
});
OutputDestination output = context.getBean(OutputDestination.class);
Object result = output.receive(1000).getPayload();
assertThat(result).isEqualTo("fooDestination");
});
}
@EnableAutoConfiguration

View File

@@ -0,0 +1,311 @@
/*
* Copyright 2019-2022 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
*
* https://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.function;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.assertj.core.util.Arrays;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.stream.binder.test.InputDestination;
import org.springframework.cloud.stream.binder.test.OutputDestination;
import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.kafka.support.KafkaNull;
import org.springframework.messaging.Message;
import static org.assertj.core.api.Assertions.assertThat;
/**
*
* @author Gary Russel
* @author Oleg Zhurakousky
* @author David Turanski
*
* @since 3.0
*/
public class FunctionBatchingTests {
@Test
void testMessageBatchConfigurationWithKafkaNull() {
TestChannelBinderConfiguration.applicationContextRunner(MessageBatchConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.input.consumer.batch-mode=true")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List<Object> list = new ArrayList<>();
list.add("{\"name\":\"bob\"}".getBytes());
list.add("{\"name\":\"jill\"}".getBytes());
list.add(KafkaNull.INSTANCE);
list.add("{\"name\":\"steve\"}".getBytes());
Message<List<Object>> inputMessage = MessageBuilder
.withPayload(list)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(outputMessage).isNotNull();
assertThat(outputMessage.getPayload())
.isEqualTo("{\"name\":\"bob\"}".getBytes());
context.stop();
});
}
@Test
void testListPayloadConfiguration() {
TestChannelBinderConfiguration.applicationContextRunner(ListPayloadNotBatchConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("[{\"name\":\"bob\"},{\"name\":\"jill\"}]".getBytes())
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(outputMessage).isNotNull();
assertThat(outputMessage.getPayload())
.isEqualTo("{\"name\":\"bob\"}".getBytes());
context.stop();
});
}
@Test
void testListStringPayloadConfigurationTextPlain() {
TestChannelBinderConfiguration.applicationContextRunner(ListStringPayloadConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.func-in-0.content-type=text/plain")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List bytes = Arrays.asList(new Object[] {"abc".getBytes(), "xyz".getBytes()});
Message inputMessage = MessageBuilder.withPayload(bytes).build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(new String(outputMessage.getPayload())).isEqualTo("[abc, xyz]");
context.stop();
});
}
@Test
void testListObjectPayloadObjectConfigurationTextPlain() {
TestChannelBinderConfiguration.applicationContextRunner(ListObjectPayloadConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.func-in-0.content-type=text/plain")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List bytes = Arrays.asList(new Object[] {"abc".getBytes(), "xyz".getBytes()});
Message inputMessage = MessageBuilder.withPayload(bytes).build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(new String(outputMessage.getPayload())).isEqualTo("[abc, xyz]");
context.stop();
});
}
@Test
void testSimpleBatchConfiguration() {
TestChannelBinderConfiguration.applicationContextRunner(SimpleBatchConfiguration.class)
.withPropertyValues(
"spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.input.consumer.batch-mode=true")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List<byte[]> list = new ArrayList<>();
list.add("{\"name\":\"bob\"}".getBytes());
list.add("{\"name\":\"jill\"}".getBytes());
Message<List<byte[]>> inputMessage = MessageBuilder
.withPayload(list)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(outputMessage).isNotNull();
assertThat(outputMessage.getPayload())
.isEqualTo("{\"name\":\"bob\"}".getBytes());
context.stop();
});
}
@Test
void testNestedBatchConfiguration() {
TestChannelBinderConfiguration.applicationContextRunner(NestedBatchConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.input.consumer.batch-mode=true")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List<byte[]> list = new ArrayList<>();
list.add("[{\"name\":\"bob\"},{\"name\":\"jill\"}]".getBytes());
Message<List<byte[]>> inputMessage = MessageBuilder
.withPayload(list)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(outputMessage).isNotNull();
assertThat(outputMessage.getPayload())
.isEqualTo("{\"name\":\"bob\"}".getBytes());
context.stop();
});
}
@EnableAutoConfiguration
public static class SimpleBatchConfiguration {
@Bean
public Function<List<Person>, Person> func() {
return x -> x.get(0);
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
@EnableAutoConfiguration
public static class ListStringPayloadConfiguration {
@Bean
public Function<List<String>, String> func() {
return x -> x.toString();
}
}
@EnableAutoConfiguration
public static class ListObjectPayloadConfiguration {
@Bean
public Function<List<Object>, String> func() {
return x -> x.toString();
}
}
@EnableAutoConfiguration
public static class ListPayloadNotBatchConfiguration {
@Bean
public Function<List<Person>, Person> func() {
return x -> x.get(0);
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
@EnableAutoConfiguration
public static class NestedBatchConfiguration {
@Bean
public Function<List<List<Person>>, Person> func() {
return x -> x.get(0).get(0);
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
@EnableAutoConfiguration
public static class MessageBatchConfiguration {
@Bean
public Function<Message<List<Person>>, Person> func() {
return x -> {
Object o = x.getPayload().get(2);
assertThat(o).isNull();
return (Person) x.getPayload().get(0);
};
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
}

View File

@@ -50,27 +50,27 @@ public class GreenfieldFunctionEnableBindingTests {
@Test
void testProcessorFromFunction() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ProcessorFromFunction.class)).web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=toUpperCase",
"--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
ProcessorFromFunction.class)).web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=toUpperCase",
"--spring.jmx.enabled=false")) {
InputDestination source = context.getBean(InputDestination.class);
source.send(new GenericMessage<byte[]>("John Doe".getBytes()));
OutputDestination target = context.getBean(OutputDestination.class);
assertThat(target.receive(10000).getPayload())
.isEqualTo("JOHN DOE".getBytes(StandardCharsets.UTF_8));
.isEqualTo("JOHN DOE".getBytes(StandardCharsets.UTF_8));
}
}
@Test
void testSinkFromConsumer() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration
.getCompleteConfiguration(SinkFromConsumer.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.function.definition=sink",
"--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration
.getCompleteConfiguration(SinkFromConsumer.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.function.definition=sink",
"--spring.jmx.enabled=false")) {
InputDestination source = context.getBean(InputDestination.class);
PollableChannel result = context.getBean("result", PollableChannel.class);

View File

@@ -90,9 +90,9 @@ public class ImplicitFunctionBindingTests {
@Test
void testFailedApplicationListenerConfiguration() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(FailedApplicationListenerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=echo")) {
TestChannelBinderConfiguration.getCompleteConfiguration(FailedApplicationListenerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=echo")) {
InputDestination input = context.getBean(InputDestination.class);
input.send(new GenericMessage<byte[]>("hello".getBytes()), "echo-in-0");
@@ -107,9 +107,9 @@ public class ImplicitFunctionBindingTests {
@Test
void testDisableAutodetect() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SendToDestinationConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.stream.function.autodetect=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SendToDestinationConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.stream.function.autodetect=false")) {
BindingsLifecycleController ctrl = context.getBean(BindingsLifecycleController.class);
Binding input = ctrl.queryState("echo-in-0");
@@ -124,9 +124,9 @@ public class ImplicitFunctionBindingTests {
@Test
void testBindingControl() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SendToDestinationConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SendToDestinationConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false")) {
BindingsLifecycleController ctrl = context.getBean(BindingsLifecycleController.class);
Binding input = ctrl.queryState("echo-in-0");
@@ -141,9 +141,9 @@ public class ImplicitFunctionBindingTests {
@Test
void dynamicBindingTestWithFunctionRegistrationAndExplicitDestination() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.function-in-0.destination=input")) {
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.stream.bindings.function-in-0.destination=input")) {
InputDestination input = context.getBean(InputDestination.class);
try {
@@ -169,9 +169,9 @@ public class ImplicitFunctionBindingTests {
@Test
void dynamicBindingTestWithFunction() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false")) {
InputDestination input = context.getBean(InputDestination.class);
try {
input.send(new GenericMessage<byte[]>("hello".getBytes()));
@@ -195,8 +195,8 @@ public class ImplicitFunctionBindingTests {
void testEmptyConfiguration() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false", "--debug")) {
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false", "--debug")) {
context.getBean(InputDestination.class);
}
catch (Exception e) { // should not fail
@@ -208,9 +208,9 @@ public class ImplicitFunctionBindingTests {
void testNullMessage() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(NullMessagerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=func; funcMessage")) {
TestChannelBinderConfiguration.getCompleteConfiguration(NullMessagerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=func; funcMessage")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -233,9 +233,9 @@ public class ImplicitFunctionBindingTests {
void testSimpleFunctionWithStreamProperty() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=func")) {
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=func")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -253,11 +253,11 @@ public class ImplicitFunctionBindingTests {
void testHeaderRetentionWithComposition() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.autodetect=false",
"--spring.cloud.function.definition=func|addHeaders")) {
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.autodetect=false",
"--spring.cloud.function.definition=func|addHeaders")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -275,9 +275,9 @@ public class ImplicitFunctionBindingTests {
void testReactiveFunctionWithState() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=aggregate")) {
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=aggregate")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -302,10 +302,10 @@ public class ImplicitFunctionBindingTests {
void testFunctionWithUseNativeEncoding() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=func",
"--spring.cloud.stream.bindings.func-out-0.producer.useNativeEncoding=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=func",
"--spring.cloud.stream.bindings.func-out-0.producer.useNativeEncoding=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -321,9 +321,9 @@ public class ImplicitFunctionBindingTests {
void testSimpleFunctionWithNativeProperty() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=func")) {
TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=func")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -341,8 +341,8 @@ public class ImplicitFunctionBindingTests {
void testSimpleFunctionWithoutDefinitionProperty() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -360,8 +360,8 @@ public class ImplicitFunctionBindingTests {
void testSimpleConsumerWithoutDefinitionProperty() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
Message<byte[]> inputMessage = MessageBuilder.withPayload("Hello".getBytes()).build();
@@ -376,8 +376,8 @@ public class ImplicitFunctionBindingTests {
void fooFunctionComposedWithConsumerNoOutputChannel() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class, SingleReactiveConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=echo|consumer")) {
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class, SingleReactiveConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=echo|consumer")) {
assertThat(context.containsBean("echoconsumer-out-0")).isFalse();
@@ -394,8 +394,8 @@ public class ImplicitFunctionBindingTests {
void fooFunctionComposedWithConsumerNonReactive() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(FunctionConsumerCopositionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=echo|consumer")) {
TestChannelBinderConfiguration.getCompleteConfiguration(FunctionConsumerCopositionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=echo|consumer")) {
assertThat(context.containsBean("echoconsumer-out-0")).isFalse();
@@ -412,8 +412,8 @@ public class ImplicitFunctionBindingTests {
void testReactiveConsumerWithoutDefinitionProperty() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleReactiveConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleReactiveConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
Message<byte[]> inputMessage = MessageBuilder.withPayload("Hello".getBytes()).build();
@@ -427,10 +427,10 @@ public class ImplicitFunctionBindingTests {
@Test
void testConsumer() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=consumer",
"--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.consumer-in-0.content-type=text/plain")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=consumer",
"--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.consumer-in-0.content-type=text/plain")) {
InputDestination source = context.getBean(InputDestination.class);
source.send(new GenericMessage<byte[]>("John Doe".getBytes()));
@@ -441,9 +441,9 @@ public class ImplicitFunctionBindingTests {
void testBindingWithReactiveFunction() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=echo")) {
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=echo")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -475,8 +475,8 @@ public class ImplicitFunctionBindingTests {
void testDeclaredTypeVsActualInstance() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SCF_GH_409Configuration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SCF_GH_409Configuration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -494,9 +494,9 @@ public class ImplicitFunctionBindingTests {
void testWithContextTypeApplicationProperty() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.input.content-type=text/plain", "--debug")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.input.content-type=text/plain", "--debug")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -517,8 +517,8 @@ public class ImplicitFunctionBindingTests {
void testWithIntegrationFlowAsFunction() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(FunctionSampleSpringIntegrationConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
.getCompleteConfiguration(FunctionSampleSpringIntegrationConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -536,9 +536,9 @@ public class ImplicitFunctionBindingTests {
void testSupplierWithCustomPoller() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierWithExplicitPollerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.stream.poller.fixed-delay=1500")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierWithExplicitPollerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.stream.poller.fixed-delay=1500")) {
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -555,11 +555,11 @@ public class ImplicitFunctionBindingTests {
void testImperativeSupplierReactiveFunctionComposition() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(ImperativeSupplierComposedWithReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.poller.fixed-delay=1000",
"--spring.cloud.function.definition=supplier|functionA")) {
TestChannelBinderConfiguration.getCompleteConfiguration(ImperativeSupplierComposedWithReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.poller.fixed-delay=1000",
"--spring.cloud.function.definition=supplier|functionA")) {
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -583,10 +583,10 @@ public class ImplicitFunctionBindingTests {
void testSupplierWithCustomPollerAndMappedOutput() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierWithExplicitPollerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.poller.fixed-delay=1200",
"--spring.cloud.function.bindings.supplier-out-0=output")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierWithExplicitPollerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.poller.fixed-delay=1200",
"--spring.cloud.function.bindings.supplier-out-0=output")) {
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -602,8 +602,8 @@ public class ImplicitFunctionBindingTests {
void testNoFunctionEnabledConfiguration() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(NoFunctionEnabledConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(NoFunctionEnabledConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
try {
context.getBean(FunctionConfiguration.class);
@@ -620,9 +620,9 @@ public class ImplicitFunctionBindingTests {
void testCollectionAndMapConversionDuringComposition() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(CompositionWithCollectionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcA|funcB",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(CompositionWithCollectionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcA|funcB",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -641,9 +641,9 @@ public class ImplicitFunctionBindingTests {
void testOutputAsCollectionOfMessages() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(SplittableTypesConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcCollectionOfMessages",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(SplittableTypesConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcCollectionOfMessages",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -664,9 +664,9 @@ public class ImplicitFunctionBindingTests {
void testOutputAsArrayOfMessages() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(SplittableTypesConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcArrayOfMessages",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(SplittableTypesConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcArrayOfMessages",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -687,13 +687,13 @@ public class ImplicitFunctionBindingTests {
void testWithExplicitBindingInstructions() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(SplittableTypesConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcArrayOfMessages",
"--spring.cloud.stream.function.bindings.funcArrayOfMessages-in-0=input",
"--spring.cloud.stream.function.bindings.funcArrayOfMessages-out-0=output",
"--spring.cloud.stream.bindings.input.destination=myInput",
"--spring.cloud.stream.bindings.output.destination=myOutput",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(SplittableTypesConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcArrayOfMessages",
"--spring.cloud.stream.function.bindings.funcArrayOfMessages-in-0=input",
"--spring.cloud.stream.function.bindings.funcArrayOfMessages-out-0=output",
"--spring.cloud.stream.bindings.input.destination=myInput",
"--spring.cloud.stream.bindings.output.destination=myOutput",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -714,12 +714,12 @@ public class ImplicitFunctionBindingTests {
void testWithExplicitBindingInstructionsOnlyDestination() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(SplittableTypesConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=funcArrayOfMessages",
"--spring.cloud.stream.bindings.funcArrayOfMessages-in-0.destination=myInput",
"--spring.cloud.stream.bindings.funcArrayOfMessages-out-0.destination=myOutput",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(SplittableTypesConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=funcArrayOfMessages",
"--spring.cloud.stream.bindings.funcArrayOfMessages-in-0.destination=myInput",
"--spring.cloud.stream.bindings.funcArrayOfMessages-out-0.destination=myOutput",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -740,11 +740,11 @@ public class ImplicitFunctionBindingTests {
void partitionOnOutputPayloadTest() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=func",
"--spring.cloud.stream.bindings.func-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.func-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=func",
"--spring.cloud.stream.bindings.func-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.func-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -763,11 +763,11 @@ public class ImplicitFunctionBindingTests {
void partitionOnOutputPayloadAsListAndFunctionAroundWrapperTest() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=uppercase|persons",
"--spring.cloud.stream.bindings.uppercase|persons-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.uppercase|persons-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=uppercase|persons",
"--spring.cloud.stream.bindings.uppercase|persons-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.uppercase|persons-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -786,11 +786,11 @@ public class ImplicitFunctionBindingTests {
void partitionOnOutputPayloadTestReactive() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcReactive",
"--spring.cloud.stream.bindings.funcReactive-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.funcReactive-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=funcReactive",
"--spring.cloud.stream.bindings.funcReactive-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.funcReactive-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -809,11 +809,11 @@ public class ImplicitFunctionBindingTests {
void partitionOnOutputPayloadWithSupplierTest() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=personSupplier",
"--spring.cloud.stream.bindings.personSupplier-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.personSupplier-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=personSupplier",
"--spring.cloud.stream.bindings.personSupplier-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.personSupplier-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -827,11 +827,11 @@ public class ImplicitFunctionBindingTests {
void partitionOnOutputPayloadWithReactiveSupplierTest() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=reactivePersonSupplier",
"--spring.cloud.stream.bindings.reactivePersonSupplier-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.reactivePersonSupplier-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=reactivePersonSupplier",
"--spring.cloud.stream.bindings.reactivePersonSupplier-out-0.producer.partitionKeyExpression=payload.id",
"--spring.cloud.stream.bindings.reactivePersonSupplier-out-0.producer.partitionCount=5",
"--spring.jmx.enabled=false")) {
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -845,16 +845,16 @@ public class ImplicitFunctionBindingTests {
void contentTypeAsByteArrayTest() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=echoPerson",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(PojoFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.function.definition=echoPerson",
"--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder.withPayload("{\"name\":\"Jim Lahey\",\"id\":420}".getBytes())
.setHeader(MessageHeaders.CONTENT_TYPE, "application/json".getBytes(StandardCharsets.UTF_8))
.build();
.setHeader(MessageHeaders.CONTENT_TYPE, "application/json".getBytes(StandardCharsets.UTF_8))
.build();
inputDestination.send(inputMessage, "echoPerson-in-0");
@@ -866,8 +866,8 @@ public class ImplicitFunctionBindingTests {
void testReactiveFunctionWithOutputAsMonoVoid() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(FunctionalConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(FunctionalConsumerConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
assertThat(context.containsBean("funcConsumer-out-0")).isFalse();
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -883,8 +883,8 @@ public class ImplicitFunctionBindingTests {
void testReactiveSendToDestinationConfiguration() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SendToDestinationConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SendToDestinationConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -909,9 +909,9 @@ public class ImplicitFunctionBindingTests {
System.clearProperty("spring.cloud.function.definition");
try {
new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveConsumerWithConcurrencyFailureConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.input-in-0.consumer.concurrency=2");
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveConsumerWithConcurrencyFailureConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.input-in-0.consumer.concurrency=2");
fail();
}
catch (BeanCreationException e) {
@@ -923,11 +923,11 @@ public class ImplicitFunctionBindingTests {
void testGh1973() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierAndProcessorConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=echo;supplier",
"--spring.cloud.stream.bindings.supplier-out-0.destination=output",
"--spring.cloud.stream.bindings.echo-out-0.destination=output")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierAndProcessorConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=echo;supplier",
"--spring.cloud.stream.bindings.supplier-out-0.destination=output",
"--spring.cloud.stream.bindings.echo-out-0.destination=output")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -945,9 +945,9 @@ public class ImplicitFunctionBindingTests {
void testGh1944() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierAndPojoConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=supplier")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierAndPojoConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=supplier")) {
OutputDestination outputDestination = context.getBean(OutputDestination.class);
Message<byte[]> result = outputDestination.receive(1000, "supplier-out-0");
@@ -959,9 +959,9 @@ public class ImplicitFunctionBindingTests {
void testGh2054() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactivePojoMessage")) {
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactivePojoMessage")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -979,9 +979,9 @@ public class ImplicitFunctionBindingTests {
void testGh2062() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=echo")) {
TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=echo")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
String jsonPerson = "error";
@@ -995,9 +995,9 @@ public class ImplicitFunctionBindingTests {
void testWithNativeEncodingImperative() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=imperative")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=imperative")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
inputDestination.send(new GenericMessage<byte[]>("hello".getBytes()));
@@ -1010,12 +1010,12 @@ public class ImplicitFunctionBindingTests {
}
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=imperative",
"--spring.cloud.stream.bindings.imperative-in-0.consumer.useNativeDecoding=true",
"--spring.cloud.stream.bindings.imperative-out-0.producer.useNativeEncoding=true"
)) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=imperative",
"--spring.cloud.stream.bindings.imperative-in-0.consumer.useNativeDecoding=true",
"--spring.cloud.stream.bindings.imperative-out-0.producer.useNativeEncoding=true"
)) {
InputDestination inputDestination = context.getBean(InputDestination.class);
inputDestination.send(new GenericMessage<byte[]>("hello".getBytes()));
@@ -1033,9 +1033,9 @@ public class ImplicitFunctionBindingTests {
void testWithNativeEncodingReactive() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactive")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactive")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
inputDestination.send(new GenericMessage<byte[]>("hello".getBytes()));
@@ -1047,11 +1047,11 @@ public class ImplicitFunctionBindingTests {
assertThat(new String((byte[]) result.getPayload())).isEqualTo("byte[]"); // check input type
}
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactive",
"--spring.cloud.stream.bindings.reactive-in-0.consumer.useNativeDecoding=true",
"--spring.cloud.stream.bindings.reactive-out-0.producer.useNativeEncoding=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactive",
"--spring.cloud.stream.bindings.reactive-in-0.consumer.useNativeDecoding=true",
"--spring.cloud.stream.bindings.reactive-out-0.producer.useNativeEncoding=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
inputDestination.send(new GenericMessage<byte[]>("hello".getBytes()));
@@ -1065,10 +1065,10 @@ public class ImplicitFunctionBindingTests {
//Consumer reactiveConsumer
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactiveConsumer",
"--spring.cloud.stream.bindings.reactiveConsumer-in-0.consumer.useNativeDecoding=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactiveConsumer",
"--spring.cloud.stream.bindings.reactiveConsumer-in-0.consumer.useNativeDecoding=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
inputDestination.send(new GenericMessage<byte[]>("hello".getBytes()));
@@ -1080,10 +1080,10 @@ public class ImplicitFunctionBindingTests {
}
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactiveFunctionConsumer",
"--spring.cloud.stream.bindings.reactiveFunctionConsumer-in-0.consumer.useNativeDecoding=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration2.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=reactiveFunctionConsumer",
"--spring.cloud.stream.bindings.reactiveFunctionConsumer-in-0.consumer.useNativeDecoding=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
inputDestination.send(new GenericMessage<byte[]>("hello".getBytes()));
@@ -1099,9 +1099,9 @@ public class ImplicitFunctionBindingTests {
void testHeaderPropagation() {
System.clearProperty("spring.cloud.function.definition");
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=func")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SingleFunctionConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=func")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -1173,7 +1173,7 @@ public class ImplicitFunctionBindingTests {
@Bean
public Function<Flux<String>, Flux<String>> aggregate() {
return inbound -> inbound.log().window(Duration.ofSeconds(1))
.flatMap(w -> w.reduce("", (s1, s2) -> s1 + s2)).log();
.flatMap(w -> w.reduce("", (s1, s2) -> s1 + s2)).log();
}
@Bean
@@ -1375,7 +1375,7 @@ public class ImplicitFunctionBindingTests {
@Bean
public IntegrationFlow uppercaseFlow() {
return IntegrationFlows.from(MessageFunction.class, gateway -> gateway.beanName("uppercase"))
.<String, String>transform(String::toUpperCase).logAndReply(LoggingHandler.Level.WARN);
.<String, String>transform(String::toUpperCase).logAndReply(LoggingHandler.Level.WARN);
}
}

View File

@@ -123,11 +123,11 @@ public class MultipleInputOutputFunctionTests {
@Test
void testMultiInputSingleOutput() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=multiInputSingleOutput")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=multiInputSingleOutput")) {
context.getBean(InputDestination.class);
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -148,11 +148,11 @@ public class MultipleInputOutputFunctionTests {
@Test
void testMultiInputMessageSingleOutput() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=multiInputSingleOutputMessage")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=multiInputSingleOutputMessage")) {
context.getBean(InputDestination.class);
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -173,11 +173,11 @@ public class MultipleInputOutputFunctionTests {
@Test
void testSingleInputMultiOutput() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=singleInputMultipleOutputs")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=singleInputMultipleOutputs")) {
context.getBean(InputDestination.class);
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -200,11 +200,11 @@ public class MultipleInputOutputFunctionTests {
@Test
void testMultipleFunctions() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=uppercase;reverse")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=uppercase;reverse")) {
context.getBean(InputDestination.class);
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -225,11 +225,11 @@ public class MultipleInputOutputFunctionTests {
@Test
void testMultipleFunctionsWithComposition() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=uppercase|reverse;reverse|uppercase")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
ReactiveFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=uppercase|reverse;reverse|uppercase")) {
context.getBean(InputDestination.class);
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -251,13 +251,13 @@ public class MultipleInputOutputFunctionTests {
@Test
void testMultiInputSingleOutputWithCustomContentType() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ContentTypeConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=multiInputSingleOutput",
"--spring.cloud.stream.bindings.multiInputSingleOutput-in-0.content-type=string/person",
"--spring.cloud.stream.bindings.multiInputSingleOutput-in-1.content-type=string/employee")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
ContentTypeConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=multiInputSingleOutput",
"--spring.cloud.stream.bindings.multiInputSingleOutput-in-0.content-type=string/person",
"--spring.cloud.stream.bindings.multiInputSingleOutput-in-1.content-type=string/employee")) {
context.getBean(InputDestination.class);
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -278,14 +278,14 @@ public class MultipleInputOutputFunctionTests {
@Test
void testMultiInputSingleOutputWithCustomContentType2() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
ContentTypeConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=multiInputSingleOutput2",
"--spring.cloud.stream.bindings.multiInputSingleOutput2-in-0.content-type=string/person",
"--spring.cloud.stream.bindings.multiInputSingleOutput2-in-1.content-type=string/employee",
"--spring.cloud.stream.bindings.multiInputSingleOutput2-out-0.content-type=string/person")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
ContentTypeConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=multiInputSingleOutput2",
"--spring.cloud.stream.bindings.multiInputSingleOutput2-in-0.content-type=string/person",
"--spring.cloud.stream.bindings.multiInputSingleOutput2-in-1.content-type=string/employee",
"--spring.cloud.stream.bindings.multiInputSingleOutput2-out-0.content-type=string/person")) {
context.getBean(InputDestination.class);
InputDestination inputDestination = context.getBean(InputDestination.class);
@@ -417,7 +417,7 @@ public class MultipleInputOutputFunctionTests {
@Override
@Nullable
protected Object convertFromInternal(
Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
String name = new String(((byte[]) message.getPayload()), StandardCharsets.UTF_8);
Person person = new Person(name);
return person;
@@ -426,7 +426,7 @@ public class MultipleInputOutputFunctionTests {
@Override
@Nullable
protected Object convertToInternal(
Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
return ((Person) payload).getName().getBytes(StandardCharsets.UTF_8);
}
@@ -445,7 +445,7 @@ public class MultipleInputOutputFunctionTests {
@Override
@Nullable
protected Object convertFromInternal(
Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
String name = new String(((byte[]) message.getPayload()), StandardCharsets.UTF_8);
Employee person = new Employee(name);
return person;
@@ -454,7 +454,7 @@ public class MultipleInputOutputFunctionTests {
@Override
@Nullable
protected Object convertToInternal(
Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
return ((Employee) payload).getName().getBytes(StandardCharsets.UTF_8);
}

View File

@@ -51,12 +51,12 @@ public class PollableSourceTests {
@Test
void testPollableSource() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(PollableAppSampleConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false",
"--spring.cloud.stream.pollable-source=blah",
"--spring.integration.poller.cron=*/2 * * * * *",
"--spring.cloud.stream.poller.max-messages-per-poll=4")) {
.getCompleteConfiguration(PollableAppSampleConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false",
"--spring.cloud.stream.pollable-source=blah",
"--spring.integration.poller.cron=*/2 * * * * *",
"--spring.cloud.stream.poller.max-messages-per-poll=4")) {
DefaultPollableMessageSource pollableSource = (DefaultPollableMessageSource) context.getBean(PollableMessageSource.class);
@@ -118,10 +118,10 @@ public class PollableSourceTests {
void testPollerMutualProperties() {
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(() -> new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(PollableAppSampleConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.integration.poller.fixed-rate=200",
"--spring.cloud.stream.poller.fixed-delay=300"))
.getCompleteConfiguration(PollableAppSampleConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.integration.poller.fixed-rate=200",
"--spring.cloud.stream.poller.fixed-delay=300"))
.withRootCauseExactlyInstanceOf(MutuallyExclusiveConfigurationPropertiesException.class)
.withMessageContaining("are mutually exclusive");
}

View File

@@ -64,21 +64,21 @@ public class RoutingFunctionTests {
@Test
void testRoutingViaExplicitEnablingAndDefinitionHeader() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.routing.enabled=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.routing.enabled=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes())
.setHeader(FunctionProperties.PREFIX + ".definition", "echo")
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
.withPayload("Hello".getBytes())
.setHeader(FunctionProperties.PREFIX + ".definition", "echo")
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -89,21 +89,21 @@ public class RoutingFunctionTests {
@Test
void testRoutingViaExplicitEnablingAndRoutingExpressionProperty() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.routing-expression=headers.contentType.toString().equals('text/plain') ? 'echo' : null",
"--spring.cloud.stream.function.routing.enabled=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.routing-expression=headers.contentType.toString().equals('text/plain') ? 'echo' : null",
"--spring.cloud.stream.function.routing.enabled=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes())
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
.withPayload("Hello".getBytes())
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -114,21 +114,21 @@ public class RoutingFunctionTests {
@Test
void testRoutingViaExplicitEnablingAndRoutingExpressionHeader() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.routing.enabled=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.routing.enabled=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes())
.setHeader("spring.cloud.function.routing-expression", "'echo'")
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
.withPayload("Hello".getBytes())
.setHeader("spring.cloud.function.routing-expression", "'echo'")
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -139,21 +139,21 @@ public class RoutingFunctionTests {
@Test
void testRoutingViaExplicitDefinitionAndDefinitionHeader() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=" + RoutingFunction.FUNCTION_NAME)) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=" + RoutingFunction.FUNCTION_NAME)) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes())
.setHeader("spring.cloud.function.definition", "echo|uppercase")
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
.withPayload("Hello".getBytes())
.setHeader("spring.cloud.function.definition", "echo|uppercase")
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -164,19 +164,19 @@ public class RoutingFunctionTests {
@Test
void testDefaultRoutingFunctionBindingFlux() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.routing.enabled=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.routing.enabled=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes())
.setHeader("spring.cloud.function.definition", "echoFlux")
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
.withPayload("Hello".getBytes())
.setHeader("spring.cloud.function.definition", "echoFlux")
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN)
.build();
inputDestination.send(inputMessage);
TestChannelBinder binder = context.getBean(TestChannelBinder.class);
@@ -190,20 +190,20 @@ public class RoutingFunctionTests {
@Test
void testPojoFunction() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=" + RoutingFunction.FUNCTION_NAME)) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=" + RoutingFunction.FUNCTION_NAME)) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("{\"name\":\"bob\"}".getBytes())
.setHeader("spring.cloud.function.definition", "pojoecho")
.build();
.withPayload("{\"name\":\"bob\"}".getBytes())
.setHeader("spring.cloud.function.definition", "pojoecho")
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -215,19 +215,19 @@ public class RoutingFunctionTests {
@Test
void testExplicitRoutingFunctionBindingWithCompositionAndRoutingEnabledExplicitly() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=enrich|" + RoutingFunction.FUNCTION_NAME,
"--spring.cloud.stream.function.routing.enabled=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=enrich|" + RoutingFunction.FUNCTION_NAME,
"--spring.cloud.stream.function.routing.enabled=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes()).build();
.withPayload("Hello".getBytes()).build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -238,18 +238,18 @@ public class RoutingFunctionTests {
@Test
void testExplicitRoutingFunctionBindingWithCompositionAndRoutingEnabledImplicitly() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=enrich|" + RoutingFunction.FUNCTION_NAME)) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=enrich|" + RoutingFunction.FUNCTION_NAME)) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes()).build();
.withPayload("Hello".getBytes()).build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -260,20 +260,20 @@ public class RoutingFunctionTests {
@Test
void testExplicitRoutingFunctionBindingWithCompositionAndRoutingEnabledExplicitlyAndMoreComposition() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=enrich|" + RoutingFunction.FUNCTION_NAME + "|reverse",
"--spring.cloud.stream.function.routing.enabled=true")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=enrich|" + RoutingFunction.FUNCTION_NAME + "|reverse",
"--spring.cloud.stream.function.routing.enabled=true")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes())
.build();
.withPayload("Hello".getBytes())
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -284,18 +284,18 @@ public class RoutingFunctionTests {
@Test
void testExplicitRoutingFunctionBindingWithCompositionAndRoutingEnabledImplicitlyAndMoreComposition() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=enrich|" + RoutingFunction.FUNCTION_NAME + "|reverse")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingFunctionConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.stream.function.definition=enrich|" + RoutingFunction.FUNCTION_NAME + "|reverse")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("Hello".getBytes()).build();
.withPayload("Hello".getBytes()).build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
@@ -307,17 +307,17 @@ public class RoutingFunctionTests {
@Test
void testRoutingToConsumers() throws Exception {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingConsumerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.routing-expression=headers['func_name']")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
RoutingConsumerConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.routing-expression=headers['func_name']")) {
InputDestination inputDestination = context.getBean(InputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("foo".getBytes())
.setHeader("func_name", "consume")
.build();
.withPayload("foo".getBytes())
.setHeader("func_name", "consume")
.build();
OutputDestination outputDestination = context.getBean(OutputDestination.class);
Field chField = ReflectionUtils.findField(outputDestination.getClass(), "channels");
chField.setAccessible(true);
@@ -326,9 +326,9 @@ public class RoutingFunctionTests {
inputDestination.send(inputMessage);
assertThat(outputChannels.isEmpty());
inputMessage = MessageBuilder
.withPayload("foo".getBytes())
.setHeader("func_name", "echo")
.build();
.withPayload("foo".getBytes())
.setHeader("func_name", "echo")
.build();
inputDestination.send(inputMessage);
assertThat(outputChannels.size()).isEqualTo(1);
}

View File

@@ -46,13 +46,13 @@ public class ScenarioTests {
@Test
void test2106() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(ConsumerConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=consume;echo",
"--spring.cloud.stream.bindings.consume-in-0.destination=input",
"--spring.cloud.stream.bindings.echo-in-0.destination=echoin",
"--spring.cloud.stream.bindings.echo-out-0.destination=echoout",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(ConsumerConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=consume;echo",
"--spring.cloud.stream.bindings.consume-in-0.destination=input",
"--spring.cloud.stream.bindings.echo-in-0.destination=echoin",
"--spring.cloud.stream.bindings.echo-out-0.destination=echoout",
"--spring.jmx.enabled=false")) {
ConsumerConfiguration configuration = context.getBean(ConsumerConfiguration.class);
@@ -84,10 +84,10 @@ public class ScenarioTests {
@Test
void testComposingSupplierWuthTypelessMessageFunction() throws Exception {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=messageSupplier|messageFunction")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SupplierConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=messageSupplier|messageFunction")) {
OutputDestination output = context.getBean(OutputDestination.class);
assertThat(output.receive(1000, "messageSuppliermessageFunction-out-0")).isNotNull();
@@ -99,10 +99,10 @@ public class ScenarioTests {
@Test
void test2107() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(FunctionReturningNullConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=uppercase")) {
TestChannelBinderConfiguration.getCompleteConfiguration(FunctionReturningNullConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=uppercase")) {
InputDestination input = context.getBean(InputDestination.class);
input.send(new GenericMessage<byte[]>("a".getBytes()), "uppercase-in-0");
@@ -116,10 +116,10 @@ public class ScenarioTests {
@Test
void test2113() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(TestConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=genericTypeFunction")) {
TestChannelBinderConfiguration.getCompleteConfiguration(TestConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false",
"--spring.cloud.function.definition=genericTypeFunction")) {
InputDestination input = context.getBean(InputDestination.class);
OutputDestination output = context.getBean(OutputDestination.class);

View File

@@ -88,14 +88,14 @@ public class StreamBridgeTests {
@Test
void test_SCF_856() throws Exception {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
StreamBridge streamBridge = context.getBean(StreamBridge.class);
streamBridge.send("myBinding-out-0",
CloudEventMessageBuilder.withData("hello").setSource("my-source")
.setId(UUID.randomUUID().toString()).setSpecVersion("1.0").setType("myType")
.setHeader(MessageUtils.TARGET_PROTOCOL, "kafka").build(),
MimeTypeUtils.APPLICATION_JSON);
CloudEventMessageBuilder.withData("hello").setSource("my-source")
.setId(UUID.randomUUID().toString()).setSpecVersion("1.0").setType("myType")
.setHeader(MessageUtils.TARGET_PROTOCOL, "kafka").build(),
MimeTypeUtils.APPLICATION_JSON);
OutputDestination output = context.getBean(OutputDestination.class);
Message<byte[]> result = output.receive();
assertThat(result.getHeaders().get("ce_type")).isNotNull();
@@ -110,14 +110,14 @@ public class StreamBridgeTests {
@Test
void test_2249() throws Exception {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(
EmptyConfiguration.class)).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.source=outputA;outputB",
"--spring.cloud.stream.bindings.outputA-out-0.producer.partition-count=3",
"--spring.cloud.stream.bindings.outputA-out-0.producer.partition-key-expression=headers['partitionKey']",
"--spring.cloud.stream.bindings.outputB-out-0.destination=outputB",
"--spring.cloud.stream.bindings.outputB-out-0.producer.partition-count=3",
"--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(
EmptyConfiguration.class)).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.source=outputA;outputB",
"--spring.cloud.stream.bindings.outputA-out-0.producer.partition-count=3",
"--spring.cloud.stream.bindings.outputA-out-0.producer.partition-key-expression=headers['partitionKey']",
"--spring.cloud.stream.bindings.outputB-out-0.destination=outputB",
"--spring.cloud.stream.bindings.outputB-out-0.producer.partition-count=3",
"--spring.jmx.enabled=false")) {
StreamBridge streamBridge = context.getBean(StreamBridge.class);
streamBridge.send("outputA-out-0", MessageBuilder.withPayload("A").setHeader("partitionKey", "A").build());
streamBridge.send("outputB", MessageBuilder.withPayload("B").build());
@@ -140,20 +140,20 @@ public class StreamBridgeTests {
@Test
void test_2299_scstPartitionAlwaysSetEvenInConcurrentScenarios() throws Exception {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class)).web(
WebApplicationType.NONE).run("--spring.cloud.stream.source=outputA",
"--spring.cloud.stream.bindings.outputA-out-0.producer.partition-count=3",
"--spring.cloud.stream.bindings.outputA-out-0.producer.partition-key-expression=headers['partitionKey']",
"--spring.jmx.enabled=false")) {
TestChannelBinderConfiguration.getCompleteConfiguration(EmptyConfiguration.class)).web(
WebApplicationType.NONE).run("--spring.cloud.stream.source=outputA",
"--spring.cloud.stream.bindings.outputA-out-0.producer.partition-count=3",
"--spring.cloud.stream.bindings.outputA-out-0.producer.partition-key-expression=headers['partitionKey']",
"--spring.jmx.enabled=false")) {
StreamBridge streamBridge = context.getBean(StreamBridge.class);
int threadCount = 10;
Set<Thread> threads = IntStream.range(0, threadCount)
.mapToObj(i -> (Runnable) () -> IntStream.range(0, 100).forEach(j -> {
String value = "M-" + i + "-" + j;
streamBridge.send("outputA-out-0",
MessageBuilder.withPayload(value).setHeader("partitionKey", value).build());
})).map(Thread::new).collect(Collectors.toSet());
.mapToObj(i -> (Runnable) () -> IntStream.range(0, 100).forEach(j -> {
String value = "M-" + i + "-" + j;
streamBridge.send("outputA-out-0",
MessageBuilder.withPayload(value).setHeader("partitionKey", value).build());
})).map(Thread::new).collect(Collectors.toSet());
threads.forEach(Thread::start);
for (Thread thread : threads) {
@@ -176,11 +176,11 @@ public class StreamBridgeTests {
@Test
void testWithOutputContentTypeWildCardBindings() throws Exception {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(ConsumerConfiguration.class, EmptyConfigurationWithCustomConverters.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.foo.content-type=application/*+foo ",
"--spring.cloud.stream.bindings.bar.content-type=application/*+non-registered-foo",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(ConsumerConfiguration.class, EmptyConfigurationWithCustomConverters.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.foo.content-type=application/*+foo ",
"--spring.cloud.stream.bindings.bar.content-type=application/*+non-registered-foo",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("foo", "hello foo");
bridge.send("bar", "hello bar");
@@ -199,10 +199,10 @@ public class StreamBridgeTests {
@Test
void testNoCachingOfStreamBridgeFunction() throws Exception {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(ConsumerConfiguration.class, InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=function",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(ConsumerConfiguration.class, InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=function",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("function-in-0", (Object) "hello foo", MimeTypeUtils.TEXT_PLAIN);
bridge.send("function-in-0", (Object) "hello foo", MimeTypeUtils.APPLICATION_JSON);
@@ -219,9 +219,9 @@ public class StreamBridgeTests {
void testDelayedSend() {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(ConsumerConfiguration.class, EmptyConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(ConsumerConfiguration.class, EmptyConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
executor.schedule(() -> bridge.send("blah", "hello foo"), 5000, TimeUnit.MILLISECONDS);
@@ -239,10 +239,10 @@ public class StreamBridgeTests {
@Test
void testWithInterceptorsMatchedAgainstAllPatterns() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(ConsumerConfiguration.class, InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=function",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(ConsumerConfiguration.class, InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=function",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("function-in-0", "hello foo");
@@ -256,9 +256,9 @@ public class StreamBridgeTests {
@Test // validate that there is no exception thrown when sending to null channel
void test_2268() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("nullChannel", "blah");
@@ -268,14 +268,14 @@ public class StreamBridgeTests {
@Test
void testInterceptorIsNotAddedMultipleTimesToTheMessageChannel() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false",
"--spring.cloud.stream.dynamic-destination-cache-size=1",
"--spring.cloud.stream.output-bindings=outputA;outputB",
"--spring.cloud.stream.bindings.outputA-out-0.destination=outputA",
"--spring.cloud.stream.bindings.outputB-out-0.destination=outputB"
)) {
.getCompleteConfiguration(InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false",
"--spring.cloud.stream.dynamic-destination-cache-size=1",
"--spring.cloud.stream.output-bindings=outputA;outputB",
"--spring.cloud.stream.bindings.outputA-out-0.destination=outputA",
"--spring.cloud.stream.bindings.outputB-out-0.destination=outputB"
)) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("outputA-out-0", "hello foo");
@@ -292,11 +292,11 @@ public class StreamBridgeTests {
@Test
void testBindingsAreRemovedWithCache() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false",
"--spring.cloud.stream.dynamic-destination-cache-size=1"
)) {
.getCompleteConfiguration(InterceptorConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false",
"--spring.cloud.stream.dynamic-destination-cache-size=1"
)) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("a", "hello foo");
@@ -334,13 +334,13 @@ public class StreamBridgeTests {
@Test
void testBindingPropertiesAreHonored() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(ConsumerConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=consumer;function",
"--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.foo.destination=function-in-0",
"--spring.cloud.stream.bindings.foo.producer.partitionCount=5",
"--spring.cloud.stream.bindings.foo.consumer.concurrency=2")) {
.getCompleteConfiguration(ConsumerConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=consumer;function",
"--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.foo.destination=function-in-0",
"--spring.cloud.stream.bindings.foo.producer.partitionCount=5",
"--spring.cloud.stream.bindings.foo.consumer.concurrency=2")) {
BindingServiceProperties bsProperties = context.getBean(BindingServiceProperties.class);
assertThat(bsProperties.getConsumerProperties("foo").getConcurrency()).isEqualTo(2);
@@ -360,10 +360,10 @@ public class StreamBridgeTests {
@Test
void testBridgeActivationWhenFunctionDefinitionIsPresent() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(SimpleConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=echo;uppercase",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(SimpleConfiguration.class))
.web(WebApplicationType.NONE).run(
"--spring.cloud.function.definition=echo;uppercase",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("echo-in-0", "hello foo");
@@ -387,9 +387,9 @@ public class StreamBridgeTests {
@Test
void testBridgeFunctions() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=foo;bar",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=foo;bar",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("foo-out-0", "hello foo");
@@ -405,9 +405,9 @@ public class StreamBridgeTests {
@Test
void testBridgeFunctionsSendingMessagePreservingHeaders() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=foo;bar",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=foo;bar",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("foo-out-0", MessageBuilder.withPayload("hello foo").setHeader("foo", "foo").build());
@@ -430,13 +430,13 @@ public class StreamBridgeTests {
@Test
void testBridgeFunctionsWitthPartitionInformation() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=foo;bar",
"--spring.cloud.stream.bindings.foo-out-0.producer.partitionKeyExpression=payload",
"--spring.cloud.stream.bindings.foo-out-0.producer.partitionCount=5",
"--spring.cloud.stream.bindings.bar-out-0.producer.partitionKeyExpression=payload",
"--spring.cloud.stream.bindings.bar-out-0.producer.partitionCount=1",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(EmptyConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=foo;bar",
"--spring.cloud.stream.bindings.foo-out-0.producer.partitionKeyExpression=payload",
"--spring.cloud.stream.bindings.foo-out-0.producer.partitionCount=5",
"--spring.cloud.stream.bindings.bar-out-0.producer.partitionKeyExpression=payload",
"--spring.cloud.stream.bindings.bar-out-0.producer.partitionCount=1",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("foo-out-0", "a");
@@ -485,9 +485,9 @@ public class StreamBridgeTests {
@Test
void testSendingMessageToOutputOfExistingSupplier() throws Exception {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(TestConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=supplier;foo",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(TestConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=supplier;foo",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("supplier-out-0", "blah");
@@ -507,8 +507,8 @@ public class StreamBridgeTests {
@Test
void testDynamicDestination() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(TestConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
.getCompleteConfiguration(TestConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
OutputDestination outputDestination = context.getBean(OutputDestination.class);
@@ -531,8 +531,8 @@ public class StreamBridgeTests {
@Test
void testWithIntegrationFlowBecauseMarcinSaidSo() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(IntegrationFlowConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
.getCompleteConfiguration(IntegrationFlowConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("foo", "blah");
@@ -546,9 +546,9 @@ public class StreamBridgeTests {
@Test
void testNewBindingCallback() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestChannelBinderConfiguration
.getCompleteConfiguration(BindingCallbackConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=uppercase",
"--spring.jmx.enabled=false")) {
.getCompleteConfiguration(BindingCallbackConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.cloud.stream.source=uppercase",
"--spring.jmx.enabled=false")) {
StreamBridge bridge = context.getBean(StreamBridge.class);
bridge.send("uppercase-in-0", "hello");
@@ -612,8 +612,8 @@ public class StreamBridgeTests {
@Nullable
protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
if (headers.containsKey(MessageHeaders.CONTENT_TYPE) &&
(headers.get(MessageHeaders.CONTENT_TYPE).toString().endsWith("+foo") ||
headers.get(MessageHeaders.CONTENT_TYPE).toString().endsWith("+blah"))) {
(headers.get(MessageHeaders.CONTENT_TYPE).toString().endsWith("+foo") ||
headers.get(MessageHeaders.CONTENT_TYPE).toString().endsWith("+blah"))) {
return payload;
}
return null;
@@ -639,7 +639,7 @@ public class StreamBridgeTests {
@Nullable
protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers, @Nullable Object conversionHint) {
if (headers.containsKey(MessageHeaders.CONTENT_TYPE) &&
(headers.get(MessageHeaders.CONTENT_TYPE).toString().endsWith("+non-registered-foo"))) {
(headers.get(MessageHeaders.CONTENT_TYPE).toString().endsWith("+non-registered-foo"))) {
return payload;
}
return null;
@@ -664,9 +664,9 @@ public class StreamBridgeTests {
int partitionCount = properties.getProducerProperties("foo").getPartitionCount();
BindingServiceProperties p = properties;
return MessageBuilder.withPayload(v)
.setHeader("concurrency", concurrency)
.setHeader("partitionCount", partitionCount)
.build();
.setHeader("concurrency", concurrency)
.setHeader("partitionCount", partitionCount)
.build();
};
}
}
@@ -742,11 +742,11 @@ public class StreamBridgeTests {
@Bean
public IntegrationFlow transform(StreamBridge bridge) {
return IntegrationFlows.from("foo").transform(v -> {
String s = new String((byte[]) v);
return s.toUpperCase();
})
.handle(v -> bridge.send("output", v))
.get();
String s = new String((byte[]) v);
return s.toUpperCase();
})
.handle(v -> bridge.send("output", v))
.get();
}
}

View File

@@ -33,8 +33,8 @@ public class KotlinConfigurationTests {
void testKotlinSupplierPollableBean() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(KotlinTestConfiguration.class))
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=produceNames")) {
.web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=produceNames")) {
OutputDestination output = context.getBean(OutputDestination.class);
Message<byte[]> result = output.receive(1000, "produceNames-out-0");

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2015-2019 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
*
* https://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.utils;
import org.mockito.Mockito;
import org.springframework.cloud.stream.binder.Binder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Marius Bogoevici
*/
@Configuration
public class IntegrationTestsMockBinderConfiguration {
@Bean
public Binder<?, ?, ?> binder() {
return Mockito.mock(Binder.class,
Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS));
}
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-stream-test-binder</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-stream-test-binder</name>
<description>Spring Cloud Stream Test Binder</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-core</artifactId>
<version>4.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2020 the original author or authors.
* Copyright 2017-2022 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.

View File

@@ -61,7 +61,7 @@ public final class FunctionBindingTestUtils {
applicationContext.getBeanFactory().registerSingleton(functionName, function);
Object actualFunction = ((FunctionInvocationWrapper) applicationContext
.getBean(FunctionCatalog.class).lookup(functionName)).getTarget();
.getBean(FunctionCatalog.class).lookup(functionName)).getTarget();
InitializingBean functionBindingRegistrar = applicationContext.getBean("functionBindingRegistrar", InitializingBean.class);
functionBindingRegistrar.afterPropertiesSet();
@@ -84,14 +84,14 @@ public final class FunctionBindingTestUtils {
TestChannelBinder binder = applicationContext.getBean(TestChannelBinder.class);
if (actualFunction instanceof Supplier || actualFunction instanceof Function) {
Binding<MessageChannel> bindProducer = binder.bindProducer(outputProperties.getDestination(),
applicationContext.getBean(outputBindingName, MessageChannel.class),
producerProperties == null ? new ProducerProperties() : producerProperties);
applicationContext.getBean(outputBindingName, MessageChannel.class),
producerProperties == null ? new ProducerProperties() : producerProperties);
bindProducer.start();
}
if (actualFunction instanceof Consumer || actualFunction instanceof Function) {
Binding<MessageChannel> bindConsumer = binder.bindConsumer(inputProperties.getDestination(), null,
applicationContext.getBean(inputBindingName, MessageChannel.class),
consumerProperties == null ? new ConsumerProperties() : consumerProperties);
applicationContext.getBean(inputBindingName, MessageChannel.class),
consumerProperties == null ? new ConsumerProperties() : consumerProperties);
bindConsumer.start();
}
}

View File

@@ -87,7 +87,7 @@ public class OutputDestination extends AbstractDestination {
@Deprecated
public Message<byte[]> receive(long timeout, int bindingIndex) {
log.warn("!!!While 'receive(long timeout, int bindingIndex)' method may still work it is deprecated no longer supported. "
+ "It will be removed after 3.1.3 release. Please use 'receive(long timeout, String bindingName)'");
+ "It will be removed after 3.1.3 release. Please use 'receive(long timeout, String bindingName)'");
try {
BlockingQueue<Message<byte[]>> destinationQueue = (new ArrayList<>(this.messageQueues.values())).get(bindingIndex);
return destinationQueue.poll(timeout, TimeUnit.MILLISECONDS);

View File

@@ -104,7 +104,7 @@ import org.springframework.util.StringUtils;
*
*/
public class TestChannelBinder extends
AbstractMessageChannelBinder<ConsumerProperties, ProducerProperties, TestChannelBinderProvisioner> {
AbstractMessageChannelBinder<ConsumerProperties, ProducerProperties, TestChannelBinderProvisioner> {
@Autowired
private BeanFactory beanFactory;
@@ -113,10 +113,10 @@ public class TestChannelBinder extends
@SuppressWarnings({ "unchecked", "rawtypes" })
private MessageSource<?> messageSourceDelegate = () -> new GenericMessage<>(
"polled data", new MapBuilder()
.put(MessageHeaders.CONTENT_TYPE, "text/plain")
.put(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK, (AcknowledgmentCallback) status -> {
}).get());
"polled data", new MapBuilder()
.put(MessageHeaders.CONTENT_TYPE, "text/plain")
.put(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK, (AcknowledgmentCallback) status -> {
}).get());
public TestChannelBinder(TestChannelBinderProvisioner provisioningProvider) {
super(new String[] {}, provisioningProvider);
@@ -141,29 +141,29 @@ public class TestChannelBinder extends
@Override
protected MessageHandler createProducerMessageHandler(ProducerDestination destination,
ProducerProperties producerProperties, MessageChannel errorChannel)
throws Exception {
ProducerProperties producerProperties, MessageChannel errorChannel)
throws Exception {
BridgeHandler handler = new BridgeHandler();
handler.setBeanFactory(this.beanFactory);
handler.setOutputChannel(
((SpringIntegrationProducerDestination) destination).getChannel());
((SpringIntegrationProducerDestination) destination).getChannel());
return handler;
}
@Override
protected MessageProducer createConsumerEndpoint(ConsumerDestination destination,
String group, ConsumerProperties properties) throws Exception {
String group, ConsumerProperties properties) throws Exception {
ErrorMessageStrategy errorMessageStrategy = new DefaultErrorMessageStrategy();
SubscribableChannel siBinderInputChannel = ((SpringIntegrationConsumerDestination) destination)
.getChannel();
.getChannel();
IntegrationMessageListeningContainer messageListenerContainer = new IntegrationMessageListeningContainer();
IntegrationBinderInboundChannelAdapter adapter = new IntegrationBinderInboundChannelAdapter(
messageListenerContainer);
messageListenerContainer);
String groupName = StringUtils.hasText(group) ? group : "anonymous";
ErrorInfrastructure errorInfrastructure = registerErrorInfrastructure(destination,
groupName, properties);
groupName, properties);
if (properties.getMaxAttempts() > 1) {
adapter.setRetryTemplate(buildRetryTemplate(properties));
adapter.setRecoveryCallback(errorInfrastructure.getRecoverer());
@@ -180,15 +180,15 @@ public class TestChannelBinder extends
@Override
protected PolledConsumerResources createPolledConsumerResources(String name,
String group, ConsumerDestination destination,
ConsumerProperties consumerProperties) {
String group, ConsumerDestination destination,
ConsumerProperties consumerProperties) {
return new PolledConsumerResources(this.messageSourceDelegate,
registerErrorInfrastructure(destination, group, consumerProperties));
registerErrorInfrastructure(destination, group, consumerProperties));
}
@Override
protected MessageHandler getErrorMessageHandler(ConsumerDestination destination,
String group, ConsumerProperties consumerProperties) {
String group, ConsumerProperties consumerProperties) {
return m -> {
this.logger.debug("Error handled: " + m);
this.lastError = m;
@@ -218,7 +218,7 @@ public class TestChannelBinder extends
* Implementation of inbound channel adapter modeled after AmqpInboundChannelAdapter.
*/
private static class IntegrationBinderInboundChannelAdapter
extends MessageProducerSupport {
extends MessageProducerSupport {
private static final ThreadLocal<AttributeAccessor> attributesHolder = new ThreadLocal<AttributeAccessor>();
@@ -229,13 +229,13 @@ public class TestChannelBinder extends
private RecoveryCallback<? extends Object> recoveryCallback;
IntegrationBinderInboundChannelAdapter(
IntegrationMessageListeningContainer listenerContainer) {
IntegrationMessageListeningContainer listenerContainer) {
this.listenerContainer = listenerContainer;
}
// Temporarily unused until DLQ strategy for this binder becomes a requirement
public void setRecoveryCallback(
RecoveryCallback<? extends Object> recoveryCallback) {
RecoveryCallback<? extends Object> recoveryCallback) {
this.recoveryCallback = recoveryCallback;
}
@@ -247,9 +247,9 @@ public class TestChannelBinder extends
protected void onInit() {
if (this.retryTemplate != null) {
Assert.state(getErrorChannel() == null,
"Cannot have an 'errorChannel' property when a 'RetryTemplate' is "
+ "provided; use an 'ErrorMessageSendingRecoverer' in the 'recoveryCallback' property to "
+ "send an error message when retries are exhausted");
"Cannot have an 'errorChannel' property when a 'RetryTemplate' is "
+ "provided; use an 'ErrorMessageSendingRecoverer' in the 'recoveryCallback' property to "
+ "send an error message when retries are exhausted");
}
Listener messageListener = new Listener();
if (this.retryTemplate != null) {
@@ -274,19 +274,19 @@ public class TestChannelBinder extends
}
else {
IntegrationBinderInboundChannelAdapter.this.retryTemplate
.execute(context -> {
processMessage(message);
return null;
}, (RecoveryCallback<Object>) IntegrationBinderInboundChannelAdapter.this.recoveryCallback);
.execute(context -> {
processMessage(message);
return null;
}, (RecoveryCallback<Object>) IntegrationBinderInboundChannelAdapter.this.recoveryCallback);
}
}
catch (RuntimeException e) {
if (getErrorChannel() != null) {
getMessagingTemplate()
.send(getErrorChannel(),
buildErrorMessage(null, new IllegalStateException(
"Message conversion failed: " + message,
e)));
.send(getErrorChannel(),
buildErrorMessage(null, new IllegalStateException(
"Message conversion failed: " + message,
e)));
}
else {
throw e;
@@ -300,7 +300,7 @@ public class TestChannelBinder extends
@Override
public <T, E extends Throwable> boolean open(RetryContext context,
RetryCallback<T, E> callback) {
RetryCallback<T, E> callback) {
if (IntegrationBinderInboundChannelAdapter.this.recoveryCallback != null) {
attributesHolder.set(context);
}
@@ -309,13 +309,13 @@ public class TestChannelBinder extends
@Override
public <T, E extends Throwable> void close(RetryContext context,
RetryCallback<T, E> callback, Throwable throwable) {
RetryCallback<T, E> callback, Throwable throwable) {
attributesHolder.remove();
}
@Override
public <T, E extends Throwable> void onError(RetryContext context,
RetryCallback<T, E> callback, Throwable throwable) {
RetryCallback<T, E> callback, Throwable throwable) {
// Empty
}

View File

@@ -64,7 +64,7 @@ public class TestChannelBinderConfiguration<T> {
* annotation
*/
public static Class<?>[] getCompleteConfiguration(
Class<?>... additionalConfigurationClasses) {
Class<?>... additionalConfigurationClasses) {
List<Class<?>> configClasses = new ArrayList<>();
configClasses.add(TestChannelBinderConfiguration.class);
configClasses.add(BindingServiceConfiguration.class);
@@ -82,7 +82,7 @@ public class TestChannelBinderConfiguration<T> {
*/
public static ApplicationContextRunner applicationContextRunner(Class<?>... additionalConfigurationClasses) {
return new ApplicationContextRunner()
.withUserConfiguration(getCompleteConfiguration(additionalConfigurationClasses));
.withUserConfiguration(getCompleteConfiguration(additionalConfigurationClasses));
}
@Bean
@@ -98,9 +98,9 @@ public class TestChannelBinderConfiguration<T> {
@SuppressWarnings("unchecked")
@Bean
public Binder<T, ? extends ConsumerProperties, ? extends ProducerProperties> springIntegrationChannelBinder(
TestChannelBinderProvisioner provisioner) {
TestChannelBinderProvisioner provisioner) {
return (Binder<T, ? extends ConsumerProperties, ? extends ProducerProperties>) new TestChannelBinder(
provisioner);
provisioner);
}
@Bean

View File

@@ -43,7 +43,7 @@ import org.springframework.messaging.SubscribableChannel;
*
*/
public class TestChannelBinderProvisioner
implements ProvisioningProvider<ConsumerProperties, ProducerProperties> {
implements ProvisioningProvider<ConsumerProperties, ProducerProperties> {
private final Map<String, SubscribableChannel> provisionedDestinations = new HashMap<>();
@@ -61,7 +61,7 @@ public class TestChannelBinderProvisioner
*/
@Override
public ProducerDestination provisionProducerDestination(String name,
ProducerProperties properties) throws ProvisioningException {
ProducerProperties properties) throws ProvisioningException {
SubscribableChannel destination = this.provisionDestination(name, true);
this.target.setChannel(destination);
return new SpringIntegrationProducerDestination(name, destination);
@@ -72,7 +72,7 @@ public class TestChannelBinderProvisioner
*/
@Override
public ConsumerDestination provisionConsumerDestination(String name, String group,
ConsumerProperties properties) throws ProvisioningException {
ConsumerProperties properties) throws ProvisioningException {
SubscribableChannel destination = this.provisionDestination(name, false);
if (this.source != null) {
this.source.setChannel(destination);
@@ -83,7 +83,7 @@ public class TestChannelBinderProvisioner
private SubscribableChannel provisionDestination(String name, boolean pubSub) {
String destinationName = name + ".destination";
SubscribableChannel destination = this.provisionedDestinations
.get(destinationName);
.get(destinationName);
if (destination == null) {
destination = new PublishSubscribeChannel();
((AbstractMessageChannel) destination).setBeanName(destinationName);

View File

@@ -38,12 +38,12 @@ public class TestChannelBinderTests {
public void test() throws Exception {
// nothing to assert. no failure on this test signifies success
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration.getCompleteConfiguration(SampleConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.function-in-0.destination=input")) {
TestChannelBinderConfiguration.getCompleteConfiguration(SampleConfiguration.class))
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false",
"--spring.cloud.stream.bindings.function-in-0.destination=input")) {
TestChannelBinder binder = context.getBean(TestChannelBinder.class);
Method registerErrorInfrastructure = ReflectionUtils
.findMethod(TestChannelBinder.class, "registerErrorInfrastructure", ProducerDestination.class, String.class);
.findMethod(TestChannelBinder.class, "registerErrorInfrastructure", ProducerDestination.class, String.class);
registerErrorInfrastructure.setAccessible(true);
ProducerDestination destination = new ProducerDestination() {
@Override

View File

@@ -69,7 +69,6 @@
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
@@ -80,43 +79,15 @@
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<configuration>
<includes>
<include>**/test/*</include>
</includes>
<classifier>test-binder</classifier>
</configuration>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
@@ -147,26 +118,6 @@
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

View File

@@ -1,31 +0,0 @@
/*
* Copyright 2017-2019 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
*
* https://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.
*/
/**
* Provides test channel binder and supporting classes
*
* THe test binder is backed by Spring Integration framework and is not intended for uses
* outside of local testing.
*
* The test binder implementation -
* {@link org.springframework.cloud.stream.binder.test.TestChannelBinder} The test binder
* configuration -
* {@link org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration} The
* example that shows how to use it -
* {@link org.springframework.cloud.stream.binder.test.SampleStreamApp}
*
*/
package org.springframework.cloud.stream.binder.test;

View File

@@ -1,311 +0,0 @@
/*
* Copyright 2019-2022 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
*
* https://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.function;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import org.assertj.core.util.Arrays;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.stream.binder.test.InputDestination;
import org.springframework.cloud.stream.binder.test.OutputDestination;
import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.kafka.support.KafkaNull;
import org.springframework.messaging.Message;
import static org.assertj.core.api.Assertions.assertThat;
/**
*
* @author Gary Russel
* @author Oleg Zhurakousky
* @author David Turanski
*
* @since 3.0
*/
public class FunctionBatchingTests {
@Test
void testMessageBatchConfigurationWithKafkaNull() {
TestChannelBinderConfiguration.applicationContextRunner(MessageBatchConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.input.consumer.batch-mode=true")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List<Object> list = new ArrayList<>();
list.add("{\"name\":\"bob\"}".getBytes());
list.add("{\"name\":\"jill\"}".getBytes());
list.add(KafkaNull.INSTANCE);
list.add("{\"name\":\"steve\"}".getBytes());
Message<List<Object>> inputMessage = MessageBuilder
.withPayload(list)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(outputMessage).isNotNull();
assertThat(outputMessage.getPayload())
.isEqualTo("{\"name\":\"bob\"}".getBytes());
context.stop();
});
}
@Test
void testListPayloadConfiguration() {
TestChannelBinderConfiguration.applicationContextRunner(ListPayloadNotBatchConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
Message<byte[]> inputMessage = MessageBuilder
.withPayload("[{\"name\":\"bob\"},{\"name\":\"jill\"}]".getBytes())
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(outputMessage).isNotNull();
assertThat(outputMessage.getPayload())
.isEqualTo("{\"name\":\"bob\"}".getBytes());
context.stop();
});
}
@Test
void testListStringPayloadConfigurationTextPlain() {
TestChannelBinderConfiguration.applicationContextRunner(ListStringPayloadConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.func-in-0.content-type=text/plain")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List bytes = Arrays.asList(new Object[] {"abc".getBytes(), "xyz".getBytes()});
Message inputMessage = MessageBuilder.withPayload(bytes).build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(new String(outputMessage.getPayload())).isEqualTo("[abc, xyz]");
context.stop();
});
}
@Test
void testListObjectPayloadObjectConfigurationTextPlain() {
TestChannelBinderConfiguration.applicationContextRunner(ListObjectPayloadConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.func-in-0.content-type=text/plain")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List bytes = Arrays.asList(new Object[] {"abc".getBytes(), "xyz".getBytes()});
Message inputMessage = MessageBuilder.withPayload(bytes).build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(new String(outputMessage.getPayload())).isEqualTo("[abc, xyz]");
context.stop();
});
}
@Test
void testSimpleBatchConfiguration() {
TestChannelBinderConfiguration.applicationContextRunner(SimpleBatchConfiguration.class)
.withPropertyValues(
"spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.input.consumer.batch-mode=true")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List<byte[]> list = new ArrayList<>();
list.add("{\"name\":\"bob\"}".getBytes());
list.add("{\"name\":\"jill\"}".getBytes());
Message<List<byte[]>> inputMessage = MessageBuilder
.withPayload(list)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(outputMessage).isNotNull();
assertThat(outputMessage.getPayload())
.isEqualTo("{\"name\":\"bob\"}".getBytes());
context.stop();
});
}
@Test
void testNestedBatchConfiguration() {
TestChannelBinderConfiguration.applicationContextRunner(NestedBatchConfiguration.class)
.withPropertyValues("spring.jmx.enabled=false",
"spring.cloud.stream.function.definition=func",
"spring.cloud.stream.bindings.input.consumer.batch-mode=true")
.run(context -> {
InputDestination inputDestination = context.getBean(InputDestination.class);
OutputDestination outputDestination = context
.getBean(OutputDestination.class);
List<byte[]> list = new ArrayList<>();
list.add("[{\"name\":\"bob\"},{\"name\":\"jill\"}]".getBytes());
Message<List<byte[]>> inputMessage = MessageBuilder
.withPayload(list)
.build();
inputDestination.send(inputMessage);
Message<byte[]> outputMessage = outputDestination.receive();
assertThat(outputMessage).isNotNull();
assertThat(outputMessage.getPayload())
.isEqualTo("{\"name\":\"bob\"}".getBytes());
context.stop();
});
}
@EnableAutoConfiguration
public static class SimpleBatchConfiguration {
@Bean
public Function<List<Person>, Person> func() {
return x -> x.get(0);
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
@EnableAutoConfiguration
public static class ListStringPayloadConfiguration {
@Bean
public Function<List<String>, String> func() {
return x -> x.toString();
}
}
@EnableAutoConfiguration
public static class ListObjectPayloadConfiguration {
@Bean
public Function<List<Object>, String> func() {
return x -> x.toString();
}
}
@EnableAutoConfiguration
public static class ListPayloadNotBatchConfiguration {
@Bean
public Function<List<Person>, Person> func() {
return x -> x.get(0);
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
@EnableAutoConfiguration
public static class NestedBatchConfiguration {
@Bean
public Function<List<List<Person>>, Person> func() {
return x -> x.get(0).get(0);
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
@EnableAutoConfiguration
public static class MessageBatchConfiguration {
@Bean
public Function<Message<List<Person>>, Person> func() {
return x -> {
Object o = x.getPayload().get(2);
assertThat(o).isNull();
return (Person) x.getPayload().get(0);
};
}
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
}

View File

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

15
pom.xml
View File

@@ -58,7 +58,6 @@
<artifactId>jackson-databind</artifactId>
<version>2.13.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-context</artifactId>
@@ -87,17 +86,9 @@
<version>${objenesis.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.4</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
<classifier>test-binder</classifier>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.4</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@@ -47,11 +47,8 @@
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<artifactId>spring-cloud-stream-test-binder</artifactId>
<scope>test</scope>
<classifier>test-binder</classifier>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>