1   /*
2    * $Id: RoundRobinXmlSplitterTestCase.java 10524 2008-01-24 19:20:11Z akuzmin $
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 RoundRobinXmlSplitterTestCase extends AbstractMuleTestCase
33  {
34      private UMOEndpoint endpoint1;
35      private UMOEndpoint endpoint2;
36      private UMOEndpoint endpoint3;
37      private RoundRobinXmlSplitter 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 RoundRobinXmlSplitter();
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-order2.xml", getClass());
70          internalTestSuccessfulXmlSplitter(payload);
71      }
72  
73      public void testDom4JDocumentPayloadXmlMessageSplitter() throws Exception
74      {
75          String payload = IOUtils.getResourceAsString("purchase-order2.xml", getClass());
76          Document doc = DocumentHelper.parseText(payload);
77          internalTestSuccessfulXmlSplitter(doc);
78      }
79  
80      public void testByteArrayPayloadXmlMessageSplitter() throws Exception
81      {
82          String payload = IOUtils.getResourceAsString("purchase-order2.xml", getClass());
83          internalTestSuccessfulXmlSplitter(payload.getBytes());
84      }
85  
86      private void internalTestSuccessfulXmlSplitter(Object payload) throws Exception
87      {
88          Mock session = MuleTestUtils.getMockSession();
89          session.matchAndReturn("getComponent", getTestComponent(getTestDescriptor("TEST", "java.lang.Object")));
90          UMOMessage message = new MuleMessage(payload);
91  
92          assertTrue(xmlSplitter.isMatch(message));
93          final RoundRobinXmlSplitterTestCase.ItemNodeConstraint itemNodeConstraint = new RoundRobinXmlSplitterTestCase.ItemNodeConstraint();
94          session.expect("dispatchEvent", C.args(itemNodeConstraint, C.eq(endpoint1)));
95          session.expect("dispatchEvent", C.args(itemNodeConstraint, C.eq(endpoint2)));
96          session.expect("dispatchEvent", C.args(itemNodeConstraint, C.eq(endpoint3)));
97          session.expect("dispatchEvent", C.args(itemNodeConstraint, C.eq(endpoint1)));
98          xmlSplitter.route(message, (UMOSession)session.proxy(), false);
99          session.verify();
100 
101         message = new MuleMessage(payload);
102 
103         session.expectAndReturn("sendEvent", C.args(itemNodeConstraint, C.eq(endpoint1)), message);
104         session.expectAndReturn("sendEvent", C.args(itemNodeConstraint, C.eq(endpoint2)), message);
105         session.expectAndReturn("sendEvent", C.args(itemNodeConstraint, C.eq(endpoint3)), message);
106         session.expectAndReturn("sendEvent", C.args(itemNodeConstraint, C.eq(endpoint1)), message);
107         UMOMessage result = xmlSplitter.route(message, (UMOSession)session.proxy(), true);
108         assertNotNull(result);
109         assertEquals(message, result);
110         session.verify();
111     }
112 
113     public void testXsdNotFoundThrowsException() throws Exception
114     {
115         final String invalidSchemaLocation = "non-existent.xsd";
116         Mock session = MuleTestUtils.getMockSession();
117         session.matchAndReturn("getComponent", getTestComponent(getTestDescriptor("TEST", "java.lang.Object")));
118         UMOEndpoint endpoint1 = getTestEndpoint("Test1Endpoint", UMOEndpoint.ENDPOINT_TYPE_SENDER);
119         endpoint1.setEndpointURI(new MuleEndpointURI("test://endpointUri.1"));
120 
121         RoundRobinXmlSplitter splitter = new RoundRobinXmlSplitter();
122         splitter.setValidateSchema(true);
123         splitter.setExternalSchemaLocation(invalidSchemaLocation);
124 
125         String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
126 
127         UMOMessage message = new MuleMessage(payload);
128 
129         assertTrue(splitter.isMatch(message));
130         try
131         {
132             splitter.route(message, (UMOSession)session.proxy(), false);
133             fail("Should have thrown an exception, because XSD is not found.");
134         }
135         catch (IllegalArgumentException iaex)
136         {
137             assertTrue("Wrong exception?", iaex.getMessage().indexOf(
138                 "Couldn't find schema at " + invalidSchemaLocation) != -1);
139         }
140         session.verify();
141     }
142 
143     public void testUnsupportedTypePayloadIsIgnored() throws Exception
144     {
145         Exception unsupportedPayload = new Exception();
146 
147         Mock session = MuleTestUtils.getMockSession();
148         session.matchAndReturn("getComponent", getTestComponent(getTestDescriptor("TEST", "java.lang.Object")));
149         UMOMessage message = new MuleMessage(unsupportedPayload);
150 
151         assertTrue(xmlSplitter.isMatch(message));
152         xmlSplitter.route(message, (UMOSession)session.proxy(), false);
153         session.verify();
154 
155         message = new MuleMessage(unsupportedPayload);
156 
157         UMOMessage result = xmlSplitter.route(message, (UMOSession)session.proxy(), true);
158         assertNull(result);
159         session.verify();
160     }
161 
162     public void testInvalidXmlPayloadThrowsException() throws Exception
163     {
164         Mock session = MuleTestUtils.getMockSession();
165         session.matchAndReturn("getComponent", getTestComponent(getTestDescriptor("TEST", "java.lang.Object")));
166         RoundRobinXmlSplitter splitter = new RoundRobinXmlSplitter();
167 
168         UMOMessage message = new MuleMessage("This is not XML.");
169 
170         try
171         {
172             splitter.route(message, (UMOSession)session.proxy(), false);
173             fail("No exception thrown.");
174         }
175         catch (IllegalArgumentException iaex)
176         {
177             assertTrue("Wrong exception message.", iaex.getMessage().startsWith(
178                 "Failed to initialise the payload: "));
179         }
180 
181     }
182 
183     private class ItemNodeConstraint implements Constraint
184     {
185         public boolean eval(Object o)
186         {
187             final UMOMessage message = (UMOMessage)o;
188             final Object payload = message.getPayload();
189             assertTrue("Wrong class type for node.", payload instanceof Document);
190 
191             Document node = (Document)payload;
192 
193             final String partNumber = node.getRootElement().attributeValue("partNum");
194 
195             return "872-AA".equals(partNumber) || "926-AA".equals(partNumber) || "126-AA".equals(partNumber)
196                    || "226-AA".equals(partNumber);
197         }
198     }
199 }