View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.servlet;
8   
9   import org.mule.api.MuleMessage;
10  import org.mule.api.transport.MuleMessageFactory;
11  import org.mule.transport.AbstractMuleMessageFactoryTestCase;
12  import org.mule.transport.http.HttpConstants;
13  import org.mule.util.UUID;
14  
15  import java.io.ByteArrayInputStream;
16  import java.io.InputStream;
17  import java.util.Arrays;
18  import java.util.HashMap;
19  import java.util.Map;
20  import java.util.Vector;
21  
22  import javax.servlet.http.HttpSession;
23  
24  import org.junit.Test;
25  
26  import static org.junit.Assert.assertEquals;
27  import static org.junit.Assert.assertFalse;
28  import static org.junit.Assert.assertNotNull;
29  import static org.junit.Assert.assertTrue;
30  import static org.mockito.Mockito.mock;
31  import static org.mockito.Mockito.when;
32  
33  public class ServletMuleMessageFactoryTestCase extends AbstractMuleMessageFactoryTestCase
34  {
35      private static final String CHARACTER_ENCODING_PROPERTY_KEY = ServletConnector.CHARACTER_ENCODING_PROPERTY_KEY;
36      private static final String CONTENT_TYPE_PROPERTY_KEY = ServletConnector.CONTENT_TYPE_PROPERTY_KEY;
37      private static final String PARAMETER_MAP_PROPERTY_KEY = ServletConnector.PARAMETER_MAP_PROPERTY_KEY;
38  
39      private static final String REQUEST_URI = MockHttpServletRequestBuilder.REQUEST_URI;
40  
41      private MuleMessageFactory factory;
42  
43      @Override
44      protected void doSetUp() throws Exception
45      {
46          super.doSetUp();
47          factory = createMuleMessageFactory();
48      }
49  
50      @Override
51      protected MuleMessageFactory doCreateMuleMessageFactory()
52      {
53          return new ServletMuleMessageFactory(muleContext);
54      }
55  
56      @Override
57      protected Object getValidTransportMessage() throws Exception
58      {
59          return new MockHttpServletRequestBuilder().buildRequest();
60      }
61  
62      @Override
63      protected Object getUnsupportedTransportMessage()
64      {
65          return "this is not a valid transport message for ServletMuleMessageFactory";
66      }
67  
68      /**
69       * Tests creating a MuleMessage from a GET request
70       */
71      @Override
72      public void testValidPayload() throws Exception
73      {
74          Object payload = getValidTransportMessage();
75          MuleMessage message = factory.create(payload, encoding);
76          assertNotNull(message);
77          assertEquals(REQUEST_URI, message.getPayload());
78      }
79  
80      @Test
81      public void testGetPayloadWithQueryParameter() throws Exception
82      {
83          MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
84          builder.queryString = "foo=bar";
85          Object payload = builder.buildRequest();
86  
87          MuleMessage message = factory.create(payload, encoding);
88          assertNotNull(message);
89          String expected = REQUEST_URI + "?" + builder.queryString;
90          assertEquals(expected, message.getPayload());
91      }
92  
93      @Test
94      public void testPostPayload() throws Exception
95      {
96          Object payload = buildPostRequest();
97          MuleMessage message = factory.create(payload, encoding);
98          assertNotNull(message);
99          assertTrue(message.getPayload() instanceof InputStream);
100     }
101 
102     @Test
103     public void testRequestParametersAreConvertedToMessageProperties() throws Exception
104     {
105         Object payload = buildPostRequest();
106         MuleMessage message = factory.create(payload, encoding);
107         assertRequestParameterProperty("foo-value", message, "foo");
108         assertRequestParameterProperty("bar-value", message, "bar");
109 
110         Map<String, Object> parameters = retrieveMapProperty(message, PARAMETER_MAP_PROPERTY_KEY);
111         assertNotNull(parameters);
112         assertEquals("foo-value", parameters.get("foo"));
113         assertEquals("bar-value", parameters.get("bar"));
114     }
115 
116     @Test
117     public void testContentEncodingWithCharsetLast() throws Exception
118     {
119         String contentType = "text/plain;charset=UTF-21";
120         Object payload = buildGetRequestWithContentType(contentType);
121         MuleMessage message = factory.create(payload, encoding);
122         assertEquals("UTF-21", message.getEncoding());
123         assertInboundScopedProperty(contentType, message, CONTENT_TYPE_PROPERTY_KEY);
124     }
125 
126     @Test
127     public void testContentEncodingWithCharsetFirst() throws Exception
128     {
129         String contentType = "charset=UTF-21;text/plain";
130         Object payload = buildGetRequestWithContentType(contentType);
131         MuleMessage message = factory.create(payload, encoding);
132         assertEquals("UTF-21", message.getEncoding());
133         assertInboundScopedProperty(contentType, message, CONTENT_TYPE_PROPERTY_KEY);
134     }
135 
136     @Test
137     public void testMessageIdFromHttpSession() throws Exception
138     {
139         String sessionId = UUID.getUUID();
140         Object payload = buildGetRequestWithSession(sessionId);
141         MuleMessage message = factory.create(payload, encoding);
142         assertEquals(sessionId, message.<Object>getInboundProperty(ServletConnector.SESSION_ID_PROPERTY_KEY));
143     }
144 
145     /**
146      * Test for MULE-5101
147      */
148     @Test
149     public void testUniqueMessageId() throws Exception
150     {
151         String sessionId = UUID.getUUID();
152         Object payload = buildGetRequestWithSession(sessionId);
153         Object payload2 = buildGetRequestWithSession(sessionId);
154         MuleMessage message = factory.create(payload, encoding);
155         MuleMessage message2 = factory.create(payload2, encoding);
156         assertEquals(sessionId, message.<Object>getInboundProperty(ServletConnector.SESSION_ID_PROPERTY_KEY));
157         assertEquals(sessionId, message2.<Object>getInboundProperty(ServletConnector.SESSION_ID_PROPERTY_KEY));
158 
159         assertFalse(message.getUniqueId().equals(message2.getUniqueId()));
160     }
161 
162     @Test
163     public void testCharacterEncodingFromHttpRequest() throws Exception
164     {
165         MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
166         builder.characterEncoding = "UTF-21";
167         Object payload = builder.buildRequest();
168 
169         MuleMessage message = factory.create(payload, encoding);
170         assertInboundScopedProperty(builder.characterEncoding, message, CHARACTER_ENCODING_PROPERTY_KEY);
171     }
172 
173     @Test
174     public void testRequestPropertiesAreConvertedToMessageProperties() throws Exception
175     {
176         Object payload = buildGetRequestWithParameterValue("foo-param", "foo-value");
177         MuleMessage message = factory.create(payload, encoding);
178         assertInboundScopedProperty("foo-value", message, "foo-param");
179     }
180 
181     @Test
182     public void testRequestAttributesAreConvertedToMessageProperties() throws Exception
183     {
184         Object payload = buildGetRequestWithAttributeValue("foo-attribute", "foo-value");
185         MuleMessage message = factory.create(payload, encoding);
186         assertInboundScopedProperty("foo-value", message, "foo-attribute");
187     }
188 
189     @Test
190     public void testRequestHeadersAreConvertedToMessageProperties() throws Exception
191     {
192         Object payload = buildGetRequestWithHeaders();
193         MuleMessage message = factory.create(payload, encoding);
194         assertInboundScopedProperty("foo-value", message, "foo-header");
195         assertInboundScopedProperty("MULE_HEADER_VALUE", message, "MULE_HEADER");
196         assertInboundScopedProperty("localhost:8080", message, HttpConstants.HEADER_HOST);
197 
198         Object[] expected = new Object[] { "value-one", "value-two" };
199         assertTrue(Arrays.equals(expected, (Object[]) message.getInboundProperty("multi-value")));
200     }
201 
202     private void assertInboundScopedProperty(Object expected, MuleMessage message, String key)
203     {
204         Object value = message.getInboundProperty(key);
205         assertEquals(expected, value);
206     }
207 
208     private void assertRequestParameterProperty(String expected, MuleMessage message, String key)
209     {
210         String propertyKey = ServletConnector.PARAMETER_PROPERTY_PREFIX + key;
211         // message factory puts props in the inbound scope
212         Object value = message.getInboundProperty(propertyKey);
213         assertEquals(expected, value);
214     }
215 
216     private Map<String, Object> retrieveMapProperty(MuleMessage message, String key)
217     {
218         return message.getInboundProperty(key);
219     }
220 
221     private Object buildGetRequestWithContentType(String contentType) throws Exception
222     {
223         MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
224         builder.contentType = contentType;
225         return builder.buildRequest();
226     }
227 
228     private Object buildGetRequestWithSession(String sessionId) throws Exception
229     {
230         HttpSession session = mock(HttpSession.class);
231         when(session.getId()).thenReturn(sessionId);
232 
233         MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
234         builder.session = session;
235         return builder.buildRequest();
236     }
237 
238     private Object buildGetRequestWithParameterValue(String key, String value) throws Exception
239     {
240         MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
241         builder.parameters = new HashMap<String, String[]>();
242         builder.parameters.put(key, new String[] { value });
243         return builder.buildRequest();
244     }
245 
246     private Object buildGetRequestWithAttributeValue(String key, String value) throws Exception
247     {
248         MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
249         builder.attributes.put(key, value);
250         return builder.buildRequest();
251     }
252 
253     private Object buildGetRequestWithHeaders() throws Exception
254     {
255         MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
256         builder.headers.put("foo-header", "foo-value");
257         builder.headers.put("X-MULE_HEADER", "MULE_HEADER_VALUE");
258         builder.headers.put(HttpConstants.HEADER_HOST, "localhost");
259 
260         Vector<String> multiValue = new Vector<String>();
261         multiValue.add("value-one");
262         multiValue.add("value-two");
263         builder.headers.put("multi-value", multiValue.elements());
264 
265         return builder.buildRequest();
266     }
267 
268     private Object buildPostRequest() throws Exception
269     {
270         MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
271         builder.method = HttpConstants.METHOD_POST;
272 
273         InputStream stream = new ByteArrayInputStream(TEST_MESSAGE.getBytes());
274         builder.inputStream = new MockServletInputStream(stream);
275 
276         builder.parameters = new HashMap<String, String[]>();
277         builder.parameters.put("foo", new String[] { "foo-value" });
278         builder.parameters.put("bar", new String[] { "bar-value" });
279 
280         return builder.buildRequest();
281     }
282 }