1
2
3
4
5
6
7
8
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.config.MuleProperties;
19 import org.mule.api.endpoint.OutboundEndpoint;
20 import org.mule.module.xml.routing.XmlMessageSplitter;
21 import org.mule.module.xml.util.NamespaceManager;
22 import org.mule.module.xml.util.XMLUtils;
23 import org.mule.routing.CorrelationMode;
24 import org.mule.tck.AbstractMuleTestCase;
25 import org.mule.tck.MuleTestUtils;
26 import org.mule.util.IOUtils;
27
28 import com.mockobjects.constraint.Constraint;
29 import com.mockobjects.dynamic.Mock;
30
31 import java.util.HashMap;
32 import java.util.Map;
33
34 import javax.xml.stream.XMLInputFactory;
35 import javax.xml.transform.Source;
36 import javax.xml.transform.Transformer;
37 import javax.xml.transform.dom.DOMResult;
38
39 import org.dom4j.Document;
40 import org.dom4j.DocumentHelper;
41
42 public class XmlMessageSplitterTestCase extends AbstractMuleTestCase
43 {
44 private OutboundEndpoint endpoint1;
45 private OutboundEndpoint endpoint2;
46 private OutboundEndpoint endpoint3;
47 private OutboundEndpoint endpoint4;
48 private OutboundEndpoint endpoint5;
49 private OutboundEndpoint endpoint6;
50 private Mock mockendpoint1;
51 private Mock mockendpoint2;
52 private Mock mockendpoint3;
53 private Mock mockendpoint4;
54 private Mock mockendpoint5;
55 private Mock mockendpoint6;
56 private XmlMessageSplitter asyncXmlSplitter;
57 private XmlMessageSplitter syncXmlSplitter;
58
59 @Override
60 protected void doSetUp() throws Exception
61 {
62
63 endpoint1 = getTestOutboundEndpoint("Test1Endpoint", "test://endpointUri.1");
64 endpoint2 = getTestOutboundEndpoint("Test2Endpoint", "test://endpointUri.2");
65 endpoint3 = getTestOutboundEndpoint("Test3Endpoint", "test://endpointUri.3");
66 mockendpoint1 = RouterTestUtils.getMockEndpoint(endpoint1);
67 mockendpoint2 = RouterTestUtils.getMockEndpoint(endpoint2);
68 mockendpoint3 = RouterTestUtils.getMockEndpoint(endpoint3);
69
70
71 endpoint4 = getTestOutboundEndpoint("Test1Endpoint", "test://endpointUri.1?exchangePattern=request-response");
72 endpoint5 = getTestOutboundEndpoint("Test2Endpoint", "test://endpointUri.2?exchangePattern=request-response");
73 endpoint6 = getTestOutboundEndpoint("Test3Endpoint", "test://endpointUri.3?exchangePattern=request-response");
74 mockendpoint4 = RouterTestUtils.getMockEndpoint(endpoint4);
75 mockendpoint5 = RouterTestUtils.getMockEndpoint(endpoint5);
76 mockendpoint6 = RouterTestUtils.getMockEndpoint(endpoint6);
77
78
79 syncXmlSplitter = new XmlMessageSplitter();
80 syncXmlSplitter.setValidateSchema(true);
81 syncXmlSplitter.setExternalSchemaLocation("purchase-order.xsd");
82
83
84
85
86 Map namespaces = new HashMap();
87 namespaces.put("e", "http://www.example.com");
88 syncXmlSplitter.setSplitExpression("/e:purchaseOrder/e:items/e:item");
89 syncXmlSplitter.setNamespaces(namespaces);
90 syncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint4.proxy());
91 syncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint5.proxy());
92 syncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint6.proxy());
93
94
95 asyncXmlSplitter = new XmlMessageSplitter();
96 asyncXmlSplitter.setValidateSchema(true);
97 asyncXmlSplitter.setExternalSchemaLocation("purchase-order.xsd");
98
99 asyncXmlSplitter.setSplitExpression("/e:purchaseOrder/e:items/e:item");
100 asyncXmlSplitter.setNamespaces(namespaces);
101 asyncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint1.proxy());
102 asyncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint2.proxy());
103 asyncXmlSplitter.addRoute((OutboundEndpoint) mockendpoint3.proxy());
104
105 syncXmlSplitter.setMuleContext(muleContext);
106 asyncXmlSplitter.setMuleContext(muleContext);
107 syncXmlSplitter.initialise();
108 asyncXmlSplitter.initialise();
109 }
110
111 public void testStringPayloadXmlMessageSplitter() throws Exception
112 {
113 String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
114 internalTestSuccessfulXmlSplitter(payload);
115 }
116
117 public void testStringPayloadXmlMessageSplitterWithoutXsd() throws Exception
118 {
119 syncXmlSplitter.setExternalSchemaLocation(null);
120 syncXmlSplitter.setValidateSchema(false);
121 String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
122 internalTestSuccessfulXmlSplitter(payload);
123 }
124
125 public void testDom4JDocumentPayloadXmlMessageSplitter() throws Exception
126 {
127 String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
128 Document doc = DocumentHelper.parseText(payload);
129 internalTestSuccessfulXmlSplitter(doc);
130 }
131
132 public void testW3CDocumentPayloadXmlMessageSplitter() throws Exception
133 {
134 String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
135 Source sourceDoc = XMLUtils.toXmlSource( XMLInputFactory.newInstance(), true, payload);
136 DOMResult result = new DOMResult();
137 Transformer transformer = XMLUtils.getTransformer();
138 transformer.transform(sourceDoc, result);
139 internalTestSuccessfulXmlSplitter(result.getNode());
140 }
141
142 public void testByteArrayPayloadXmlMessageSplitter() throws Exception
143 {
144 String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
145 internalTestSuccessfulXmlSplitter(payload.getBytes());
146 }
147
148 public void testByteArrayPayloadCorrelateNever() throws Exception
149 {
150 String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
151 syncXmlSplitter.setEnableCorrelation(CorrelationMode.NEVER);
152 asyncXmlSplitter.setEnableCorrelation(CorrelationMode.NEVER);
153 internalTestSuccessfulXmlSplitter(payload.getBytes());
154 }
155
156 private void internalTestSuccessfulXmlSplitter(Object payload) throws Exception
157 {
158 Mock session = MuleTestUtils.getMockSession();
159 session.matchAndReturn("getFlowConstruct", getTestService());
160 session.matchAndReturn("setFlowConstruct", RouterTestUtils.getArgListCheckerFlowConstruct(), null);
161 MuleMessage message = new DefaultMuleMessage(payload, muleContext);
162
163 assertTrue(asyncXmlSplitter.isMatch(message));
164 final ItemNodeConstraint itemNodeConstraint = new ItemNodeConstraint();
165 mockendpoint1.expect("process", RouterTestUtils.getArgListCheckerMuleEvent());
166 mockendpoint2.expect("process", RouterTestUtils.getArgListCheckerMuleEvent());
167 asyncXmlSplitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
168 mockendpoint1.verify();
169 mockendpoint2.verify();
170
171 message = new DefaultMuleMessage(payload, muleContext);
172 MuleEvent event = new OutboundRoutingTestEvent(message, null);
173 mockendpoint4.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
174 mockendpoint5.expectAndReturn("process", RouterTestUtils.getArgListCheckerMuleEvent(), event);
175 MuleEvent result = syncXmlSplitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
176 MuleMessage resultMessage = result.getMessage();
177 assertNotNull(resultMessage);
178 assertNotNull(result);
179 assertTrue(resultMessage instanceof MuleMessageCollection);
180 assertEquals(2, ((MuleMessageCollection) resultMessage).size());
181 mockendpoint4.verify();
182 mockendpoint5.verify();
183 }
184
185 public void testXsdNotFoundThrowsException() throws Exception
186 {
187 final String invalidSchemaLocation = "non-existent.xsd";
188 Mock session = MuleTestUtils.getMockSession();
189 session.matchAndReturn("getFlowConstruct", getTestService());
190
191 XmlMessageSplitter splitter = new XmlMessageSplitter();
192 splitter.setValidateSchema(true);
193 splitter.setExternalSchemaLocation(invalidSchemaLocation);
194
195 String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
196
197 MuleMessage message = new DefaultMuleMessage(payload, muleContext);
198
199 assertTrue(splitter.isMatch(message));
200 try
201 {
202 splitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
203 fail("Should have thrown an exception, because XSD is not found.");
204 }
205 catch (IllegalArgumentException iaex)
206 {
207 assertTrue("Wrong exception?", iaex.getMessage().indexOf(
208 "Couldn't find schema at " + invalidSchemaLocation) != -1);
209 }
210 session.verify();
211 }
212
213
214 public void testInvalidPayloadTypeThrowsException() throws Exception
215 {
216 Mock session = MuleTestUtils.getMockSession();
217 session.matchAndReturn("getFlowConstruct", getTestService());
218
219 XmlMessageSplitter splitter = new XmlMessageSplitter();
220
221 MuleMessage message = new DefaultMuleMessage(new Exception(), muleContext);
222
223 try
224 {
225 splitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
226 fail("No exception thrown.");
227 }
228 catch (IllegalArgumentException iaex)
229 {
230 assertTrue("Wrong exception message.", iaex.getMessage().startsWith(
231 "Failed to initialise the payload: "));
232 }
233
234 }
235
236 public void testInvalidXmlPayloadThrowsException() throws Exception
237 {
238 Mock session = MuleTestUtils.getMockSession();
239 session.matchAndReturn("getFlowConstruct", getTestService());
240
241 XmlMessageSplitter splitter = new XmlMessageSplitter();
242
243 MuleMessage message = new DefaultMuleMessage("This is not XML.", muleContext);
244
245 try
246 {
247 splitter.route(new OutboundRoutingTestEvent(message, (MuleSession) session.proxy()));
248 fail("No exception thrown.");
249 }
250 catch (IllegalArgumentException iaex)
251 {
252 assertTrue("Wrong exception message.", iaex.getMessage().startsWith(
253 "Failed to initialise the payload: "));
254 }
255
256 }
257
258 public void testGlobalNamespaceManagerLookup() throws Exception
259 {
260
261 syncXmlSplitter.setNamespaces(null);
262 asyncXmlSplitter.setNamespaces(null);
263
264
265 NamespaceManager namespaceManager = muleContext.getRegistry().lookupObject(NamespaceManager.class);
266 if (namespaceManager == null)
267 {
268 namespaceManager = new NamespaceManager();
269 muleContext.getRegistry().registerObject(MuleProperties.OBJECT_MULE_NAMESPACE_MANAGER, namespaceManager);
270 }
271 Map namespaces = new HashMap();
272 namespaces.put("e", "http://www.example.com");
273 syncXmlSplitter.setSplitExpression("/e:purchaseOrder/e:items/e:item");
274 asyncXmlSplitter.setSplitExpression("/e:purchaseOrder/e:items/e:item");
275 namespaceManager.setNamespaces(namespaces);
276
277
278 syncXmlSplitter.initialise();
279 asyncXmlSplitter.initialise();
280
281 String payload = IOUtils.getResourceAsString("purchase-order.xml", getClass());
282 internalTestSuccessfulXmlSplitter(payload);
283 }
284
285 private class ItemNodeConstraint implements Constraint
286 {
287 public boolean eval(Object o)
288 {
289 final MuleMessage message = (MuleMessage) o;
290 final Object payload = message.getPayload();
291 assertTrue("Wrong class type for node.", payload instanceof Document);
292
293
294 if (syncXmlSplitter.enableCorrelation == CorrelationMode.NEVER
295 || asyncXmlSplitter.enableCorrelation == CorrelationMode.NEVER)
296 {
297 assertEquals(-1, message.getCorrelationGroupSize());
298 }
299 else
300 {
301
302 assertEquals(2, message.getCorrelationGroupSize());
303 }
304
305 Document node = (Document) payload;
306 final String partNumber = node.getRootElement().attributeValue("partNum");
307 return "872-AA".equals(partNumber) || "926-AA".equals(partNumber);
308 }
309 }
310 }