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