1   /*
2    * $Id: FilteringXmlMessageSplitterTestCase.java 11728 2008-05-13 07:31:11Z 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.routing.outbound;
12  
13  import org.mule.impl.MuleMessage;
14  import org.mule.impl.endpoint.MuleEndpointURI;
15  import org.mule.tck.AbstractMuleTestCase;
16  import org.mule.tck.MuleTestUtils;
17  import org.mule.umo.UMOMessage;
18  import org.mule.umo.UMOSession;
19  import org.mule.umo.endpoint.UMOEndpoint;
20  import org.mule.util.IOUtils;
21  
22  import com.mockobjects.constraint.Constraint;
23  import com.mockobjects.dynamic.C;
24  import com.mockobjects.dynamic.Mock;
25  
26  import java.util.HashMap;
27  import java.util.Map;
28  
29  import org.dom4j.Document;
30  import org.dom4j.DocumentHelper;
31  
32  public class FilteringXmlMessageSplitterTestCase extends AbstractMuleTestCase
33  {
34      private UMOEndpoint endpoint1;
35      private UMOEndpoint endpoint2;
36      private UMOEndpoint endpoint3;
37      private FilteringXmlMessageSplitter xmlSplitter;
38  
39      // @Override
40      protected void doSetUp() throws Exception
41      {
42          // setup endpoints
43          endpoint1 = getTestEndpoint("Test1Endpoint", UMOEndpoint.ENDPOINT_TYPE_SENDER);
44          endpoint1.setEndpointURI(new MuleEndpointURI("test://endpointUri.1"));
45          endpoint2 = getTestEndpoint("Test2Endpoint", UMOEndpoint.ENDPOINT_TYPE_SENDER);
46          endpoint2.setEndpointURI(new MuleEndpointURI("test://endpointUri.2"));
47          endpoint3 = getTestEndpoint("Test3Endpoint", UMOEndpoint.ENDPOINT_TYPE_SENDER);
48          endpoint3.setEndpointURI(new MuleEndpointURI("test://endpointUri.3"));
49  
50          // setup splitter
51          xmlSplitter = new FilteringXmlMessageSplitter();
52          xmlSplitter.setValidateSchema(true);
53          xmlSplitter.setExternalSchemaLocation("purchase-order.xsd");
54  
55          // The xml document declares a default namespace, thus
56          // we need to workaround it by specifying it both in
57          // the namespaces and in the splitExpression
58          Map namespaces = new HashMap();
59          namespaces.put("e", "http://www.example.com");
60          xmlSplitter.setSplitExpression("/e:purchaseOrder/e:items/e:item");
61          xmlSplitter.setNamespaces(namespaces);
62          xmlSplitter.addEndpoint(endpoint1);
63          xmlSplitter.addEndpoint(endpoint2);
64          xmlSplitter.addEndpoint(endpoint3);
65      }
66  
67      public void testStringPayloadXmlMessageSplitter() throws Exception
68      {
69          String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
70          internalTestSuccessfulXmlSplitter(payload);
71      }
72  
73      public void testStringPayloadXmlMessageSplitterWithoutXsd() throws Exception
74      {
75          xmlSplitter.setExternalSchemaLocation(null);
76          xmlSplitter.setValidateSchema(false);
77          String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
78          internalTestSuccessfulXmlSplitter(payload);
79      }
80  
81      public void testDom4JDocumentPayloadXmlMessageSplitter() throws Exception
82      {
83          String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
84          Document doc = DocumentHelper.parseText(payload);
85          internalTestSuccessfulXmlSplitter(doc);
86      }
87  
88      public void testByteArrayPayloadXmlMessageSplitter() throws Exception
89      {
90          String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
91          internalTestSuccessfulXmlSplitter(payload.getBytes());
92      }
93  
94      public void testByteArrayPayloadCorrelateNever() throws Exception
95      {
96          String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
97          xmlSplitter.setEnableCorrelation(AbstractOutboundRouter.ENABLE_CORRELATION_NEVER);
98          internalTestSuccessfulXmlSplitter(payload.getBytes());
99      }
100 
101     private void internalTestSuccessfulXmlSplitter(Object payload) throws Exception
102     {
103         Mock session = MuleTestUtils.getMockSession();
104         session.matchAndReturn("getComponent",
105             getTestComponent(getTestDescriptor("TEST", "java.lang.Object")));
106         UMOMessage message = new MuleMessage(payload);
107 
108         assertTrue(xmlSplitter.isMatch(message));
109         final ItemNodeConstraint itemNodeConstraint = new ItemNodeConstraint();
110         session.expect("dispatchEvent", C.args(itemNodeConstraint, C.eq(endpoint1)));
111         session.expect("dispatchEvent", C.args(itemNodeConstraint, C.eq(endpoint1)));
112         xmlSplitter.route(message, (UMOSession) session.proxy(), false);
113         session.verify();
114 
115         message = new MuleMessage(payload);
116 
117         session.expectAndReturn("sendEvent", C.args(itemNodeConstraint, C.eq(endpoint1)), message);
118         session.expectAndReturn("sendEvent", C.args(itemNodeConstraint, C.eq(endpoint1)), message);
119         UMOMessage result = xmlSplitter.route(message, (UMOSession) session.proxy(), true);
120         assertNotNull(result);
121         assertEquals(message, result);
122         session.verify();
123     }
124 
125     public void testXsdNotFoundThrowsException() throws Exception
126     {
127         final String invalidSchemaLocation = "non-existent.xsd";
128         Mock session = MuleTestUtils.getMockSession();
129 
130         UMOEndpoint endpoint1 = getTestEndpoint("Test1Endpoint", UMOEndpoint.ENDPOINT_TYPE_SENDER);
131         endpoint1.setEndpointURI(new MuleEndpointURI("test://endpointUri.1"));
132 
133         FilteringXmlMessageSplitter splitter = new FilteringXmlMessageSplitter();
134         splitter.setValidateSchema(true);
135         splitter.setExternalSchemaLocation(invalidSchemaLocation);
136 
137         String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
138 
139         UMOMessage message = new MuleMessage(payload);
140 
141         assertTrue(splitter.isMatch(message));
142         try
143         {
144             splitter.route(message, (UMOSession) session.proxy(), false);
145             fail("Should have thrown an exception, because XSD is not found.");
146         }
147         catch (IllegalArgumentException iaex)
148         {
149             assertTrue("Wrong exception?", iaex.getMessage().indexOf(
150                 "Couldn't find schema at " + invalidSchemaLocation) != -1);
151         }
152         session.verify();
153     }
154 
155     public void testUnsupportedTypePayloadIsIgnored() throws Exception
156     {
157         Exception unsupportedPayload = new Exception();
158 
159         Mock session = MuleTestUtils.getMockSession();
160 
161         UMOMessage message = new MuleMessage(unsupportedPayload);
162 
163         assertTrue(xmlSplitter.isMatch(message));
164         xmlSplitter.route(message, (UMOSession) session.proxy(), false);
165         session.verify();
166 
167         message = new MuleMessage(unsupportedPayload);
168 
169         UMOMessage result = xmlSplitter.route(message, (UMOSession) session.proxy(), true);
170         assertNull(result);
171         session.verify();
172     }
173 
174     public void testInvalidXmlPayloadThrowsException() throws Exception
175     {
176         Mock session = MuleTestUtils.getMockSession();
177 
178         FilteringXmlMessageSplitter splitter = new FilteringXmlMessageSplitter();
179 
180         UMOMessage message = new MuleMessage("This is not XML.");
181 
182         try
183         {
184             splitter.route(message, (UMOSession) session.proxy(), false);
185             fail("No exception thrown.");
186         }
187         catch (IllegalArgumentException iaex)
188         {
189             assertTrue("Wrong exception message.", iaex.getMessage().startsWith(
190                 "Failed to initialise the payload: "));
191         }
192 
193     }
194 
195     private class ItemNodeConstraint implements Constraint
196     {
197         public boolean eval(Object o)
198         {
199             final UMOMessage message = (UMOMessage) o;
200             final Object payload = message.getPayload();
201             assertTrue("Wrong class type for node.", payload instanceof Document);
202 
203             // MULE-2963
204             if (xmlSplitter.enableCorrelation == AbstractOutboundRouter.ENABLE_CORRELATION_NEVER)
205             {
206                 assertEquals(-1, message.getCorrelationGroupSize());                
207             }
208             else
209             {
210                 // the purchase order document contains two parts
211                 assertEquals(2, message.getCorrelationGroupSize());
212             }
213 
214             Document node = (Document) payload;
215             final String partNumber = node.getRootElement().attributeValue("partNum");
216             return "872-AA".equals(partNumber) || "926-AA".equals(partNumber);
217         }
218     }
219 }