Migrate to servlet binder for web features

This commit is contained in:
Dave Syer
2017-08-08 08:27:04 +01:00
parent 540b4d378e
commit 1af0d451cf
107 changed files with 4055 additions and 2010 deletions

View File

@@ -0,0 +1,79 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet;
import java.util.Arrays;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Dave Syer
*
*/
public class JsonUtilsTests {
private ObjectMapper mapper = new ObjectMapper();
@Test
public void empty() {
assertThat(JsonUtils.split("[]")).isEmpty();
}
@Test
public void strings() {
assertThat(JsonUtils.split("[\"foo\", \"bar\"]")).hasSize(2).contains("foo",
"bar");
}
@Test
public void objects() throws Exception {
assertThat(JsonUtils.split(
mapper.writeValueAsString(Arrays.asList(new Foo("foo"), new Foo("bar")))))
.hasSize(2)
.contains("{\"value\":\"foo\"}", "{\"value\":\"bar\"}");
}
@Test
public void arrays() throws Exception {
assertThat(JsonUtils.split(mapper.writeValueAsString(
Arrays.asList(Arrays.asList(new Foo("foo"), new Foo("bar")))))).hasSize(1)
.contains("[{\"value\":\"foo\"},{\"value\":\"bar\"}]");
}
protected static class Foo {
private String value;
public Foo() {
}
public Foo(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}

View File

@@ -0,0 +1,101 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.Input;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class DoubleSinkMessageChannelBinderTests implements MessageHandler {
@Autowired
private Sink sink;
@Autowired
private Custom custom;
@Autowired
private MockMvc mockMvc;
private Message<?> message;
@Test
public void string() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(
post("/stream/input").contentType(MediaType.TEXT_PLAIN).content("hello"))
.andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@Test
public void custom() throws Exception {
custom.input().subscribe(this);
mockMvc.perform(
post("/stream/custom").contentType(MediaType.TEXT_PLAIN).content("hello"))
.andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
assertThat(this.message).isNotNull();
custom.input().unsubscribe(this);
}
@SpringBootApplication
@EnableBinding({ Sink.class, Custom.class })
protected static class TestConfiguration {
}
@Override
public void handleMessage(Message<?> message) throws MessagingException {
this.message = message;
}
interface Custom {
@Input("custom")
SubscribableChannel input();
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.messaging.Processor;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class HeaderProcessorMessageChannelBinderTests {
@Autowired
private MockMvc mockMvc;
@Test
public void function() throws Exception {
mockMvc.perform(post("/stream/input").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isOk())
.andExpect(header().string("x-foo", "bar"))
.andExpect(content().string(containsString("HELLO")));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public Message<String> uppercase(Message<String> input) {
return MessageBuilder.withPayload(input.getPayload().toUpperCase())
.copyHeadersIfAbsent(input.getHeaders()).setHeader("x-foo", "bar")
.build();
}
}
}

View File

@@ -0,0 +1,72 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.servlet.MessageController;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.http.MediaType;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class HeadersDroppedRoutedProcessorMessageChannelBinderTests {
@Autowired
private MockMvc mockMvc;
@Test
public void function() throws Exception {
mockMvc.perform(post("/stream/input/words")
.contentType(MediaType.APPLICATION_JSON).content("\"hello\""))
.andExpect(status().isOk())
.andExpect(header().string(MessageController.ROUTE_KEY, "words"))
.andExpect(content().string(containsString("HELLO")));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public String uppercase(String input) {
return input.toUpperCase();
}
}
}

View File

@@ -0,0 +1,116 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.servlet.MessageController;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.http.MediaType;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest("spring.cloud.stream.bindings.input.destination:words")
@AutoConfigureMockMvc
@DirtiesContext
public class NamedProcessorMessageChannelBinderTests {
@Autowired
private MockMvc mockMvc;
@Autowired
private MessageController controller;
@Autowired
private Processor processor;
@Before
public void init() {
controller.reset();
}
@Test
public void function() throws Exception {
mockMvc.perform(post("/stream/words").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void implicit() throws Exception {
mockMvc.perform(post("/stream").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void empty() throws Exception {
mockMvc.perform(get("/stream/output").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(containsString("[]")));
}
@Test
public void output() throws Exception {
processor.input().send(MessageBuilder.withPayload("hello").build());
mockMvc.perform(get("/stream/output").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void outputWithRoute() throws Exception {
processor.input().send(MessageBuilder.withPayload("hello")
.setHeader(MessageController.ROUTE_KEY, "uppercase").build());
mockMvc.perform(
get("/stream/output/uppercase").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public String uppercase(String input) {
return input.toUpperCase();
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class NamedSinkMessageChannelBinderTests implements MessageHandler {
@Autowired
private Sink sink;
@Autowired
private MockMvc mockMvc;
private Message<?> message;
@Test
public void consumer() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(post("/stream/input").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@SpringBootApplication
@EnableBinding(Sink.class)
protected static class TestConfiguration {
}
@Override
public void handleMessage(Message<?> message) throws MessagingException {
this.message = message;
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest("spring.cloud.stream.bindings.output.destination:words")
@AutoConfigureMockMvc
@DirtiesContext
public class NamedSourceMessageChannelBinderTests {
@Autowired
private Source source;
@Autowired
private MockMvc mockMvc;
@Test
public void supplier() throws Exception {
source.output().send(MessageBuilder.withPayload("hello").build());
mockMvc.perform(get("/stream/words")).andExpect(status().isOk())
.andExpect(content().string(containsString("hello")));
}
@SpringBootApplication
@EnableBinding(Source.class)
protected static class TestConfiguration {
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.messaging.Processor;
import org.springframework.http.MediaType;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(properties = "logging.level.org.springframework.web=DEBUG")
@AutoConfigureMockMvc
@DirtiesContext
public class PojoProcessorMessageChannelBinderTests {
@Autowired
private MockMvc mockMvc;
@Test
public void json() throws Exception {
mockMvc.perform(post("/stream").contentType(MediaType.APPLICATION_JSON)
.content("{\"value\":\"hello\"}")).andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void text() throws Exception {
mockMvc.perform(post("/stream").contentType(MediaType.TEXT_PLAIN)
.content("[{\"value\":\"hello\"}]")).andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void single() throws Exception {
mockMvc.perform(post("/stream").contentType(MediaType.TEXT_PLAIN)
.content("{\"value\":\"hello\"}")).andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public Foo uppercase(Foo input) {
return input.toUpperCase();
}
}
protected static class Foo {
private String value;
public Foo() {
}
public Foo(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Foo toUpperCase() {
return new Foo(value.toUpperCase());
}
}
}

View File

@@ -0,0 +1,113 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class PojoSinkMessageChannelBinderTests implements MessageHandler {
@Autowired
private Sink sink;
@Autowired
private MockMvc mockMvc;
private Message<?> message;
@Test
public void consumer() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(post("/stream/input").contentType(MediaType.APPLICATION_JSON)
.content("{\"value\":\"hello\"}")).andExpect(status().isAccepted())
.andExpect(content().string("{\"value\":\"hello\"}"));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@Test
public void multi() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(post("/stream/input").contentType(MediaType.APPLICATION_JSON)
.content("[{\"value\":\"hello\"},{\"value\":\"world\"}]"))
.andExpect(status().isAccepted()).andExpect(content()
.string("[{\"value\":\"hello\"}, {\"value\":\"world\"}]"));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@SpringBootApplication
@EnableBinding(Sink.class)
protected static class TestConfiguration {
}
@Override
public void handleMessage(Message<?> message) throws MessagingException {
this.message = message;
}
protected static class Foo {
private String value;
public Foo() {
}
public Foo(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Foo toUpperCase() {
return new Foo(value.toUpperCase());
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest("spring.cloud.stream.binder.servlet.prefix:awesome")
@AutoConfigureMockMvc
@DirtiesContext
public class PrefixMessageChannelBinderTests implements MessageHandler {
@Autowired
private Sink sink;
@Autowired
private MockMvc mockMvc;
private Message<?> message;
@Test
public void consumer() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(post("/awesome/input").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@SpringBootApplication
@EnableBinding(Sink.class)
protected static class TestConfiguration {
}
@Override
public void handleMessage(Message<?> message) throws MessagingException {
this.message = message;
}
}

View File

@@ -0,0 +1,138 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.messaging.Processor;
import org.springframework.http.MediaType;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class ProcessorMessageChannelBinderTests {
@Autowired
private Processor processor;
@Autowired
private MockMvc mockMvc;
@Before
public void init() throws Exception {
mockMvc.perform(get("/stream/output?purge=true")).andReturn();
}
@Test
public void supplier() throws Exception {
processor.output().send(MessageBuilder.withPayload("hello").build());
mockMvc.perform(get("/stream/output")).andExpect(status().isOk())
.andExpect(content().string(containsString("hello")));
}
@Test
public void missing() throws Exception {
// Missing route is not found if channel is explicit
mockMvc.perform(get("/stream/output/missing")).andExpect(status().isNotFound())
.andExpect(content().string(equalTo("")));
}
@Test
public void empty() throws Exception {
// Missing route where channel can be inferred (there is an input channel) is
// going to be passed on as a body
mockMvc.perform(get("/stream/missing")).andExpect(status().isOk())
.andExpect(content().string(equalTo("MISSING")));
}
@Test
public void function() throws Exception {
mockMvc.perform(post("/stream/input").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void keyed() throws Exception {
mockMvc.perform(get("/stream/hello")).andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void implicit() throws Exception {
mockMvc.perform(post("/stream").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void string() throws Exception {
mockMvc.perform(
post("/stream/input").contentType(MediaType.TEXT_PLAIN).content("hello"))
.andExpect(status().isOk()).andExpect(content().string(equalTo("HELLO")));
}
@Test
public void multi() throws Exception {
mockMvc.perform(post("/stream/input").contentType(MediaType.APPLICATION_JSON)
.content("[\"hello\",\"world\"]")).andExpect(status().isOk())
.andExpect(content().string("[\"HELLO\",\"WORLD\"]"));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public String uppercase(String input) {
return input.toUpperCase();
}
public static void main(String[] args) throws Exception {
SpringApplication.run(
ProcessorMessageChannelBinderTests.TestConfiguration.class,
"--logging.level.root=INFO");
}
}
}

View File

@@ -0,0 +1,99 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.servlet.MessageController;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class RoutedProcessorMessageChannelBinderTests {
@Autowired
private MockMvc mockMvc;
@Test
public void function() throws Exception {
mockMvc.perform(post("/stream/input/words")
.contentType(MediaType.APPLICATION_JSON).content("\"hello\""))
.andExpect(status().isOk())
.andExpect(header().string(MessageController.ROUTE_KEY, "words"))
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void keyed() throws Exception {
mockMvc.perform(get("/stream/words/hello")).andExpect(status().isOk())
.andExpect(header().string(MessageController.ROUTE_KEY, "words"))
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void channelAndKeyed() throws Exception {
mockMvc.perform(get("/stream/input/words/hello")).andExpect(status().isOk())
.andExpect(header().string(MessageController.ROUTE_KEY, "words"))
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void implicit() throws Exception {
mockMvc.perform(post("/stream/words").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isOk())
.andExpect(header().string(MessageController.ROUTE_KEY, "words"))
.andExpect(content().string(containsString("HELLO")));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public Message<String> uppercase(Message<String> input) {
return MessageBuilder.withPayload(input.getPayload().toUpperCase())
.copyHeadersIfAbsent(input.getHeaders()).build();
}
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.binder.servlet.MessageController;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class RoutedSinkMessageChannelBinderTests implements MessageHandler {
@Autowired
private Sink sink;
@Autowired
private MockMvc mockMvc;
private Message<?> message;
@Test
public void consumer() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(post("/stream/input/words")
.contentType(MediaType.APPLICATION_JSON).content("\"hello\""))
.andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
assertThat(this.message).isNotNull();
assertThat(this.message.getHeaders().get(MessageController.ROUTE_KEY))
.isEqualTo("words");
sink.input().unsubscribe(this);
}
@SpringBootApplication
@EnableBinding(Sink.class)
protected static class TestConfiguration {
}
@Override
public void handleMessage(Message<?> message) throws MessagingException {
this.message = message;
}
}

View File

@@ -0,0 +1,75 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.binder.servlet.MessageController;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class RoutedSourceMessageChannelBinderTests {
@Autowired
private Source source;
@Autowired
private MockMvc mockMvc;
@Test
public void supplier() throws Exception {
source.output().send(MessageBuilder.withPayload("hello")
.setHeader(MessageController.ROUTE_KEY, "words").build());
mockMvc.perform(get("/stream/output/words")).andExpect(status().isOk())
.andExpect(content().string(containsString("hello")));
}
@Test
public void implicit() throws Exception {
source.output().send(MessageBuilder.withPayload("hello")
.setHeader(MessageController.ROUTE_KEY, "words").build());
mockMvc.perform(get("/stream/words")).andExpect(status().isOk())
.andExpect(content().string(containsString("hello")));
}
@SpringBootApplication
@EnableBinding(Source.class)
protected static class TestConfiguration {
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.messaging.Processor;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class SinkAndProcessorMessageChannelBinderTests {
protected static Log log = LogFactory
.getLog(SinkAndProcessorMessageChannelBinderTests.class);
@Autowired
private MockMvc mockMvc;
@Test
public void function() throws Exception {
mockMvc.perform(get("/stream/output?purge=true")).andReturn();
mockMvc.perform(post("/stream/input/words")
.contentType(MediaType.APPLICATION_JSON).content("\"hello\""))
.andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void consumer() throws Exception {
mockMvc.perform(get("/stream/output?purge=true")).andReturn();
mockMvc.perform(post("/stream/input/accept")
.contentType(MediaType.APPLICATION_JSON).content("\"hello\""))
.andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@Autowired
private Processor processor;
@StreamListener(value = Processor.INPUT, condition = "headers['stream_routekey']=='words'")
public void uppercase(Message<String> input) {
processor.output()
.send(MessageBuilder.withPayload(input.getPayload().toUpperCase())
.copyHeaders(input.getHeaders()).build());
}
@StreamListener(value = Processor.INPUT, condition = "headers['stream_routekey']=='accept'")
public void accept(String input) {
log.warn("Processed: " + input);
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class SinkMessageChannelBinderTests implements MessageHandler {
@Autowired
private Sink sink;
@Autowired
private MockMvc mockMvc;
private Message<?> message;
@Test
public void consumer() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(post("/stream/input").contentType(MediaType.APPLICATION_JSON)
.content("\"hello\"")).andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@Test
public void multi() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(post("/stream/input").contentType(MediaType.APPLICATION_JSON)
.content("[\"hello\",\"world\"]")).andExpect(status().isAccepted())
.andExpect(content().string(containsString("[\"hello\",\"world\"]")));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@Test
public void string() throws Exception {
sink.input().subscribe(this);
mockMvc.perform(
post("/stream/input").contentType(MediaType.TEXT_PLAIN).content("hello"))
.andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@Test
public void missing() throws Exception {
sink.input().subscribe(this);
// It gets routed to "input" channel with key "missing"
mockMvc.perform(post("/stream/missing").contentType(MediaType.TEXT_PLAIN)
.content("hello")).andExpect(status().isAccepted())
.andExpect(content().string(containsString("hello")));
assertThat(this.message).isNotNull();
sink.input().unsubscribe(this);
}
@SpringBootApplication
@EnableBinding(Sink.class)
protected static class TestConfiguration {
}
@Override
public void handleMessage(Message<?> message) throws MessagingException {
this.message = message;
}
}

View File

@@ -0,0 +1,77 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.messaging.Processor;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class SinkWithResponseMessageChannelBinderTests {
@Autowired
private MockMvc mockMvc;
@Test
public void function() throws Exception {
mockMvc.perform(post("/stream/input/words")
.contentType(MediaType.APPLICATION_JSON).content("\"hello\""))
.andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@Autowired
private Processor processor;
@StreamListener(value = Processor.INPUT, condition = "headers['stream_routekey']=='words'")
public void uppercase(Message<String> input) {
// TODO: this won't work without the Message<?> wrapper for the input because
// the headers don't get copied.
processor.output()
.send(MessageBuilder.withPayload(input.getPayload().toUpperCase())
.copyHeaders(input.getHeaders()).build());
}
}
}

View File

@@ -0,0 +1,107 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import java.util.Collections;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.servlet.RouteRegistry;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class SourceAndProcessorMessageChannelBinderTests {
protected static Log log = LogFactory
.getLog(SourceAndProcessorMessageChannelBinderTests.class);
@Autowired
private MockMvc mockMvc;
@Test
public void function() throws Exception {
mockMvc.perform(get("/stream/output?purge=true")).andReturn();
mockMvc.perform(post("/stream/input/words")
.contentType(MediaType.APPLICATION_JSON).content("\"hello\""))
.andExpect(status().isOk())
.andExpect(content().string(containsString("HELLO")));
}
@Test
public void missing() throws Exception {
mockMvc.perform(get("/stream/output?purge=true")).andReturn();
mockMvc.perform(get("/stream/output/missing")).andExpect(status().isNotFound());
}
@Test
public void empty() throws Exception {
// An explicit route registration prevents the implicit conversion of route into
// body
mockMvc.perform(get("/stream/output?purge=true")).andReturn();
mockMvc.perform(get("/stream/empty")).andExpect(status().isOk())
.andExpect(content().string(containsString("[]")));
}
@SpringBootApplication
@EnableBinding(Processor.class)
protected static class TestConfiguration {
@Autowired
private Processor processor;
@StreamListener(Processor.INPUT)
public void uppercase(Message<String> input) {
processor.output()
.send(MessageBuilder.withPayload(input.getPayload().toUpperCase())
.copyHeaders(input.getHeaders()).build());
}
@Bean
public RouteRegistry routeRegistry() {
return () -> Collections.singleton("empty");
}
}
}

View File

@@ -0,0 +1,94 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@DirtiesContext
public class SourceMessageChannelBinderTests {
@Autowired
private Source source;
@Autowired
private MockMvc mockMvc;
@Test
public void supplier() throws Exception {
source.output().send(MessageBuilder.withPayload("hello").build());
mockMvc.perform(get("/stream/output")).andExpect(status().isOk())
.andExpect(content().string(containsString("hello")));
}
@Test
public void implicit() throws Exception {
source.output().send(MessageBuilder.withPayload("hello").build());
mockMvc.perform(get("/stream")).andExpect(status().isOk())
.andExpect(content().string(containsString("hello")));
}
@Test
public void trailing() throws Exception {
source.output().send(MessageBuilder.withPayload("hello").build());
mockMvc.perform(get("/stream/")).andExpect(status().isOk())
.andExpect(content().string(containsString("hello")));
}
@Test
public void empty() throws Exception {
mockMvc.perform(get("/stream/output?purge=true")).andReturn();
mockMvc.perform(get("/stream/output")).andExpect(status().isOk())
.andExpect(content().string(containsString("[]")));
}
@Test
public void missing() throws Exception {
// Missing route is just empty
mockMvc.perform(get("/stream/missing")).andExpect(status().isNotFound())
.andExpect(content().string(equalTo("")));
}
@SpringBootApplication
@EnableBinding(Source.class)
protected static class TestConfiguration {
}
}

View File

@@ -0,0 +1,195 @@
/*
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.servlet.test;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Dave Syer
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class SseSourceMessageChannelBinderTests {
private static Log log = LogFactory.getLog(SseSourceMessageChannelBinderTests.class);
@Autowired
private Source source;
private CountDownLatch latch = new CountDownLatch(1);
private RestTemplate rest = new RestTemplate();
@LocalServerPort
private int port;
private String message = null;
@Before
public void init() throws Exception {
rest.getForEntity(
new URI("http://localhost:" + port + "/stream/output?purge=true"),
String.class);
}
@Test
public void supplier() throws Exception {
source.output().send(MessageBuilder.withPayload("hello").build());
rest.getInterceptors().add(new NonClosingInterceptor());
ResponseEntity<String> response = rest.execute(
new URI("http://localhost:" + port + "/stream/output"), HttpMethod.GET,
request -> request.getHeaders()
.setAccept(Arrays.asList(MediaType.TEXT_EVENT_STREAM)),
this::extract);
assertThat(response.getHeaders().getContentType())
.isGreaterThan(MediaType.TEXT_EVENT_STREAM);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo("data:hello\n\n");
}
@Test
public void lateSending() throws Exception {
message = "world";
rest.getInterceptors().add(new NonClosingInterceptor());
ResponseEntity<String> response = rest.execute(
new URI("http://localhost:" + port + "/stream/output"), HttpMethod.GET,
request -> request.getHeaders()
.setAccept(Arrays.asList(MediaType.TEXT_EVENT_STREAM)),
this::extract);
assertThat(response.getHeaders().getContentType())
.isGreaterThan(MediaType.TEXT_EVENT_STREAM);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo("data:world\n\n");
}
@SpringBootApplication
@EnableBinding(Source.class)
protected static class TestConfiguration {
}
private ResponseEntity<String> extract(ClientHttpResponse response)
throws IOException {
if (message != null) {
// Once there is an incoming request we can send a message to it
source.output().send(MessageBuilder.withPayload(message).build());
}
byte[] bytes = new byte[1024];
StringBuilder builder = new StringBuilder();
int read = 0;
while (read >= 0
&& StringUtils.countOccurrencesOf(builder.toString(), "\n") < 2) {
read = response.getBody().read(bytes, 0, bytes.length);
if (read > 0) {
latch.countDown();
builder.append(new String(bytes, 0, read));
}
log.debug("Building: " + builder);
}
log.debug("Done: " + builder);
return ResponseEntity.status(response.getStatusCode())
.headers(response.getHeaders()).body(builder.toString());
}
/**
* Special interceptor that prevents the response from being closed and allows us to
* assert on the contents of an event stream.
*/
private class NonClosingInterceptor implements ClientHttpRequestInterceptor {
private class NonClosingResponse implements ClientHttpResponse {
private ClientHttpResponse delegate;
public NonClosingResponse(ClientHttpResponse delegate) {
this.delegate = delegate;
}
@Override
public InputStream getBody() throws IOException {
return delegate.getBody();
}
@Override
public HttpHeaders getHeaders() {
return delegate.getHeaders();
}
@Override
public HttpStatus getStatusCode() throws IOException {
return delegate.getStatusCode();
}
@Override
public int getRawStatusCode() throws IOException {
return delegate.getRawStatusCode();
}
@Override
public String getStatusText() throws IOException {
return delegate.getStatusText();
}
@Override
public void close() {
}
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
return new NonClosingResponse(execution.execute(request, body));
}
}
}

View File

@@ -0,0 +1,2 @@
spring.main.banner-mode=off
#logging.level.org.springframework.cloud.stream.binder.servlet=DEBUG