View Javadoc

1   /*
2    * $Id: RoundRobinXmlSplitterTestCase.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.DefaultMuleMessage;
14  import org.mule.api.MuleEvent;
15  import org.mule.api.MuleMessage;
16  import org.mule.api.MuleMessageCollection;
17  import org.mule.api.MuleSession;
18  import org.mule.api.endpoint.OutboundEndpoint;
19  import org.mule.module.xml.routing.XmlMessageSplitter;
20  import org.mule.tck.AbstractMuleTestCase;
21  import org.mule.tck.MuleTestUtils;
22  import org.mule.util.IOUtils;
23  
24  import com.mockobjects.constraint.Constraint;
25  import com.mockobjects.dynamic.Mock;
26  
27  import java.util.HashMap;
28  import java.util.Map;
29  
30  import org.dom4j.Document;
31  import org.dom4j.DocumentHelper;
32  
33  public class RoundRobinXmlSplitterTestCase extends AbstractMuleTestCase
34  {
35      private OutboundEndpoint endpoint1;
36      private OutboundEndpoint endpoint2;
37      private OutboundEndpoint endpoint3;
38      private OutboundEndpoint endpoint4;
39      private OutboundEndpoint endpoint5;
40      private OutboundEndpoint endpoint6;
41      private Mock mockendpoint1;
42      private Mock mockendpoint2;
43      private Mock mockendpoint3;
44      private Mock mockendpoint4;
45      private Mock mockendpoint5;
46      private Mock mockendpoint6;
47      private XmlMessageSplitter asyncXmlSplitter;
48      private XmlMessageSplitter syncXmlSplitter;
49  
50      @Override
51      protected void doSetUp() throws Exception
52      {
53          // setup async targets
54          endpoint1 = getTestOutboundEndpoint("Test1Endpoint", "test://endpointUri.1");
55          endpoint2 = getTestOutboundEndpoint("Test2Endpoint", "test://endpointUri.2");
56          endpoint3 = getTestOutboundEndpoint("Test3Endpoint", "test://endpointUri.3");
57          mockendpoint1 = RouterTestUtils.getMockEndpoint(endpoint1);
58          mockendpoint2 = RouterTestUtils.getMockEndpoint(endpoint2);
59          mockendpoint3 = RouterTestUtils.getMockEndpoint(endpoint3);
60  
61          // setup sync targets
62          endpoint4 = getTestOutboundEndpoint("Test4Endpoint", "test://endpointUri.4?exchangePattern=request-response");
63          endpoint5 = getTestOutboundEndpoint("Test5Endpoint", "test://endpointUri.5?exchangePattern=request-response");
64          endpoint6 = getTestOutboundEndpoint("Test6Endpoint", "test://endpointUri.6?exchangePattern=request-response");
65          mockendpoint4 = RouterTestUtils.getMockEndpoint(endpoint4);
66          mockendpoint5 = RouterTestUtils.getMockEndpoint(endpoint5);
67          mockendpoint6 = RouterTestUtils.getMockEndpoint(endpoint6);
68  
69          // setup async splitter
70          asyncXmlSplitter = new XmlMessageSplitter();
71          asyncXmlSplitter.setValidateSchema(true);
72          asyncXmlSplitter.setExternalSchemaLocation("purchase-order.xsd");
73          asyncXmlSplitter.setMuleContext(muleContext);
74  
75          // The xml document declares a default namespace, thus
76          // we need to workaround it by specifying it both in
77          // the namespaces and in the splitExpression
78          Map namespaces = new HashMap();
79          namespaces.put("e", "http://www.example.com");
80          asyncXmlSplitter.setSplitExpression("/e:purchaseOrder/e:items/e:item");
81          asyncXmlSplitter.setNamespaces(namespaces);
82          asyncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint1.proxy());
83          asyncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint2.proxy());
84          asyncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint3.proxy());
85  
86          // setup sync splitter
87          syncXmlSplitter = new XmlMessageSplitter();
88          syncXmlSplitter.setMuleContext(muleContext);
89          syncXmlSplitter.setValidateSchema(true);
90          syncXmlSplitter.setExternalSchemaLocation("purchase-order.xsd");
91          syncXmlSplitter.setSplitExpression("/e:purchaseOrder/e:items/e:item");
92  
93          syncXmlSplitter.setNamespaces(namespaces);
94          syncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint4.proxy());
95          syncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint5.proxy());
96          syncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint6.proxy());
97      }
98  
99      public void testStringPayloadXmlMessageSplitter() throws Exception
100     {
101         String payload = IOUtils.getResourceAsString("purchase-order2.xml", getClass());
102         internalTestSuccessfulXmlSplitter(payload);
103     }
104 
105     public void testDom4JDocumentPayloadXmlMessageSplitter() throws Exception
106     {
107         String payload = IOUtils.getResourceAsString("purchase-order2.xml", getClass());
108         Document doc = DocumentHelper.parseText(payload);
109         internalTestSuccessfulXmlSplitter(doc);
110     }
111 
112     public void testByteArrayPayloadXmlMessageSplitter() throws Exception
113     {
114         String payload = IOUtils.getResourceAsString("purchase-order2.xml", getClass());
115         internalTestSuccessfulXmlSplitter(payload.getBytes());
116     }
117 
118     private void internalTestSuccessfulXmlSplitter(Object payload) throws Exception
119     {
120         Mock session = MuleTestUtils.getMockSession();
121         session.matchAndReturn("getFlowConstruct", getTestService());
122         session.matchAndReturn("setFlowConstruct", RouterTestUtils.getArgListCheckerFlowConstruct(), null);
123         MuleMessage message = new DefaultMuleMessage(payload, muleContext);
124 
125         assertTrue(asyncXmlSplitter.isMatch(message));
126         final RoundRobinXmlSplitterTestCase.ItemNodeConstraint itemNodeConstraint = new RoundRobinXmlSplitterTestCase.ItemNodeConstraint();
127         mockendpoint1.expect("process", RouterTestUtils.getArgListCheckerMuleEvent());
128         mockendpoint2.expect("process", RouterTestUtils.getArgListCheckerMuleEvent());
129         mockendpoint3.expect("process", RouterTestUtils.getArgListCheckerMuleEvent());
130         mockendpoint1.expect("process", RouterTestUtils.getArgListCheckerMuleEvent());
131         asyncXmlSplitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
132         mockendpoint1.verify();
133         mockendpoint2.verify();
134         mockendpoint3.verify();
135 
136         message = new DefaultMuleMessage(payload, muleContext);
137         MuleEvent event = new OutboundRoutingTestEvent(message, null);
138         assertTrue(syncXmlSplitter.isMatch(message));
139         mockendpoint4.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
140         mockendpoint5.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
141         mockendpoint6.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
142         mockendpoint4.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
143         MuleEvent result = syncXmlSplitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
144         MuleMessage resultMessage = result.getMessage();
145         assertNotNull(resultMessage);
146         assertNotNull(result);
147         assertTrue(resultMessage instanceof MuleMessageCollection);
148         assertEquals(4, ((MuleMessageCollection) resultMessage).size());
149         mockendpoint4.verify();
150         mockendpoint5.verify();
151         mockendpoint6.verify();
152     }
153 
154     public void testXsdNotFoundThrowsException() throws Exception
155     {
156         final String invalidSchemaLocation = "non-existent.xsd";
157         Mock session = MuleTestUtils.getMockSession();
158         session.matchAndReturn("getFlowConstruct", getTestService());
159 
160         XmlMessageSplitter splitter = new XmlMessageSplitter();
161         splitter.setValidateSchema(true);
162         splitter.setExternalSchemaLocation(invalidSchemaLocation);
163         splitter.setMuleContext(muleContext);
164         String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
165 
166         MuleMessage message = new DefaultMuleMessage(payload, muleContext);
167 
168         assertTrue(splitter.isMatch(message));
169         try
170         {
171             splitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
172             fail("Should have thrown an exception, because XSD is not found.");
173         }
174         catch (IllegalArgumentException iaex)
175         {
176             assertTrue("Wrong exception?", iaex.getMessage().indexOf(
177                     "Couldn't find schema at " + invalidSchemaLocation) != -1);
178         }
179         session.verify();
180     }
181 
182 
183     public void testInvalidXmlPayloadThrowsException() throws Exception
184     {
185         Mock session = MuleTestUtils.getMockSession();
186         session.matchAndReturn("getFlowConstruct", getTestService());
187 
188         XmlMessageSplitter splitter = new XmlMessageSplitter();
189         splitter.setMuleContext(muleContext);      
190         MuleMessage message = new DefaultMuleMessage("This is not XML.", muleContext);
191 
192         try
193         {
194             splitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
195             fail("No exception thrown.");
196         }
197         catch (IllegalArgumentException iaex)
198         {
199             assertTrue("Wrong exception message.", iaex.getMessage().startsWith(
200                     "Failed to initialise the payload: "));
201         }
202 
203     }
204 
205     private class ItemNodeConstraint implements Constraint
206     {
207         public boolean eval(Object o)
208         {
209             final MuleMessage message = (MuleMessage) o;
210             final Object payload = message.getPayload();
211             assertTrue("Wrong class type for node.", payload instanceof Document);
212 
213             Document node = (Document) payload;
214 
215             final String partNumber = node.getRootElement().attributeValue("partNum");
216 
217             return "872-AA".equals(partNumber) || "926-AA".equals(partNumber) || "126-AA".equals(partNumber)
218                     || "226-AA".equals(partNumber);
219         }
220     }
221 }