Initial take on removing StreamListener
StreamListener was deprecated in 3.0.x. This commit is the initial one in removing StreamListener and it's related components completely in 4.0.x. More tests need to be adjusted and migrated which will be addressed in later commits.
This commit is contained in:
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.handler.annotation.Header;
|
||||
import org.springframework.messaging.handler.annotation.Headers;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class StreamListenerAnnotatedMethodArgumentsTests {
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
Locale.setDefault(Locale.US);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testAnnotatedArguments() {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(TestPojoWithAnnotatedArguments.class, "--server.port=0");
|
||||
|
||||
TestPojoWithAnnotatedArguments testPojoWithAnnotatedArguments = context
|
||||
.getBean(TestPojoWithAnnotatedArguments.class);
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
sink.input()
|
||||
.send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", MimeType.valueOf("application/json"))
|
||||
.setHeader("testHeader", "testValue").build());
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedArguments).hasSize(3);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(0))
|
||||
.isInstanceOf(StreamListenerTestUtils.FooPojo.class);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(1))
|
||||
.isInstanceOf(Map.class);
|
||||
assertThat((Map<String, Object>) testPojoWithAnnotatedArguments.receivedArguments
|
||||
.get(1)).containsEntry(MessageHeaders.CONTENT_TYPE,
|
||||
MimeType.valueOf("application/json"));
|
||||
assertThat((Map<String, String>) testPojoWithAnnotatedArguments.receivedArguments
|
||||
.get(1)).containsEntry("testHeader", "testValue");
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedArguments.get(2))
|
||||
.isEqualTo("application/json");
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInputAnnotationAtMethodParameter() {
|
||||
try {
|
||||
SpringApplication.run(TestPojoWithInvalidInputAnnotatedArgument.class,
|
||||
"--server.port=0");
|
||||
fail("Exception expected: " + INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidAnnotationAtMethodParameterWithPojoThatPassesValidation() {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestPojoWithValidAnnotationThatPassesValidation.class, "--server.port=0");
|
||||
|
||||
TestPojoWithValidAnnotationThatPassesValidation testPojoWithValidAnnotationThatPassesValidation = context
|
||||
.getBean(TestPojoWithValidAnnotationThatPassesValidation.class);
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
sink.input().send(MessageBuilder.withPayload("{\"foo\":\"" + id + "\"}")
|
||||
.setHeader("contentType", MimeType.valueOf("application/json")).build());
|
||||
assertThat(
|
||||
testPojoWithValidAnnotationThatPassesValidation.receivedArguments.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testValidAnnotationAtMethodParameterWithPojoThatFailsValidation() {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestPojoWithValidAnnotationThatPassesValidation.class, "--server.port=0");
|
||||
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
try {
|
||||
sink.input().send(MessageBuilder.withPayload("{\"foo\":\"\"}")
|
||||
.setHeader("contentType", MimeType.valueOf("application/json"))
|
||||
.build());
|
||||
fail("Exception expected: MethodArgumentNotValidException!");
|
||||
}
|
||||
catch (MethodArgumentNotValidException e) {
|
||||
assertThat(e.getMessage()).contains(
|
||||
"default message [foo]]; default message [must not be blank]]");
|
||||
}
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithAnnotatedArguments {
|
||||
|
||||
List<Object> receivedArguments = new ArrayList<>();
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo,
|
||||
@Headers Map<String, Object> headers,
|
||||
@Header(MessageHeaders.CONTENT_TYPE) String contentType) {
|
||||
this.receivedArguments.add(fooPojo);
|
||||
this.receivedArguments.add(headers);
|
||||
this.receivedArguments.add(contentType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithInvalidInputAnnotatedArgument {
|
||||
|
||||
List<Object> receivedArguments = new ArrayList<>();
|
||||
|
||||
@StreamListener
|
||||
public void receive(
|
||||
@Input(Processor.INPUT) @Payload StreamListenerTestUtils.FooPojo fooPojo,
|
||||
@Headers Map<String, Object> headers,
|
||||
@Header(MessageHeaders.CONTENT_TYPE) String contentType) {
|
||||
this.receivedArguments.add(fooPojo);
|
||||
this.receivedArguments.add(headers);
|
||||
this.receivedArguments.add(contentType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithValidAnnotationThatPassesValidation {
|
||||
|
||||
List<Object> receivedArguments = new ArrayList<>();
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
public void receive(
|
||||
@Valid StreamListenerTestUtils.PojoWithValidation pojoWithValidation) {
|
||||
this.receivedArguments.add(pojoWithValidation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerAnnotationBeanPostProcessor;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.cloud.stream.config.BindingServiceConfiguration.STREAM_LISTENER_ANNOTATION_BEAN_POST_PROCESSOR_NAME;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class StreamListenerAnnotationBeanPostProcessorOverrideTest {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@Ignore
|
||||
public void testOverrideStreamListenerAnnotationBeanPostProcessor() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(TestPojoWithAnnotatedArguments.class, "--server.port=0");
|
||||
|
||||
TestPojoWithAnnotatedArguments testPojoWithAnnotatedArguments = context
|
||||
.getBean(TestPojoWithAnnotatedArguments.class);
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json")
|
||||
.setHeader("testHeader", "testValue").setHeader("type", "foo").build());
|
||||
sink.input().send(MessageBuilder.withPayload("{\"bar\":\"foofoo" + id + "\"}")
|
||||
.setHeader("contentType", "application/json")
|
||||
.setHeader("testHeader", "testValue").setHeader("type", "bar").build());
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedFoo).hasSize(1);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithAnnotatedArguments {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedFoo = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Overrides the default {@link StreamListenerAnnotationBeanPostProcessor}.
|
||||
*/
|
||||
@Bean(name = STREAM_LISTENER_ANNOTATION_BEAN_POST_PROCESSOR_NAME)
|
||||
public static StreamListenerAnnotationBeanPostProcessor streamListenerAnnotationBeanPostProcessor() {
|
||||
return new StreamListenerAnnotationBeanPostProcessor() {
|
||||
@Override
|
||||
protected StreamListener postProcessAnnotation(
|
||||
StreamListener originalAnnotation, Method annotatedMethod) {
|
||||
Map<String, Object> attributes = new HashMap<>(
|
||||
AnnotationUtils.getAnnotationAttributes(originalAnnotation));
|
||||
attributes.put("condition",
|
||||
"headers['type']=='" + originalAnnotation.condition() + "'");
|
||||
return AnnotationUtils.synthesizeAnnotation(attributes,
|
||||
StreamListener.class, annotatedMethod);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@StreamListener(value = Sink.INPUT, condition = "foo")
|
||||
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedFoo.add(fooPojo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,147 +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.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.stream.config;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@MessageMapping
|
||||
@Documented
|
||||
@StreamListener
|
||||
@interface EventHandler {
|
||||
|
||||
/**
|
||||
* The name of the binding target (e.g. channel) that the method subscribes to.
|
||||
* @return the name of the binding target.
|
||||
*/
|
||||
@AliasFor(annotation = StreamListener.class, attribute = "target")
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* The name of the binding target (e.g. channel) that the method subscribes to.
|
||||
* @return the name of the binding target.
|
||||
*/
|
||||
@AliasFor(annotation = StreamListener.class, attribute = "target")
|
||||
String target() default "";
|
||||
|
||||
/**
|
||||
* A condition that must be met by all items that are dispatched to this method.
|
||||
* @return a SpEL expression that must evaluate to a {@code boolean} value.
|
||||
*/
|
||||
@AliasFor(annotation = StreamListener.class, attribute = "condition")
|
||||
String condition() default "";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*/
|
||||
public class StreamListenerAsMetaAnnotationTests {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testCustomAnnotation() {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(TestPojoWithCustomAnnotatedArguments.class, "--server.port=0");
|
||||
|
||||
TestPojoWithCustomAnnotatedArguments testPojoWithAnnotatedArguments = context
|
||||
.getBean(TestPojoWithCustomAnnotatedArguments.class);
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json")
|
||||
.setHeader("testHeader", "testValue").setHeader("type", "foo").build());
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedFoo).hasSize(1);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testAnnotation() {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(TestPojoWithAnnotatedArguments.class, "--server.port=0");
|
||||
|
||||
TestPojoWithAnnotatedArguments testPojoWithAnnotatedArguments = context
|
||||
.getBean(TestPojoWithAnnotatedArguments.class);
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json")
|
||||
.setHeader("testHeader", "testValue").setHeader("type", "foo").build());
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedFoo).hasSize(1);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithCustomAnnotatedArguments {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedFoo = new ArrayList<>();
|
||||
|
||||
List<StreamListenerTestUtils.BarPojo> receivedBar = new ArrayList<>();
|
||||
|
||||
@EventHandler(value = Sink.INPUT, condition = "headers['type']=='foo'")
|
||||
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedFoo.add(fooPojo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithAnnotatedArguments {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedFoo = new ArrayList<>();
|
||||
|
||||
List<StreamListenerTestUtils.BarPojo> receivedBar = new ArrayList<>();
|
||||
|
||||
@StreamListener(value = Sink.INPUT, condition = "headers['type']=='foo'")
|
||||
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedFoo.add(fooPojo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
*/
|
||||
public class StreamListenerContentTypeConversionTests {
|
||||
|
||||
@Test
|
||||
public void testContentTypeConversion() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(TestSinkWithContentTypeConversion.class, "--server.port=0");
|
||||
@SuppressWarnings("unchecked")
|
||||
TestSinkWithContentTypeConversion testSink = context
|
||||
.getBean(TestSinkWithContentTypeConversion.class);
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
assertThat(testSink.latch.await(10, TimeUnit.SECONDS));
|
||||
assertThat(testSink.receivedArguments).hasSize(1);
|
||||
assertThat(testSink.receivedArguments.get(0)).hasFieldOrPropertyWithValue("foo",
|
||||
"barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestSinkWithContentTypeConversion {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedArguments = new ArrayList<>();
|
||||
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
@StreamListener(Sink.INPUT)
|
||||
public void receive(StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedArguments.add(fooPojo);
|
||||
this.latch.countDown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerErrorMessages;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
*/
|
||||
public class StreamListenerDuplicateMappingTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMultipleMappingsWithReturnValue() {
|
||||
ConfigurableApplicationContext context = null;
|
||||
try {
|
||||
context = SpringApplication.run(TestMultipleMappingsWithReturnValue.class,
|
||||
"--server.port=0");
|
||||
fail("Exception expected on duplicate mapping");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).startsWith(
|
||||
StreamListenerErrorMessages.MULTIPLE_VALUE_RETURNING_METHODS);
|
||||
}
|
||||
finally {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateMappingFromAbstractMethod() {
|
||||
ConfigurableApplicationContext context = null;
|
||||
try {
|
||||
context = SpringApplication.run(TestDuplicateMappingFromAbstractMethod.class,
|
||||
"--server.port=0");
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
String errorMessage = e.getCause().getMessage()
|
||||
.startsWith("Duplicate @StreamListener mapping")
|
||||
? "Duplicate mapping exception is not expected"
|
||||
: "Test failed with exception";
|
||||
fail(errorMessage + ": " + e.getMessage());
|
||||
}
|
||||
finally {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface GenericSink<T extends Base> {
|
||||
|
||||
void testMethod(T msg);
|
||||
|
||||
}
|
||||
|
||||
public interface Base {
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMultipleMappingsWithReturnValue {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public String receive(Message<String> fooMessage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public String receiveDuplicateMapping(Message<String> fooMessage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestDuplicateMappingFromAbstractMethod
|
||||
implements GenericSink<TestBase> {
|
||||
|
||||
@Override
|
||||
@StreamListener(Sink.INPUT)
|
||||
public void testMethod(TestBase msg) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TestBase implements Base {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class StreamListenerHandlerBeanTests {
|
||||
|
||||
private Class<?> configClass;
|
||||
|
||||
public StreamListenerHandlerBeanTests(Class<?> configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<?> InputConfigs() {
|
||||
return Arrays.asList(TestHandlerBeanWithSendTo.class, TestHandlerBean2.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testHandlerBean() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
|
||||
"--spring.cloud.stream.bindings.output.contentType=application/json",
|
||||
"--server.port=0");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input()
|
||||
.send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
HandlerBean handlerBean = context.getBean(HandlerBean.class);
|
||||
Assertions.assertThat(handlerBean.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(handlerBean.receivedPojos.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload()).isEqualTo("{\"bar\":\"barbar" + id + "\"}");
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestHandlerBeanWithSendTo {
|
||||
|
||||
@Bean
|
||||
public HandlerBeanWithSendTo handlerBean() {
|
||||
return new HandlerBeanWithSendTo();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestHandlerBean2 {
|
||||
|
||||
@Bean
|
||||
public HandlerBeanWithOutput handlerBean() {
|
||||
return new HandlerBeanWithOutput();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class HandlerBeanWithSendTo extends HandlerBean {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public StreamListenerTestUtils.BarPojo receive(
|
||||
StreamListenerTestUtils.FooPojo fooMessage) {
|
||||
this.receivedPojos.add(fooMessage);
|
||||
StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo();
|
||||
barPojo.setBar(fooMessage.getFoo());
|
||||
return barPojo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class HandlerBeanWithOutput extends HandlerBean {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@Output(Processor.OUTPUT)
|
||||
public StreamListenerTestUtils.BarPojo receive(
|
||||
StreamListenerTestUtils.FooPojo fooMessage) {
|
||||
this.receivedPojos.add(fooMessage);
|
||||
StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo();
|
||||
barPojo.setBar(fooMessage.getFoo());
|
||||
return barPojo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class HandlerBean {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedPojos = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,623 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerErrorMessages;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.annotation.Router;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.support.DefaultMessageBuilderFactory;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INPUT_AT_STREAM_LISTENER;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INVALID_INBOUND_NAME;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INVALID_OUTBOUND_NAME;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INVALID_OUTPUT_VALUES;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.NO_INPUT_DESTINATION;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.RETURN_TYPE_MULTIPLE_OUTBOUND_SPECIFIED;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.RETURN_TYPE_NO_OUTBOUND_SPECIFIED;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Gary Russell
|
||||
* @author Vinicius Carvalho
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class StreamListenerHandlerMethodTests {
|
||||
|
||||
@Test
|
||||
public void testInvalidInputOnMethod() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestInvalidInputOnMethod.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + INPUT_AT_STREAM_LISTENER);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(INPUT_AT_STREAM_LISTENER);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testMethodWithObjectAsMethodArgument() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestMethodWithObjectAsMethodArgument.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.input.contentType=text/plain",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
final String testMessage = "testing";
|
||||
processor.input().send(MessageBuilder.withPayload(testMessage).build());
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<String> result = (Message<String>) messageCollector
|
||||
.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
/**
|
||||
* @since 2.0 : This test is an example of the new behavior of 2.0 when it comes to
|
||||
* contentType handling. The default contentType being JSON in order to be able to
|
||||
* check a message without quotes the user needs to set the input/output contentType
|
||||
* accordingly Also, received messages are always of Message<byte[]> now.
|
||||
*/
|
||||
public void testMethodHeadersPropagatged() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestMethodHeadersPropagated.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.input.contentType=text/plain",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
final String testMessage = "testing";
|
||||
processor.input().send(
|
||||
MessageBuilder.withPayload(testMessage).setHeader("foo", "bar").build());
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<String> result = (Message<String>) messageCollector
|
||||
.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase());
|
||||
assertThat(result.getHeaders().get("foo")).isEqualTo("bar");
|
||||
context.close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
@Disabled
|
||||
public void testMethodHeadersNotPropagatged() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestMethodHeadersNotPropagated.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.input.contentType=text/plain",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
final String testMessage = "testing";
|
||||
processor.input().send(
|
||||
MessageBuilder.withPayload(testMessage).setHeader("foo", "bar").build());
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<String> result = (Message<String>) messageCollector
|
||||
.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase());
|
||||
assertThat(result.getHeaders().get("foo")).isNull();
|
||||
context.close();
|
||||
}
|
||||
|
||||
// TODO: Handle dynamic destinations and contentType
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testStreamListenerMethodWithTargetBeanFromOutside() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestStreamListenerMethodWithTargetBeanFromOutside.class,
|
||||
"--server.port=0", "--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.input.contentType=text/plain",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain");
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
final String testMessageToSend = "testing";
|
||||
sink.input().send(MessageBuilder.withPayload(testMessageToSend).build());
|
||||
DirectChannel directChannel = (DirectChannel) context
|
||||
.getBean(testMessageToSend.toUpperCase(), MessageChannel.class);
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<String> result = (Message<String>) messageCollector
|
||||
.forChannel(directChannel).poll(1000, TimeUnit.MILLISECONDS);
|
||||
sink.input().send(MessageBuilder.withPayload(testMessageToSend).build());
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessageToSend.toUpperCase());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidReturnTypeWithSendToAndOutput() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestReturnTypeWithMultipleOutput.class,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + RETURN_TYPE_MULTIPLE_OUTBOUND_SPECIFIED);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(RETURN_TYPE_MULTIPLE_OUTBOUND_SPECIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidReturnTypeWithNoOutput() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestInvalidReturnTypeWithNoOutput.class,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + RETURN_TYPE_NO_OUTBOUND_SPECIFIED);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(RETURN_TYPE_NO_OUTBOUND_SPECIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidInputAnnotationWithNoValue() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestInvalidInputAnnotationWithNoValue.class,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + INVALID_INBOUND_NAME);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(INVALID_INBOUND_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidOutputAnnotationWithNoValue() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestInvalidOutputAnnotationWithNoValue.class,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + INVALID_OUTBOUND_NAME);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(INVALID_OUTBOUND_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodInvalidInboundName() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodInvalidInboundName.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected on using invalid inbound name");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(
|
||||
StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodInvalidOutboundName() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodInvalidOutboundName.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected on using invalid outbound name");
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e) {
|
||||
assertThat(e.getMessage()).contains("invalid");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousMethodArguments1() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestAmbiguousMethodArguments1.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage())
|
||||
.contains(AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAmbiguousMethodArguments2() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestAmbiguousMethodArguments2.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected:" + AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage())
|
||||
.contains(AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodWithInputAsMethodAndParameter() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodWithInputAsMethodAndParameter.class,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodWithOutputAsMethodAndParameter() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodWithOutputAsMethodAndParameter.class,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
fail("Exception expected:" + INVALID_OUTPUT_VALUES);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).startsWith(INVALID_OUTPUT_VALUES);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodWithoutInput() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodWithoutInput.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected when inbound target is not set");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(NO_INPUT_DESTINATION);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodWithMultipleInputParameters() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestMethodWithMultipleInputParameters.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
StreamListenerTestUtils.FooInboundChannel1 inboundChannel2 = context
|
||||
.getBean(StreamListenerTestUtils.FooInboundChannel1.class);
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
((SubscribableChannel) processor.output()).subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
Assert.isTrue(
|
||||
message.getPayload().equals("footesting")
|
||||
|| message.getPayload().equals("BARTESTING"),
|
||||
"Assert failed");
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
processor.input().send(MessageBuilder.withPayload("{\"foo\":\"fooTESTing\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
inboundChannel2.input()
|
||||
.send(MessageBuilder.withPayload("{\"bar\":\"bartestING\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
assertThat(latch.await(1, TimeUnit.SECONDS));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodWithMultipleOutputParameters() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestMethodWithMultipleOutputParameters.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
StreamListenerTestUtils.FooOutboundChannel1 source2 = context
|
||||
.getBean(StreamListenerTestUtils.FooOutboundChannel1.class);
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
((SubscribableChannel) processor.output()).subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
Assert.isTrue(message.getPayload().equals("testing"), "Assert failed");
|
||||
Assert.isTrue(message.getHeaders().get("output").equals("output2"),
|
||||
"Assert failed");
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
((SubscribableChannel) source2.output()).subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
Assert.isTrue(message.getPayload().equals("TESTING"), "Assert failed");
|
||||
Assert.isTrue(message.getHeaders().get("output").equals("output1"),
|
||||
"Assert failed");
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
processor.input().send(MessageBuilder.withPayload("testING")
|
||||
.setHeader("output", "output1").build());
|
||||
processor.input().send(MessageBuilder.withPayload("TESTing")
|
||||
.setHeader("output", "output2").build());
|
||||
assertThat(latch.await(1, TimeUnit.SECONDS));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodWithMultipleOutputParameters {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
|
||||
@Output(Processor.OUTPUT) final MessageChannel output1,
|
||||
@Output(StreamListenerTestUtils.FooOutboundChannel1.OUTPUT) final MessageChannel output2) {
|
||||
input.subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
if (message.getHeaders().get("output").equals("output1")) {
|
||||
output1.send(org.springframework.messaging.support.MessageBuilder
|
||||
.withPayload(
|
||||
message.getPayload().toString().toUpperCase())
|
||||
.build());
|
||||
}
|
||||
else if (message.getHeaders().get("output").equals("output2")) {
|
||||
output2.send(org.springframework.messaging.support.MessageBuilder
|
||||
.withPayload(
|
||||
message.getPayload().toString().toLowerCase())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Sink.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodWithoutInput {
|
||||
|
||||
@StreamListener
|
||||
public void receive(StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodWithObjectAsMethodArgument {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public String receive(Object received) {
|
||||
return received.toString().toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodHeadersPropagated {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public String receive(String received) {
|
||||
return received.toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodHeadersNotPropagated {
|
||||
|
||||
@StreamListener(value = Processor.INPUT, copyHeaders = "${foo.bar:false}")
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public String receive(String received) {
|
||||
return received.toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestStreamListenerMethodWithTargetBeanFromOutside {
|
||||
|
||||
private static final String ROUTER_QUEUE = "routeInstruction";
|
||||
|
||||
@StreamListener(Sink.INPUT)
|
||||
@SendTo(ROUTER_QUEUE)
|
||||
public Message<String> convertMessageBody(Message<String> message) {
|
||||
return new DefaultMessageBuilderFactory()
|
||||
.withPayload(message.getPayload().toUpperCase()).build();
|
||||
}
|
||||
|
||||
@Router(inputChannel = ROUTER_QUEUE)
|
||||
public String route(String message) {
|
||||
return message.toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Sink.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInvalidInputOnMethod {
|
||||
|
||||
@StreamListener
|
||||
@Input(Sink.INPUT)
|
||||
public void receive(StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Sink.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestAmbiguousMethodArguments1 {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo,
|
||||
String value) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Sink.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestAmbiguousMethodArguments2 {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo,
|
||||
@Payload StreamListenerTestUtils.BarPojo barPojo) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestReturnTypeWithMultipleOutput {
|
||||
|
||||
@StreamListener
|
||||
public String receive(@Input(Processor.INPUT) SubscribableChannel input1,
|
||||
@Output(Processor.OUTPUT) MessageChannel output1,
|
||||
@Output(StreamListenerTestUtils.FooOutboundChannel1.OUTPUT) MessageChannel output2) {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInvalidReturnTypeWithNoOutput {
|
||||
|
||||
@StreamListener
|
||||
public String receive(@Input(Processor.INPUT) SubscribableChannel input1) {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInvalidInputAnnotationWithNoValue {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input SubscribableChannel input) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInvalidOutputAnnotationWithNoValue {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input(Processor.OUTPUT) SubscribableChannel input,
|
||||
@Output MessageChannel output) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Sink.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodInvalidInboundName {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input("invalid") SubscribableChannel input) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodInvalidOutboundName {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
|
||||
@Output("invalid") MessageChannel output) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Sink.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodWithInputAsMethodAndParameter {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input(Sink.INPUT) StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooOutboundChannel1.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodWithOutputAsMethodAndParameter {
|
||||
|
||||
@StreamListener
|
||||
@Output(StreamListenerTestUtils.FooOutboundChannel1.OUTPUT)
|
||||
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
|
||||
@Output(Processor.OUTPUT) final MessageChannel output1) {
|
||||
input.subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
output1.send(org.springframework.messaging.support.MessageBuilder
|
||||
.withPayload(message.getPayload().toString().toUpperCase())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding({ Processor.class, StreamListenerTestUtils.FooInboundChannel1.class })
|
||||
@EnableAutoConfiguration
|
||||
public static class TestMethodWithMultipleInputParameters {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input(Processor.INPUT) SubscribableChannel input1,
|
||||
@Input(StreamListenerTestUtils.FooInboundChannel1.INPUT) SubscribableChannel input2,
|
||||
final @Output(Processor.OUTPUT) MessageChannel output) {
|
||||
input1.subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
output.send(org.springframework.messaging.support.MessageBuilder
|
||||
.withPayload(message.getPayload().toString().toUpperCase())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
input2.subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
output.send(org.springframework.messaging.support.MessageBuilder
|
||||
.withPayload(message.getPayload().toString().toUpperCase())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class StreamListenerMessageArgumentTests {
|
||||
|
||||
private Class<?> configClass;
|
||||
|
||||
public StreamListenerMessageArgumentTests(Class<?> configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<?> InputConfigs() {
|
||||
return Arrays.asList(new Class[] { TestPojoWithMessageArgument1.class,
|
||||
TestPojoWithMessageArgument2.class });
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMessageArgument() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
|
||||
"--server.port=0",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain",
|
||||
"--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input().send(MessageBuilder.withPayload("barbar" + id)
|
||||
.setHeader("contentType", "text/plain").build());
|
||||
TestPojoWithMessageArgument testPojoWithMessageArgument = context
|
||||
.getBean(TestPojoWithMessageArgument.class);
|
||||
assertThat(testPojoWithMessageArgument.receivedMessages).hasSize(1);
|
||||
assertThat(testPojoWithMessageArgument.receivedMessages.get(0).getPayload())
|
||||
.isEqualTo("barbar" + id);
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload()).contains("barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithMessageArgument1 extends TestPojoWithMessageArgument {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public StreamListenerTestUtils.BarPojo receive(Message<String> fooMessage) {
|
||||
this.receivedMessages.add(fooMessage);
|
||||
StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo();
|
||||
barPojo.setBar(fooMessage.getPayload());
|
||||
return barPojo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithMessageArgument2 extends TestPojoWithMessageArgument {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@Output(Processor.OUTPUT)
|
||||
public StreamListenerTestUtils.BarPojo receive(Message<String> fooMessage) {
|
||||
this.receivedMessages.add(fooMessage);
|
||||
StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo();
|
||||
barPojo.setBar(fooMessage.getPayload());
|
||||
return barPojo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestPojoWithMessageArgument {
|
||||
|
||||
List<Message<String>> receivedMessages = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* See issue https://github.com/spring-cloud/spring-cloud-stream/issues/1080
|
||||
*
|
||||
* StreamListener method called twice when using @SpyBean
|
||||
*
|
||||
* @author Soby Chacko
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest
|
||||
public class StreamListenerMethodRegisteredOnlyOnceTest {
|
||||
|
||||
@Autowired
|
||||
private SomeSink sink;
|
||||
|
||||
@SpyBean
|
||||
private SomeHandler handler;
|
||||
|
||||
@Test
|
||||
public void should_handleSomeMessage() {
|
||||
this.sink.channel().send(new GenericMessage<>("Payload"));
|
||||
verify(this.handler).handleMessage(); // should only be invoked once.
|
||||
}
|
||||
|
||||
public interface SomeSink {
|
||||
|
||||
@Input(Sink.INPUT)
|
||||
SubscribableChannel channel();
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(SomeSink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class SomeHandler {
|
||||
|
||||
@StreamListener(Sink.INPUT)
|
||||
public void handleMessage() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.model.InitializationError;
|
||||
import org.junit.runners.model.RunnerBuilder;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
* @author Oleg Zhurakousky
|
||||
*
|
||||
*/
|
||||
@RunWith(StreamListenerMethodReturnWithConversionTests.class)
|
||||
@Suite.SuiteClasses({
|
||||
StreamListenerMethodReturnWithConversionTests.TestReturnConversion.class,
|
||||
StreamListenerMethodReturnWithConversionTests.TestReturnNoConversion.class })
|
||||
public class StreamListenerMethodReturnWithConversionTests extends Suite {
|
||||
|
||||
public StreamListenerMethodReturnWithConversionTests(Class<?> klass,
|
||||
RunnerBuilder builder) throws InitializationError {
|
||||
super(klass, builder);
|
||||
}
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public static class TestReturnConversion {
|
||||
|
||||
private Class<?> configClass;
|
||||
|
||||
public TestReturnConversion(Class<?> configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<?> InputConfigs() {
|
||||
return Arrays.asList(new Class[] { TestPojoWithMimeType1.class,
|
||||
TestPojoWithMimeType2.class });
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReturnConversion() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
this.configClass,
|
||||
"--spring.cloud.stream.bindings.output.contentType=application/json",
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input()
|
||||
.send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
TestPojoWithMimeType testPojoWithMimeType = context
|
||||
.getBean(TestPojoWithMimeType.class);
|
||||
Assertions.assertThat(testPojoWithMimeType.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(new String(message.getPayload()))
|
||||
.isEqualTo("{\"bar\":\"barbar" + id + "\"}");
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public static class TestReturnNoConversion {
|
||||
|
||||
private Class<?> configClass;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public TestReturnNoConversion(Class<?> configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<?> InputConfigs() {
|
||||
return Arrays.asList(new Class[] { TestPojoWithMimeType1.class,
|
||||
TestPojoWithMimeType2.class });
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReturnNoConversion() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
this.configClass, "--server.port=0", "--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input()
|
||||
.send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
TestPojoWithMimeType testPojoWithMimeType = context
|
||||
.getBean(TestPojoWithMimeType.class);
|
||||
Assertions.assertThat(testPojoWithMimeType.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
StreamListenerTestUtils.BarPojo barPojo = this.mapper.readValue(
|
||||
message.getPayload(), StreamListenerTestUtils.BarPojo.class);
|
||||
assertThat(barPojo.getBar()).isEqualTo("barbar" + id);
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE,
|
||||
MimeType.class) != null);
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithMimeType1 extends TestPojoWithMimeType {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public StreamListenerTestUtils.BarPojo receive(
|
||||
StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedPojos.add(fooPojo);
|
||||
StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo();
|
||||
barPojo.setBar(fooPojo.getFoo());
|
||||
return barPojo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithMimeType2 extends TestPojoWithMimeType {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@Output(Processor.OUTPUT)
|
||||
public StreamListenerTestUtils.BarPojo receive(
|
||||
StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedPojos.add(fooPojo);
|
||||
StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo();
|
||||
barPojo.setBar(fooPojo.getFoo());
|
||||
return barPojo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestPojoWithMimeType {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedPojos = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018-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.config;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerAnnotationBeanPostProcessor;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerSetupMethodOrchestrator;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.cloud.stream.messaging.Source;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Soby Chacko
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest
|
||||
public class StreamListenerMethodSetupOrchestratorTests {
|
||||
|
||||
@SpyBean
|
||||
CustomOrchestrator customOrchestrator;
|
||||
|
||||
@SpyBean
|
||||
MultipleStreamListenerProcessor multipleStreamListenerProcessor;
|
||||
|
||||
@SpyBean
|
||||
StreamListenerAnnotationBeanPostProcessor streamListenerAnnotationBeanPostProcessor;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testCustomStreamListenerOrchestratorAndDefaultTogetherInSameContext()
|
||||
throws Exception {
|
||||
|
||||
// Two StreamListener methods, so 2 invocations
|
||||
verify(this.customOrchestrator, times(2)).supports(any());
|
||||
|
||||
Method method = this.multipleStreamListenerProcessor.getClass()
|
||||
.getMethod("handleMessage");
|
||||
StreamListener streamListener = AnnotatedElementUtils.findMergedAnnotation(method,
|
||||
StreamListener.class);
|
||||
// verify that the invocation happened on the custom Orchestrator
|
||||
verify(this.customOrchestrator).orchestrateStreamListenerSetupMethod(
|
||||
streamListener, method, this.multipleStreamListenerProcessor);
|
||||
|
||||
Method method1 = this.multipleStreamListenerProcessor.getClass()
|
||||
.getMethod("produceString");
|
||||
StreamListener streamListener1 = AnnotatedElementUtils
|
||||
.findMergedAnnotation(method, StreamListener.class);
|
||||
|
||||
// Verify that the invocation did not happen on the custom orchestrator
|
||||
verify(this.customOrchestrator, never()).orchestrateStreamListenerSetupMethod(
|
||||
streamListener1, method1, this.multipleStreamListenerProcessor);
|
||||
|
||||
Field field = ReflectionUtils.findField(
|
||||
this.streamListenerAnnotationBeanPostProcessor.getClass(),
|
||||
"streamListenerSetupMethodOrchestrators");
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
|
||||
Set<StreamListenerSetupMethodOrchestrator> field1;
|
||||
field1 = (LinkedHashSet<StreamListenerSetupMethodOrchestrator>) ReflectionUtils
|
||||
.getField(field, this.streamListenerAnnotationBeanPostProcessor);
|
||||
List<StreamListenerSetupMethodOrchestrator> list = new ArrayList<>(field1);
|
||||
|
||||
// Ensure that the custom orchestrator did not support this request
|
||||
assertThat(list.get(0).supports(method1)).isEqualTo(false);
|
||||
// Ensure that we are using the default Orchestrator in
|
||||
// StreamListenerAnnoatationBeanPostProcessor
|
||||
assertThat(list.get(1).supports(method1)).isEqualTo(true);
|
||||
}
|
||||
|
||||
public interface SomeProcessor {
|
||||
|
||||
@Input(Sink.INPUT)
|
||||
SubscribableChannel channel1();
|
||||
|
||||
@Input("foobar")
|
||||
SubscribableChannel channel2();
|
||||
|
||||
@Output(Source.OUTPUT)
|
||||
MessageChannel channel3();
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(SomeProcessor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class MultipleStreamListenerProcessor {
|
||||
|
||||
@StreamListener(Sink.INPUT)
|
||||
public void handleMessage() {
|
||||
}
|
||||
|
||||
@StreamListener("foobar")
|
||||
@SendTo("output")
|
||||
public String produceString() {
|
||||
return "foobar";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CustomOrchestrator myOrchestrator() {
|
||||
return new CustomOrchestrator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class CustomOrchestrator implements StreamListenerSetupMethodOrchestrator {
|
||||
|
||||
@Override
|
||||
public boolean supports(Method method) {
|
||||
return method.getReturnType() != String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void orchestrateStreamListenerSetupMethod(StreamListener streamListener,
|
||||
Method method, Object bean) {
|
||||
// stub method
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class StreamListenerMethodWithReturnMessageTests {
|
||||
|
||||
private Class<?> configClass;
|
||||
|
||||
public StreamListenerMethodWithReturnMessageTests(Class<?> configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<?> InputConfigs() {
|
||||
return Arrays.asList(new Class[] { TestPojoWithMessageReturn1.class,
|
||||
TestPojoWithMessageReturn2.class });
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReturnMessage() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input()
|
||||
.send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
TestPojoWithMessageReturn testPojoWithMessageReturn = context
|
||||
.getBean(TestPojoWithMessageReturn.class);
|
||||
Assertions.assertThat(testPojoWithMessageReturn.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(testPojoWithMessageReturn.receivedPojos.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload()).contains("barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithMessageReturn1 extends TestPojoWithMessageReturn {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public Message<?> receive(StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedPojos.add(fooPojo);
|
||||
StreamListenerTestUtils.BarPojo barPojo = new StreamListenerTestUtils.BarPojo();
|
||||
barPojo.setBar(fooPojo.getFoo());
|
||||
return MessageBuilder.withPayload(barPojo).setHeader("foo", "bar").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithMessageReturn2 extends TestPojoWithMessageReturn {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@Output(Processor.OUTPUT)
|
||||
public Message<?> receive(StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedPojos.add(fooPojo);
|
||||
StreamListenerTestUtils.BarPojo bazPojo = new StreamListenerTestUtils.BarPojo();
|
||||
bazPojo.setBar(fooPojo.getFoo());
|
||||
return MessageBuilder.withPayload(bazPojo).setHeader("foo", "bar").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestPojoWithMessageReturn {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedPojos = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class StreamListenerMethodWithReturnValueTests {
|
||||
|
||||
private Class<?> configClass;
|
||||
|
||||
public StreamListenerMethodWithReturnValueTests(Class<?> configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<?> InputConfigs() {
|
||||
return Arrays.asList(
|
||||
new Class[] { TestStringProcessor1.class, TestStringProcessor2.class });
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReturn() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input()
|
||||
.send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
TestStringProcessor testStringProcessor = context
|
||||
.getBean(TestStringProcessor.class);
|
||||
Assertions.assertThat(testStringProcessor.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(testStringProcessor.receivedPojos.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload()).contains("barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestStringProcessor1 extends TestStringProcessor {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public String receive(StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedPojos.add(fooPojo);
|
||||
return fooPojo.getFoo();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestStringProcessor2 extends TestStringProcessor {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@Output(Processor.OUTPUT)
|
||||
public String receive(StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedPojos.add(fooPojo);
|
||||
return fooPojo.getFoo();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestStringProcessor {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedPojos = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-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.config;
|
||||
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
|
||||
/**
|
||||
* @author Ilayaperumal Gopinathan
|
||||
*/
|
||||
public class StreamListenerTestUtils {
|
||||
|
||||
public interface FooInboundChannel1 {
|
||||
|
||||
String INPUT = "foo1-input";
|
||||
|
||||
@Input(FooInboundChannel1.INPUT)
|
||||
SubscribableChannel input();
|
||||
|
||||
}
|
||||
|
||||
public interface FooOutboundChannel1 {
|
||||
|
||||
String OUTPUT = "foo1-output";
|
||||
|
||||
@Output(FooOutboundChannel1.OUTPUT)
|
||||
MessageChannel output();
|
||||
|
||||
}
|
||||
|
||||
public static class FooPojo {
|
||||
|
||||
private String foo;
|
||||
|
||||
public String getFoo() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
public void setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("FooPojo{");
|
||||
sb.append("foo='").append(this.foo).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class BarPojo {
|
||||
|
||||
private String bar;
|
||||
|
||||
public String getBar() {
|
||||
return this.bar;
|
||||
}
|
||||
|
||||
public void setBar(String bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("BarPojo{");
|
||||
sb.append("bar='").append(this.bar).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class PojoWithValidation {
|
||||
|
||||
private String foo;
|
||||
|
||||
public String getFoo() {
|
||||
return this.foo;
|
||||
}
|
||||
|
||||
public void setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerErrorMessages;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.springframework.cloud.stream.binding.StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class StreamListenerWithAnnotatedInputOutputArgsTests {
|
||||
|
||||
@Test
|
||||
public void testInputOutputArgs() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestInputOutputArgs.class, "--server.port=0",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain",
|
||||
"--spring.jmx.enabled=false");
|
||||
sendMessageAndValidate(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInputOutputArgsWithMoreParameters() {
|
||||
try {
|
||||
SpringApplication.run(TestInputOutputArgsWithMoreParameters.class,
|
||||
"--server.port=0");
|
||||
fail("Expected exception: " + INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInputOutputArgsWithInvalidBindableTarget() {
|
||||
try {
|
||||
SpringApplication.run(TestInputOutputArgsWithInvalidBindableTarget.class,
|
||||
"--server.port=0", "--spring.jmx.enabled=false");
|
||||
fail("Exception expected on using invalid bindable target as method parameter");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(
|
||||
StreamListenerErrorMessages.INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInputOutputArgsWithParameterOrderChanged() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestInputOutputArgsWithParameterOrderChanged.class, "--server.port=0",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain",
|
||||
"--spring.jmx.enabled=false");
|
||||
sendMessageAndValidate(context);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void sendMessageAndValidate(ConfigurableApplicationContext context)
|
||||
throws InterruptedException {
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
processor.input().send(MessageBuilder.withPayload("hello")
|
||||
.setHeader("contentType", "text/plain").build());
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<String> result = (Message<String>) messageCollector
|
||||
.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo("HELLO");
|
||||
context.close();
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInputOutputArgs {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
|
||||
@Output(Processor.OUTPUT) final MessageChannel output) {
|
||||
input.subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
output.send(MessageBuilder
|
||||
.withPayload(message.getPayload().toString().toUpperCase())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInputOutputArgsWithMoreParameters {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input(Processor.INPUT) SubscribableChannel input,
|
||||
@Output(Processor.OUTPUT) final MessageChannel output, String someArg) {
|
||||
input.subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
output.send(MessageBuilder
|
||||
.withPayload(message.getPayload().toString().toUpperCase())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInputOutputArgsWithInvalidBindableTarget {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Input("invalid") SubscribableChannel input,
|
||||
@Output(Processor.OUTPUT) final MessageChannel output) {
|
||||
input.subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
output.send(MessageBuilder
|
||||
.withPayload(message.getPayload().toString().toUpperCase())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestInputOutputArgsWithParameterOrderChanged {
|
||||
|
||||
@StreamListener
|
||||
public void receive(@Output(Processor.OUTPUT) final MessageChannel output,
|
||||
@Input("input") SubscribableChannel input) {
|
||||
input.subscribe(new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
output.send(MessageBuilder
|
||||
.withPayload(message.getPayload().toString().toUpperCase())
|
||||
.build());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binding.StreamListenerErrorMessages;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class StreamListenerWithConditionsTest {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testAnnotatedArgumentsWithConditionalClass() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(TestPojoWithAnnotatedArguments.class, "--server.port=0");
|
||||
|
||||
TestPojoWithAnnotatedArguments testPojoWithAnnotatedArguments = context
|
||||
.getBean(TestPojoWithAnnotatedArguments.class);
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
sink.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json")
|
||||
.setHeader("testHeader", "testValue").setHeader("type", "foo").build());
|
||||
sink.input().send(MessageBuilder.withPayload("{\"bar\":\"foofoo" + id + "\"}")
|
||||
.setHeader("contentType", "application/json")
|
||||
.setHeader("testHeader", "testValue").setHeader("type", "bar").build());
|
||||
sink.input().send(MessageBuilder.withPayload("{\"bar\":\"foofoo" + id + "\"}")
|
||||
.setHeader("contentType", "application/json")
|
||||
.setHeader("testHeader", "testValue").setHeader("type", "qux").build());
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedFoo).hasSize(1);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedFoo.get(0))
|
||||
.hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedBar).hasSize(1);
|
||||
assertThat(testPojoWithAnnotatedArguments.receivedBar.get(0))
|
||||
.hasFieldOrPropertyWithValue("bar", "foofoo" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConditionalFailsWithReturnValue() throws Exception {
|
||||
try {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestConditionalOnMethodWithReturnValueFails.class, "--server.port=0");
|
||||
context.close();
|
||||
fail("Context creation failure expected");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(
|
||||
StreamListenerErrorMessages.CONDITION_ON_METHOD_RETURNING_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConditionalFailsWithDeclarativeMethod() throws Exception {
|
||||
try {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(
|
||||
TestConditionalOnDeclarativeMethodFails.class, "--server.port=0");
|
||||
context.close();
|
||||
fail("Context creation failure expected");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertThat(e.getMessage()).contains(
|
||||
StreamListenerErrorMessages.CONDITION_ON_DECLARATIVE_METHOD);
|
||||
}
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestPojoWithAnnotatedArguments {
|
||||
|
||||
List<StreamListenerTestUtils.FooPojo> receivedFoo = new ArrayList<>();
|
||||
|
||||
List<StreamListenerTestUtils.BarPojo> receivedBar = new ArrayList<>();
|
||||
|
||||
@StreamListener(value = Sink.INPUT, condition = "headers['type']=='foo'")
|
||||
public void receive(@Payload StreamListenerTestUtils.FooPojo fooPojo) {
|
||||
this.receivedFoo.add(fooPojo);
|
||||
}
|
||||
|
||||
@StreamListener(target = Sink.INPUT, condition = "headers['type']=='bar'")
|
||||
public void receive(@Payload StreamListenerTestUtils.BarPojo barPojo) {
|
||||
this.receivedBar.add(barPojo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestConditionalOnDeclarativeMethodFails {
|
||||
|
||||
@StreamListener(condition = "headers['type']=='foo'")
|
||||
public void receive(@Input("input") MessageChannel input) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class TestConditionalOnMethodWithReturnValueFails {
|
||||
|
||||
@StreamListener(value = Sink.INPUT, condition = "headers['type']=='foo'")
|
||||
public String receive(String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.binder.BinderFactory;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.TestSupportBinder;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Vinicius Carvalho
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 1.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
// @checkstyle:off
|
||||
@SpringBootTest(classes = TextPlainToJsonConversionTest.FooProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
// @checkstyle:on
|
||||
public class TextPlainToJsonConversionTest {
|
||||
|
||||
@Autowired
|
||||
private Processor testProcessor;
|
||||
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testNoContentTypeToJsonConversionOnInput() throws Exception {
|
||||
this.testProcessor.input()
|
||||
.send(MessageBuilder.withPayload("{\"name\":\"Bar\"}").build());
|
||||
Message<String> received = (Message<String>) ((TestSupportBinder) this.binderFactory
|
||||
.getBinder(null, MessageChannel.class)).messageCollector()
|
||||
.forChannel(this.testProcessor.output())
|
||||
.poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
Foo foo = this.mapper.readValue(received.getPayload(), Foo.class);
|
||||
assertThat(foo.getName()).isEqualTo("transformed-Bar");
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0: Conversion from text/plain -> json is no longer supported. Strict
|
||||
* contentType only.
|
||||
*/
|
||||
@Test(expected = MessagingException.class)
|
||||
public void testTextPlainToJsonConversionOnInput() {
|
||||
this.testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}")
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build());
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class FooProcessor {
|
||||
|
||||
@StreamListener("input")
|
||||
@SendTo("output")
|
||||
public Foo consume(Foo foo) {
|
||||
Foo returnFoo = new Foo();
|
||||
returnFoo.setName("transformed-" + foo.getName());
|
||||
return returnFoo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Foo {
|
||||
|
||||
private String name;
|
||||
|
||||
public Foo() {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Foo{name='" + this.name + "'}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
///*
|
||||
// * Copyright 2017-2018 the original author or authors.
|
||||
// *
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * 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.config;
|
||||
//
|
||||
//import java.util.concurrent.TimeUnit;
|
||||
//
|
||||
//import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
//import org.junit.Test;
|
||||
//import org.junit.runner.RunWith;
|
||||
//
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
//import org.springframework.boot.test.context.SpringBootTest;
|
||||
//import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
//import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
//import org.springframework.cloud.stream.binder.BinderFactory;
|
||||
//import org.springframework.cloud.stream.messaging.Processor;
|
||||
//import org.springframework.cloud.stream.test.binder.TestSupportBinder;
|
||||
//import org.springframework.integration.support.MessageBuilder;
|
||||
//import org.springframework.messaging.Message;
|
||||
//import org.springframework.messaging.MessageChannel;
|
||||
//import org.springframework.messaging.MessageHeaders;
|
||||
//import org.springframework.messaging.MessagingException;
|
||||
//import org.springframework.messaging.handler.annotation.SendTo;
|
||||
//import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
//
|
||||
//import static org.assertj.core.api.Assertions.assertThat;
|
||||
//
|
||||
///**
|
||||
// * @author Marius Bogoevici
|
||||
// * @author Vinicius Carvalho
|
||||
// * @author Oleg Zhurakousky
|
||||
// * @since 1.2
|
||||
// */
|
||||
//@RunWith(SpringJUnit4ClassRunner.class)
|
||||
//// @checkstyle:off
|
||||
//@SpringBootTest(classes = TextPlainToJsonConversionTest.FooProcessor.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
//// @checkstyle:on
|
||||
//public class TextPlainToJsonConversionTest {
|
||||
//
|
||||
// @Autowired
|
||||
// private Processor testProcessor;
|
||||
//
|
||||
// @Autowired
|
||||
// private BinderFactory binderFactory;
|
||||
//
|
||||
// private ObjectMapper mapper = new ObjectMapper();
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// @Test
|
||||
// public void testNoContentTypeToJsonConversionOnInput() throws Exception {
|
||||
// this.testProcessor.input()
|
||||
// .send(MessageBuilder.withPayload("{\"name\":\"Bar\"}").build());
|
||||
// Message<String> received = (Message<String>) ((TestSupportBinder) this.binderFactory
|
||||
// .getBinder(null, MessageChannel.class)).messageCollector()
|
||||
// .forChannel(this.testProcessor.output())
|
||||
// .poll(1, TimeUnit.SECONDS);
|
||||
// assertThat(received).isNotNull();
|
||||
// Foo foo = this.mapper.readValue(received.getPayload(), Foo.class);
|
||||
// assertThat(foo.getName()).isEqualTo("transformed-Bar");
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @since 2.0: Conversion from text/plain -> json is no longer supported. Strict
|
||||
// * contentType only.
|
||||
// */
|
||||
// @Test(expected = MessagingException.class)
|
||||
// public void testTextPlainToJsonConversionOnInput() {
|
||||
// this.testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}")
|
||||
// .setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build());
|
||||
// }
|
||||
//
|
||||
// @EnableBinding(Processor.class)
|
||||
// @EnableAutoConfiguration
|
||||
// public static class FooProcessor {
|
||||
//
|
||||
// @StreamListener("input")
|
||||
// @SendTo("output")
|
||||
// public Foo consume(Foo foo) {
|
||||
// Foo returnFoo = new Foo();
|
||||
// returnFoo.setName("transformed-" + foo.getName());
|
||||
// return returnFoo;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public static class Foo {
|
||||
//
|
||||
// private String name;
|
||||
//
|
||||
// public Foo() {
|
||||
// }
|
||||
//
|
||||
// public String getName() {
|
||||
// return this.name;
|
||||
// }
|
||||
//
|
||||
// public void setName(String name) {
|
||||
// this.name = name;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String toString() {
|
||||
// return "Foo{name='" + this.name + "'}";
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -1,272 +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.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.stream.config.contentType;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Source;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.handler.annotation.Headers;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Vinicius Carvalho
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ContentTypeTests {
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
public void testSendWithDefaultContentType() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
User user = new User("Alice");
|
||||
source.output().send(MessageBuilder.withPayload(user).build());
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
User received = this.mapper.readValue(message.getPayload(), User.class);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendJsonAsString() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
User user = new User("Alice");
|
||||
String json = this.mapper.writeValueAsString(user);
|
||||
source.output().send(MessageBuilder.withPayload(user).build());
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
assertThat(json).isEqualTo(message.getPayload());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendJsonString() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
source.output().send(MessageBuilder.withPayload("foo").build());
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
assertThat("foo").isEqualTo(message.getPayload());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBynaryData() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
source.output()
|
||||
.send(MessageBuilder.withPayload(data)
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE,
|
||||
MimeTypeUtils.APPLICATION_OCTET_STREAM)
|
||||
.build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_OCTET_STREAM));
|
||||
assertThat(message.getPayload()).isEqualTo(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBinaryDataWithContentType() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.output.contentType=image/jpeg")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
source.output().send(MessageBuilder.withPayload(data).build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message.getPayload()).isEqualTo(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBinaryDataWithContentTypeUsingHeaders() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
source.output().send(MessageBuilder.withPayload(data)
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_JPEG)
|
||||
.build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.IMAGE_JPEG));
|
||||
assertThat(message.getPayload()).isEqualTo(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendStringType() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
User user = new User("Alice");
|
||||
source.output().send(MessageBuilder.withPayload(user).build());
|
||||
Message<String> message = (Message<String>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.TEXT_PLAIN));
|
||||
assertThat(message.getPayload()).isEqualTo(user.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveWithDefaults() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SinkApplication.class, "--server.port=0", "--spring.jmx.enabled=false")) {
|
||||
TestSink testSink = context.getBean(TestSink.class);
|
||||
SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
User user = new User("Alice");
|
||||
testSink.pojo().send(MessageBuilder
|
||||
.withPayload(this.mapper.writeValueAsBytes(user)).build());
|
||||
Map<String, Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
User received = (User) sourceApp.arguments.pop();
|
||||
assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveRawWithDifferentContentTypes() {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SinkApplication.class, "--server.port=0", "--spring.jmx.enabled=false")) {
|
||||
TestSink testSink = context.getBean(TestSink.class);
|
||||
SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
testSink.raw().send(MessageBuilder.withPayload(new byte[4])
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_JPEG)
|
||||
.build());
|
||||
testSink.raw().send(MessageBuilder.withPayload(new byte[4])
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_GIF)
|
||||
.build());
|
||||
Map<String, Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
sourceApp.arguments.pop();
|
||||
assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MimeTypeUtils.IMAGE_GIF));
|
||||
headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
sourceApp.arguments.pop();
|
||||
assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MimeTypeUtils.IMAGE_JPEG));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface TestSink {
|
||||
|
||||
@Input("POJO_INPUT")
|
||||
SubscribableChannel pojo();
|
||||
|
||||
@Input("STRING_INPUT")
|
||||
SubscribableChannel string();
|
||||
|
||||
@Input("TUPLE_INPUT")
|
||||
SubscribableChannel tuple();
|
||||
|
||||
@Input("RAW_INPUT")
|
||||
SubscribableChannel raw();
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Source.class)
|
||||
@SpringBootApplication
|
||||
public static class SourceApplication {
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(TestSink.class)
|
||||
@SpringBootApplication
|
||||
public static class SinkApplication {
|
||||
|
||||
public LinkedList<? super Object> arguments = new LinkedList<>();
|
||||
|
||||
@StreamListener("POJO_INPUT")
|
||||
public void receive(User user, @Headers Map<String, Object> headers) {
|
||||
this.arguments.push(user);
|
||||
this.arguments.push(headers);
|
||||
}
|
||||
|
||||
@StreamListener("STRING_INPUT")
|
||||
public void receive(String string) {
|
||||
}
|
||||
|
||||
@StreamListener("RAW_INPUT")
|
||||
public void receive(byte[] data, @Headers Map<String, Object> headers) {
|
||||
this.arguments.push(data);
|
||||
this.arguments.push(headers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
///*
|
||||
// * 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.
|
||||
// */
|
||||
//
|
||||
//package org.springframework.cloud.stream.config.contentType;
|
||||
//
|
||||
//import java.util.LinkedList;
|
||||
//import java.util.Map;
|
||||
//import java.util.concurrent.TimeUnit;
|
||||
//
|
||||
//import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
//import org.junit.Test;
|
||||
//
|
||||
//import org.springframework.boot.SpringApplication;
|
||||
//import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
//import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
//import org.springframework.cloud.stream.annotation.Input;
|
||||
//import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
//import org.springframework.cloud.stream.messaging.Source;
|
||||
//import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
//import org.springframework.context.ConfigurableApplicationContext;
|
||||
//import org.springframework.integration.support.MessageBuilder;
|
||||
//import org.springframework.messaging.Message;
|
||||
//import org.springframework.messaging.MessageHeaders;
|
||||
//import org.springframework.messaging.SubscribableChannel;
|
||||
//import org.springframework.messaging.handler.annotation.Headers;
|
||||
//import org.springframework.util.MimeType;
|
||||
//import org.springframework.util.MimeTypeUtils;
|
||||
//
|
||||
//import static org.assertj.core.api.Assertions.assertThat;
|
||||
//
|
||||
///**
|
||||
// * @author Vinicius Carvalho
|
||||
// * @author Oleg Zhurakousky
|
||||
// */
|
||||
//@SuppressWarnings("unchecked")
|
||||
//public class ContentTypeTests {
|
||||
//
|
||||
// private ObjectMapper mapper = new ObjectMapper();
|
||||
//
|
||||
// @Test
|
||||
// public void testSendWithDefaultContentType() throws Exception {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SourceApplication.class, "--server.port=0",
|
||||
// "--spring.jmx.enabled=false")) {
|
||||
//
|
||||
// MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
// Source source = context.getBean(Source.class);
|
||||
// User user = new User("Alice");
|
||||
// source.output().send(MessageBuilder.withPayload(user).build());
|
||||
// Message<String> message = (Message<String>) collector
|
||||
// .forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
// User received = this.mapper.readValue(message.getPayload(), User.class);
|
||||
// assertThat(
|
||||
// message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
// .includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
// assertThat(user.getName()).isEqualTo(received.getName());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendJsonAsString() throws Exception {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SourceApplication.class, "--server.port=0",
|
||||
// "--spring.jmx.enabled=false")) {
|
||||
// MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
// Source source = context.getBean(Source.class);
|
||||
// User user = new User("Alice");
|
||||
// String json = this.mapper.writeValueAsString(user);
|
||||
// source.output().send(MessageBuilder.withPayload(user).build());
|
||||
// Message<String> message = (Message<String>) collector
|
||||
// .forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
// assertThat(
|
||||
// message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
// .includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
// assertThat(json).isEqualTo(message.getPayload());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendJsonString() throws Exception {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SourceApplication.class, "--server.port=0",
|
||||
// "--spring.jmx.enabled=false")) {
|
||||
// MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
// Source source = context.getBean(Source.class);
|
||||
// source.output().send(MessageBuilder.withPayload("foo").build());
|
||||
// Message<String> message = (Message<String>) collector
|
||||
// .forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
// assertThat(
|
||||
// message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
// .includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
// assertThat("foo").isEqualTo(message.getPayload());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendBynaryData() throws Exception {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SourceApplication.class, "--server.port=0",
|
||||
// "--spring.jmx.enabled=false")) {
|
||||
//
|
||||
// MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
// Source source = context.getBean(Source.class);
|
||||
// byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
// source.output()
|
||||
// .send(MessageBuilder.withPayload(data)
|
||||
// .setHeader(MessageHeaders.CONTENT_TYPE,
|
||||
// MimeTypeUtils.APPLICATION_OCTET_STREAM)
|
||||
// .build());
|
||||
// Message<byte[]> message = (Message<byte[]>) collector
|
||||
// .forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
// assertThat(
|
||||
// message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
// .includes(MimeTypeUtils.APPLICATION_OCTET_STREAM));
|
||||
// assertThat(message.getPayload()).isEqualTo(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendBinaryDataWithContentType() throws Exception {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false",
|
||||
// "--spring.cloud.stream.bindings.output.contentType=image/jpeg")) {
|
||||
// MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
// Source source = context.getBean(Source.class);
|
||||
// byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
// source.output().send(MessageBuilder.withPayload(data).build());
|
||||
// Message<byte[]> message = (Message<byte[]>) collector
|
||||
// .forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
// assertThat(message.getPayload()).isEqualTo(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendBinaryDataWithContentTypeUsingHeaders() throws Exception {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SourceApplication.class, "--server.port=0",
|
||||
// "--spring.jmx.enabled=false")) {
|
||||
// MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
// Source source = context.getBean(Source.class);
|
||||
// byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
// source.output().send(MessageBuilder.withPayload(data)
|
||||
// .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_JPEG)
|
||||
// .build());
|
||||
// Message<byte[]> message = (Message<byte[]>) collector
|
||||
// .forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
// assertThat(
|
||||
// message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
// .includes(MimeTypeUtils.IMAGE_JPEG));
|
||||
// assertThat(message.getPayload()).isEqualTo(data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testSendStringType() throws Exception {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SourceApplication.class, "--server.port=0", "--spring.jmx.enabled=false",
|
||||
// "--spring.cloud.stream.bindings.output.contentType=text/plain")) {
|
||||
// MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
// Source source = context.getBean(Source.class);
|
||||
// User user = new User("Alice");
|
||||
// source.output().send(MessageBuilder.withPayload(user).build());
|
||||
// Message<String> message = (Message<String>) collector
|
||||
// .forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
// assertThat(
|
||||
// message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
// .includes(MimeTypeUtils.TEXT_PLAIN));
|
||||
// assertThat(message.getPayload()).isEqualTo(user.toString());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testReceiveWithDefaults() throws Exception {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SinkApplication.class, "--server.port=0", "--spring.jmx.enabled=false")) {
|
||||
// TestSink testSink = context.getBean(TestSink.class);
|
||||
// SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
// User user = new User("Alice");
|
||||
// testSink.pojo().send(MessageBuilder
|
||||
// .withPayload(this.mapper.writeValueAsBytes(user)).build());
|
||||
// Map<String, Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
// User received = (User) sourceApp.arguments.pop();
|
||||
// assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
// .includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
// assertThat(user.getName()).isEqualTo(received.getName());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testReceiveRawWithDifferentContentTypes() {
|
||||
// try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
// SinkApplication.class, "--server.port=0", "--spring.jmx.enabled=false")) {
|
||||
// TestSink testSink = context.getBean(TestSink.class);
|
||||
// SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
// testSink.raw().send(MessageBuilder.withPayload(new byte[4])
|
||||
// .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_JPEG)
|
||||
// .build());
|
||||
// testSink.raw().send(MessageBuilder.withPayload(new byte[4])
|
||||
// .setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.IMAGE_GIF)
|
||||
// .build());
|
||||
// Map<String, Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
// sourceApp.arguments.pop();
|
||||
// assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
// .includes(MimeTypeUtils.IMAGE_GIF));
|
||||
// headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
// sourceApp.arguments.pop();
|
||||
// assertThat(((MimeType) headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
// .includes(MimeTypeUtils.IMAGE_JPEG));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public interface TestSink {
|
||||
//
|
||||
// @Input("POJO_INPUT")
|
||||
// SubscribableChannel pojo();
|
||||
//
|
||||
// @Input("STRING_INPUT")
|
||||
// SubscribableChannel string();
|
||||
//
|
||||
// @Input("TUPLE_INPUT")
|
||||
// SubscribableChannel tuple();
|
||||
//
|
||||
// @Input("RAW_INPUT")
|
||||
// SubscribableChannel raw();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @EnableBinding(Source.class)
|
||||
// @SpringBootApplication
|
||||
// public static class SourceApplication {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @EnableBinding(TestSink.class)
|
||||
// @SpringBootApplication
|
||||
// public static class SinkApplication {
|
||||
//
|
||||
// public LinkedList<? super Object> arguments = new LinkedList<>();
|
||||
//
|
||||
// @StreamListener("POJO_INPUT")
|
||||
// public void receive(User user, @Headers Map<String, Object> headers) {
|
||||
// this.arguments.push(user);
|
||||
// this.arguments.push(headers);
|
||||
// }
|
||||
//
|
||||
// @StreamListener("STRING_INPUT")
|
||||
// public void receive(String string) {
|
||||
// }
|
||||
//
|
||||
// @StreamListener("RAW_INPUT")
|
||||
// public void receive(byte[] data, @Headers Map<String, Object> headers) {
|
||||
// this.arguments.push(data);
|
||||
// this.arguments.push(headers);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
Reference in New Issue
Block a user