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