1   /*
2    * $Id: JmsTransformersTestCase.java 12210 2008-07-01 11:38:41Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.jms;
12  
13  import org.mule.RequestContext;
14  import org.mule.transport.jms.integration.AbstractJmsFunctionalTestCase;
15  import org.mule.transport.jms.transformers.AbstractJmsTransformer;
16  import org.mule.transport.jms.transformers.JMSMessageToObject;
17  import org.mule.transport.jms.transformers.ObjectToJMSMessage;
18  import org.mule.util.FileUtils;
19  import org.mule.util.compression.CompressionStrategy;
20  import org.mule.util.compression.GZipCompression;
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Properties;
28  import java.util.Vector;
29  
30  import javax.jms.BytesMessage;
31  import javax.jms.ConnectionFactory;
32  import javax.jms.MapMessage;
33  import javax.jms.ObjectMessage;
34  import javax.jms.Session;
35  import javax.jms.StreamMessage;
36  import javax.jms.TextMessage;
37  
38  import org.apache.commons.io.output.ByteArrayOutputStream;
39  
40  /**
41   * <code>JmsTransformersTestCase</code> Tests the JMS transformer implementations.
42   */
43  
44  public class JmsTransformersTestCase extends AbstractJmsFunctionalTestCase
45  {
46      private Session session = null;
47  
48      protected String getConfigResources()
49      {
50          return "activemq-config.xml";
51      }
52  
53      protected void doSetUp() throws Exception
54      {
55          super.doSetUp();
56          
57          JmsConnector connector = (JmsConnector) muleContext.getRegistry().lookupConnector("jmsConnector");
58          ConnectionFactory cf = connector.getConnectionFactory();
59          
60          session = cf.createConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);                
61      }
62  
63      // @Override
64      protected void doTearDown() throws Exception
65      {
66          RequestContext.setEvent(null);
67          if (session != null)
68          {
69              session.close();
70              session = null;
71          }
72      }
73  
74      public void testTransformObjectMessage() throws Exception
75      {
76          RequestContext.setEvent(getTestEvent("test"));
77  
78          ObjectMessage oMsg = session.createObjectMessage();
79          File f = FileUtils.newFile("/some/random/path");
80          oMsg.setObject(f);
81          AbstractJmsTransformer trans = new JMSMessageToObject();
82          Object result = trans.transform(oMsg);
83          assertTrue("Transformed object should be a File", result.getClass().equals(File.class));
84  
85          AbstractJmsTransformer trans2 = new SessionEnabledObjectToJMSMessage(session);
86          trans2.setReturnClass(ObjectMessage.class);
87          Object result2 = trans2.transform(f);
88          assertTrue("Transformed object should be an object message", result2 instanceof ObjectMessage);
89      }
90  
91      public void testTransformTextMessage() throws Exception
92      {
93          RequestContext.setEvent(getTestEvent("test"));
94  
95          String text = "This is a test TextMessage";
96          TextMessage tMsg = session.createTextMessage();
97          tMsg.setText(text);
98  
99          AbstractJmsTransformer trans = new JMSMessageToObject();
100         Object result = trans.transform(tMsg);
101         assertTrue("Transformed object should be a string", text.equals(result.toString()));
102 
103         AbstractJmsTransformer trans2 = new SessionEnabledObjectToJMSMessage(session);
104         trans2.setReturnClass(TextMessage.class);
105         Object result2 = trans2.transform(text);
106         assertTrue("Transformed object should be a TextMessage", result2 instanceof TextMessage);
107     }
108 
109     public void testTransformMapMessage() throws Exception
110     {
111         RequestContext.setEvent(getTestEvent("test"));
112 
113         Properties p = new Properties();
114         p.setProperty("Key1", "Value1");
115         p.setProperty("Key2", "Value2");
116         p.setProperty("Key3", "Value3");
117 
118         AbstractJmsTransformer trans = new SessionEnabledObjectToJMSMessage(session);
119         trans.setReturnClass(MapMessage.class);
120         Object result2 = trans.transform(p);
121         assertTrue("Transformed object should be a MapMessage", result2 instanceof MapMessage);
122 
123         MapMessage mMsg = (MapMessage)result2;
124         AbstractJmsTransformer trans2 = new JMSMessageToObject();
125         trans2.setReturnClass(Map.class);
126         Object result = trans2.transform(mMsg);
127         assertTrue("Transformed object should be a Map", result instanceof Map);
128     }
129 
130     public void testTransformByteMessage() throws Exception
131     {
132         RequestContext.setEvent(getTestEvent("test"));
133 
134         AbstractJmsTransformer trans = new SessionEnabledObjectToJMSMessage(session);
135         trans.setReturnClass(BytesMessage.class);
136         String text = "This is a test BytesMessage";
137         Object result2 = trans.transform(text.getBytes());
138         assertTrue("Transformed object should be a BytesMessage", result2 instanceof BytesMessage);
139 
140         AbstractJmsTransformer trans2 = new JMSMessageToObject();
141         trans2.setReturnClass(byte[].class);
142         BytesMessage bMsg = (BytesMessage)result2;
143         Object result = trans2.transform(bMsg);
144         assertTrue("Transformed object should be a byte[]", result instanceof byte[]);
145         String res = new String((byte[])result);
146         assertEquals("Source and result should be equal", text, res);
147     }
148 
149     public void testTransformStreamMessage() throws Exception
150     {
151         RequestContext.setEvent(getTestEvent("test"));
152 
153         String text = "Test Text";
154         int i = 97823;
155         double d = 0923.2143E124;
156         List list = new ArrayList();
157         list.add(new Integer(i));
158         list.add(new Double(d));
159         list.add(text);
160 
161         StreamMessage message = session.createStreamMessage();
162         message.writeString(text);
163         message.writeInt(i);
164         message.writeDouble(d);
165         message.reset();
166 
167         AbstractJmsTransformer trans = new JMSMessageToObject();
168         Object result = trans.transform(message);
169         assertTrue("Transformed object should be a Vector", result instanceof Vector);
170 
171         String newText = (String) ((Vector) result).get(0);
172         Integer newI = (Integer) ((Vector) result).get(1);
173         Double newD = (Double) ((Vector) result).get(2);
174         assertEquals(i, newI.intValue());
175         assertEquals(new Double(d), newD);
176         assertEquals(text, newText);
177     }
178     
179     
180     // The following test was disabled for ActiveMQ 3.x because ActiveMQ 3.2.4
181     // unconditionally uncompresses BytesMessages for reading, even if it is not
182     // supposed to do so (the layer doing the message reading seems to have no access
183     // to the Broker configuration and seems to assume that compressed data was
184     // compressed by ActiveMQ for more efficient wire transport).
185     // This was fixed in 4.x.
186     // For more information why this was VERY BAD read:
187     // http://en.wikipedia.org/wiki/Zip_of_death
188     public void testCompressedBytesMessage() throws Exception
189     {
190         RequestContext.setEvent(getTestEvent("test"));
191 
192         // use GZIP
193         CompressionStrategy compressor = new GZipCompression();
194 
195         // create compressible data
196         ByteArrayOutputStream baos = new ByteArrayOutputStream();
197         for (int i = 0; i < 5000; i++)
198         {
199             baos.write(i);
200         }
201 
202         byte[] originalBytes = baos.toByteArray();
203         byte[] compressedBytes = compressor.compressByteArray(originalBytes);
204         assertTrue("Source compressedBytes should be compressed", compressor.isCompressed(compressedBytes));
205 
206         // now create a BytesMessage from the compressed byte[]
207         AbstractJmsTransformer trans = new SessionEnabledObjectToJMSMessage(session);
208         trans.setReturnClass(BytesMessage.class);
209         Object result2 = trans.transform(compressedBytes);
210         assertTrue("Transformed object should be a Bytes message", result2 instanceof BytesMessage);
211 
212         // check whether the BytesMessage contains the compressed bytes
213         BytesMessage intermediate = (BytesMessage)result2;
214         intermediate.reset();
215         byte[] intermediateBytes = new byte[(int)(intermediate.getBodyLength())];
216         int intermediateSize = intermediate.readBytes(intermediateBytes);
217         assertTrue("Intermediate bytes must be compressed", compressor.isCompressed(intermediateBytes));
218         assertTrue("Intermediate bytes must be equal to compressed source", Arrays.equals(compressedBytes,
219             intermediateBytes));
220         assertEquals("Intermediate bytes and compressed source must have same size", compressedBytes.length,
221             intermediateSize);
222 
223         // now test the other way around: getting the byte[] from a manually created
224         // BytesMessage
225         AbstractJmsTransformer trans2 = new JMSMessageToObject();
226         trans2.setReturnClass(byte[].class);
227         BytesMessage bMsg = session.createBytesMessage();
228         bMsg.writeBytes(compressedBytes);
229         Object result = trans2.transform(bMsg);
230         assertTrue("Transformed object should be a byte[]", result instanceof byte[]);
231         assertTrue("Result should be compressed", compressor.isCompressed((byte[])result));
232         assertTrue("Source and result should be equal", Arrays.equals(compressedBytes, (byte[])result));
233     }
234 
235     /*
236      * This class overrides getSession() to return the specified test MuleSession;
237      * otherwise we would need a full-fledged JMS connector with dispatchers etc.
238      * TODO check if we really need this stateful transformer now
239      */
240     public static class SessionEnabledObjectToJMSMessage extends ObjectToJMSMessage
241     {
242         private final Session transformerSession;
243 
244         public SessionEnabledObjectToJMSMessage(Session session)
245         {
246             super();
247             transformerSession = session;
248         }
249 
250         // @Override
251         protected Session getSession()
252         {
253             return transformerSession;
254         }
255     }
256 
257 }