1   /*
2    * $Id: JmsTransformersTestCase.java 7963 2007-08-21 08:53:15Z 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.test.integration.providers.jms.activemq;
12  
13  import org.mule.impl.RequestContext;
14  import org.mule.providers.jms.transformers.AbstractJmsTransformer;
15  import org.mule.providers.jms.transformers.JMSMessageToObject;
16  import org.mule.providers.jms.transformers.ObjectToJMSMessage;
17  import org.mule.tck.AbstractMuleTestCase;
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.Arrays;
24  import java.util.Map;
25  import java.util.Properties;
26  
27  import javax.jms.BytesMessage;
28  import javax.jms.MapMessage;
29  import javax.jms.ObjectMessage;
30  import javax.jms.Session;
31  import javax.jms.TextMessage;
32  
33  import org.apache.activemq.ActiveMQConnectionFactory;
34  import org.apache.commons.io.output.ByteArrayOutputStream;
35  
36  /**
37   * <code>JmsTransformersTestCase</code> Tests the JMS transformer implementations.
38   */
39  
40  public class JmsTransformersTestCase extends AbstractMuleTestCase
41  {
42      private ActiveMQConnectionFactory factory = null;
43      private Session session = null;
44  
45      // @Override
46      protected void doSetUp() throws Exception
47      {
48          factory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false&broker.useJmx=false");
49  
50          session = factory.createConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
51      }
52  
53      // @Override
54      protected void doTearDown() throws Exception
55      {
56          RequestContext.setEvent(null);
57          session.close();
58          session = null;
59          factory = null;
60      }
61  
62      public void testTransformObjectMessage() throws Exception
63      {
64          RequestContext.setEvent(getTestEvent("test"));
65  
66          ObjectMessage oMsg = session.createObjectMessage();
67          File f = FileUtils.newFile("/some/random/path");
68          oMsg.setObject(f);
69          AbstractJmsTransformer trans = new JMSMessageToObject();
70          Object result = trans.transform(oMsg);
71          assertTrue("Transformed object should be a File", result.getClass().equals(File.class));
72  
73          AbstractJmsTransformer trans2 = new SessionEnabledObjectToJMSMessage(session);
74          trans2.setReturnClass(ObjectMessage.class);
75          Object result2 = trans2.transform(f);
76          assertTrue("Transformed object should be an object message", result2 instanceof ObjectMessage);
77      }
78  
79      public void testTransformTextMessage() throws Exception
80      {
81          RequestContext.setEvent(getTestEvent("test"));
82  
83          String text = "This is a test TextMessage";
84          TextMessage tMsg = session.createTextMessage();
85          tMsg.setText(text);
86  
87          AbstractJmsTransformer trans = new JMSMessageToObject();
88          Object result = trans.transform(tMsg);
89          assertTrue("Transformed object should be a string", text.equals(result.toString()));
90  
91          AbstractJmsTransformer trans2 = new SessionEnabledObjectToJMSMessage(session);
92          trans2.setReturnClass(TextMessage.class);
93          Object result2 = trans2.transform(text);
94          assertTrue("Transformed object should be a TextMessage", result2 instanceof TextMessage);
95      }
96  
97      public void testTransformMapMessage() throws Exception
98      {
99          RequestContext.setEvent(getTestEvent("test"));
100 
101         Properties p = new Properties();
102         p.setProperty("Key1", "Value1");
103         p.setProperty("Key2", "Value2");
104         p.setProperty("Key3", "Value3");
105 
106         AbstractJmsTransformer trans = new SessionEnabledObjectToJMSMessage(session);
107         trans.setReturnClass(MapMessage.class);
108         Object result2 = trans.transform(p);
109         assertTrue("Transformed object should be a MapMessage", result2 instanceof MapMessage);
110 
111         MapMessage mMsg = (MapMessage)result2;
112         AbstractJmsTransformer trans2 = new JMSMessageToObject();
113         trans2.setReturnClass(Map.class);
114         Object result = trans2.transform(mMsg);
115         assertTrue("Transformed object should be a Map", result instanceof Map);
116     }
117 
118     public void testTransformByteMessage() throws Exception
119     {
120         RequestContext.setEvent(getTestEvent("test"));
121 
122         AbstractJmsTransformer trans = new SessionEnabledObjectToJMSMessage(session);
123         trans.setReturnClass(BytesMessage.class);
124         String text = "This is a test BytesMessage";
125         Object result2 = trans.transform(text.getBytes());
126         assertTrue("Transformed object should be a BytesMessage", result2 instanceof BytesMessage);
127 
128         AbstractJmsTransformer trans2 = new JMSMessageToObject();
129         trans2.setReturnClass(byte[].class);
130         BytesMessage bMsg = (BytesMessage)result2;
131         Object result = trans2.transform(bMsg);
132         assertTrue("Transformed object should be a byte[]", result instanceof byte[]);
133         String res = new String((byte[])result);
134         assertEquals("Source and result should be equal", text, res);
135     }
136 
137     // The following test was disabled for ActiveMQ 3.x because ActiveMQ 3.2.4
138     // unconditionally uncompresses BytesMessages for reading, even if it is not
139     // supposed to do so (the layer doing the message reading seems to have no access
140     // to the Broker configuration and seems to assume that compressed data was
141     // compressed by ActiveMQ for more efficient wire transport).
142     // This was fixed in 4.x.
143     // For more information why this was VERY BAD read:
144     // http://en.wikipedia.org/wiki/Zip_of_death
145     public void testCompressedBytesMessage() throws Exception
146     {
147         RequestContext.setEvent(getTestEvent("test"));
148 
149         // use GZIP
150         CompressionStrategy compressor = new GZipCompression();
151 
152         // create compressible data
153         ByteArrayOutputStream baos = new ByteArrayOutputStream();
154         for (int i = 0; i < 5000; i++)
155         {
156             baos.write(i);
157         }
158 
159         byte[] originalBytes = baos.toByteArray();
160         byte[] compressedBytes = compressor.compressByteArray(originalBytes);
161         assertTrue("Source compressedBytes should be compressed", compressor.isCompressed(compressedBytes));
162 
163         // now create a BytesMessage from the compressed byte[]
164         AbstractJmsTransformer trans = new SessionEnabledObjectToJMSMessage(session);
165         trans.setReturnClass(BytesMessage.class);
166         Object result2 = trans.transform(compressedBytes);
167         assertTrue("Transformed object should be a Bytes message", result2 instanceof BytesMessage);
168 
169         // check whether the BytesMessage contains the compressed bytes
170         BytesMessage intermediate = (BytesMessage)result2;
171         intermediate.reset();
172         byte[] intermediateBytes = new byte[(int)(intermediate.getBodyLength())];
173         int intermediateSize = intermediate.readBytes(intermediateBytes);
174         assertTrue("Intermediate bytes must be compressed", compressor.isCompressed(intermediateBytes));
175         assertTrue("Intermediate bytes must be equal to compressed source", Arrays.equals(compressedBytes,
176             intermediateBytes));
177         assertEquals("Intermediate bytes and compressed source must have same size", compressedBytes.length,
178             intermediateSize);
179 
180         // now test the other way around: getting the byte[] from a manually created
181         // BytesMessage
182         AbstractJmsTransformer trans2 = new JMSMessageToObject();
183         trans2.setReturnClass(byte[].class);
184         BytesMessage bMsg = session.createBytesMessage();
185         bMsg.writeBytes(compressedBytes);
186         Object result = trans2.transform(bMsg);
187         assertTrue("Transformed object should be a byte[]", result instanceof byte[]);
188         assertTrue("Result should be compressed", compressor.isCompressed((byte[])result));
189         assertTrue("Source and result should be equal", Arrays.equals(compressedBytes, (byte[])result));
190     }
191 
192     /*
193      * This class overrides getSession() to return the specified test Session;
194      * otherwise we would need a full-fledged JMS connector with dispatchers etc.
195      * TODO check if we really need this stateful transformer now
196      */
197     public static class SessionEnabledObjectToJMSMessage extends ObjectToJMSMessage
198     {
199         private final Session transformerSession;
200 
201         public SessionEnabledObjectToJMSMessage(Session session)
202         {
203             super();
204             transformerSession = session;
205         }
206 
207         // @Override
208         protected Session getSession()
209         {
210             return transformerSession;
211         }
212     }
213 
214 }