/* * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.integration.http.config; import static org.hamcrest.CoreMatchers.any; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.springframework.integration.test.util.TestUtils.getPropertyValue; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletResponse; import org.hamcrest.Matcher; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.convert.converter.Converter; import org.springframework.expression.common.LiteralExpression; import org.springframework.expression.spel.standard.SpelExpression; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.http.converter.SerializingHttpMessageConverter; import org.springframework.integration.http.inbound.HttpRequestHandlingController; import org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway; import org.springframework.integration.http.support.DefaultHttpHeaderMapper; import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHandler; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.PollableChannel; import org.springframework.messaging.SubscribableChannel; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Mark Fisher * @author Iwein Fuld * @author Oleg Zhurakousky * @author Gary Russell * @author Gunnar Hillert * @author Biju Kunjummen * @author Artem Bilan */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @DirtiesContext public class HttpInboundGatewayParserTests { @Autowired @Qualifier("inboundGateway") private HttpRequestHandlingMessagingGateway gateway; @Autowired @Qualifier("inboundGatewayWithOneCustomConverter") private HttpRequestHandlingMessagingGateway gatewayWithOneCustomConverter; @Autowired @Qualifier("inboundGatewayNoDefaultConverters") private HttpRequestHandlingMessagingGateway gatewayNoDefaultConverters; @Autowired @Qualifier("inboundGatewayWithCustomAndDefaultConverters") private HttpRequestHandlingMessagingGateway gatewayWithCustomAndDefaultConverters; @Autowired @Qualifier("withMappedHeaders") private HttpRequestHandlingMessagingGateway withMappedHeaders; @Autowired @Qualifier("withMappedHeadersAndConverter") private HttpRequestHandlingMessagingGateway withMappedHeadersAndConverter; @Autowired private HttpRequestHandlingController inboundController; @Autowired private HttpRequestHandlingController inboundControllerViewExp; @Autowired private SubscribableChannel requests; @Autowired private PollableChannel responses; @Test public void checkConfig() { assertNotNull(this.gateway); assertTrue(getPropertyValue(this.gateway, "expectReply", Boolean.class)); assertTrue(getPropertyValue(this.gateway, "convertExceptions", Boolean.class)); assertSame(this.responses, getPropertyValue(this.gateway, "replyChannel")); assertNotNull(TestUtils.getPropertyValue(this.gateway, "errorChannel")); MessagingTemplate messagingTemplate = TestUtils.getPropertyValue(this.gateway, "messagingTemplate", MessagingTemplate.class); assertEquals(1234L, TestUtils.getPropertyValue(messagingTemplate, "sendTimeout")); assertEquals(4567L, TestUtils.getPropertyValue(messagingTemplate, "receiveTimeout")); boolean registerDefaultConverters = TestUtils.getPropertyValue(this.gateway, "mergeWithDefaultConverters", Boolean.class); assertFalse("By default the register-default-converters flag should be false", registerDefaultConverters); @SuppressWarnings("unchecked") List<HttpMessageConverter<?>> messageConverters = TestUtils.getPropertyValue(this.gateway, "messageConverters", List.class); assertTrue("The default converters should have been registered, given there are no custom converters", messageConverters.size() > 0); assertFalse(TestUtils.getPropertyValue(this.gateway, "autoStartup", Boolean.class)); assertEquals(1001, TestUtils.getPropertyValue(this.gateway, "phase")); } @Test @DirtiesContext public void checkFlow() throws Exception { this.requests.subscribe(handlerExpecting(any(Message.class))); MockHttpServletRequest request = new MockHttpServletRequest(); request.setMethod("GET"); request.addHeader("Accept", "application/my-serialized"); request.setParameter("foo", "bar"); MockHttpServletResponse response = new MockHttpServletResponse(); List<HttpMessageConverter<?>> converters = new ArrayList<>(); SerializingHttpMessageConverter serializingHttpMessageConverter = new SerializingHttpMessageConverter(); serializingHttpMessageConverter.setSupportedMediaTypes( Collections.singletonList(new MediaType("application", "my-serialized"))); converters.add(serializingHttpMessageConverter); this.gateway.setMessageConverters(converters); this.gateway.afterPropertiesSet(); this.gateway.start(); this.gateway.handleRequest(request, response); assertThat(response.getStatus(), is(HttpServletResponse.SC_OK)); assertEquals(response.getContentType(), "application/my-serialized"); } @Test public void testController() throws Exception { DirectFieldAccessor accessor = new DirectFieldAccessor(inboundController); String errorCode = (String) accessor.getPropertyValue("errorCode"); assertEquals("oops", errorCode); LiteralExpression viewExpression = (LiteralExpression) accessor.getPropertyValue("viewExpression"); assertEquals("foo", viewExpression.getValue()); } @Test public void testControllerViewExp() throws Exception { DirectFieldAccessor accessor = new DirectFieldAccessor(inboundControllerViewExp); String errorCode = (String) accessor.getPropertyValue("errorCode"); assertEquals("oops", errorCode); SpelExpression viewExpression = (SpelExpression) accessor.getPropertyValue("viewExpression"); assertNotNull(viewExpression); assertEquals("'bar'", viewExpression.getExpressionString()); } @Test public void requestWithHeaders() throws Exception { DefaultHttpHeaderMapper headerMapper = (DefaultHttpHeaderMapper) TestUtils.getPropertyValue(withMappedHeaders, "headerMapper"); HttpHeaders headers = new HttpHeaders(); headers.set("foo", "foo"); headers.set("bar", "bar"); headers.set("baz", "baz"); Map<String, Object> map = headerMapper.toHeaders(headers); assertTrue(map.size() == 2); assertEquals("foo", map.get("foo")); assertEquals("bar", map.get("bar")); Map<String, Object> mapOfHeaders = new HashMap<String, Object>(); mapOfHeaders.put("abc", "abc"); MessageHeaders mh = new MessageHeaders(mapOfHeaders); headers = new HttpHeaders(); headerMapper.fromHeaders(mh, headers); assertTrue(headers.size() == 1); List<String> abc = headers.get("abc"); assertEquals("abc", abc.get(0)); } @Test public void requestWithHeadersWithConversionService() throws Exception { DefaultHttpHeaderMapper headerMapper = (DefaultHttpHeaderMapper) TestUtils.getPropertyValue(withMappedHeadersAndConverter, "headerMapper"); headerMapper.setUserDefinedHeaderPrefix("X-"); HttpHeaders headers = new HttpHeaders(); headers.set("foo", "foo"); headers.set("bar", "bar"); headers.set("baz", "baz"); Map<String, Object> map = headerMapper.toHeaders(headers); assertTrue(map.size() == 2); assertEquals("foo", map.get("foo")); assertEquals("bar", map.get("bar")); Map<String, Object> mapOfHeaders = new HashMap<String, Object>(); mapOfHeaders.put("abc", "abc"); Person person = new Person(); person.setName("Oleg"); mapOfHeaders.put("person", person); MessageHeaders mh = new MessageHeaders(mapOfHeaders); headers = new HttpHeaders(); headerMapper.fromHeaders(mh, headers); assertTrue(headers.size() == 2); List<String> abc = headers.get("X-abc"); assertEquals("abc", abc.get(0)); List<String> personHeaders = headers.get("X-person"); assertEquals("Oleg", personHeaders.get(0)); } @Test public void testInboundGatewayWithMessageConverterDefaults() { @SuppressWarnings("unchecked") List<HttpMessageConverter<?>> messageConverters = TestUtils.getPropertyValue(gatewayWithOneCustomConverter, "messageConverters", List.class); assertThat("There should be only 1 message converter, by default register-default-converters is off", messageConverters.size(), is(1)); //The converter should be the customized one assertThat(messageConverters.get(0), instanceOf(SerializingHttpMessageConverter.class)); } @Test public void testInboundGatewayWithNoMessageConverterDefaults() { @SuppressWarnings("unchecked") List<HttpMessageConverter<?>> messageConverters = TestUtils.getPropertyValue(gatewayNoDefaultConverters, "messageConverters", List.class); //First converter should be the customized one assertThat(messageConverters.get(0), instanceOf(SerializingHttpMessageConverter.class)); assertThat("There should be only 1 message converter, the register-default-converters is false", messageConverters.size(), is(1)); } @Test public void testInboundGatewayWithCustomAndDefaultMessageConverters() { @SuppressWarnings("unchecked") List<HttpMessageConverter<?>> messageConverters = TestUtils.getPropertyValue(gatewayWithCustomAndDefaultConverters, "messageConverters", List.class); //First converter should be the customized one assertThat(messageConverters.get(0), instanceOf(SerializingHttpMessageConverter.class)); assertTrue("There should be more than one converter", messageConverters.size() > 1); } @SuppressWarnings("rawtypes") private MessageHandler handlerExpecting(final Matcher<Message> messageMatcher) { return message -> assertThat(message, is(messageMatcher)); } public static class Person { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public static class PersonConverter implements Converter<Person, String> { @Override public String convert(Person source) { return source.getName(); } } }