View Javadoc

1   /*
2    * $Id: CloseStreamOnMuleExceptionTestCase.java 22431 2011-07-18 07:40:35Z dirk.olmes $
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.test.integration.streaming;
12  
13  import org.mule.module.client.MuleClient;
14  import org.mule.module.xml.stax.DelegateXMLStreamReader;
15  import org.mule.module.xml.stax.StaxSource;
16  import org.mule.module.xml.util.XMLUtils;
17  import org.mule.tck.AbstractServiceAndFlowTestCase;
18  import org.mule.util.concurrent.Latch;
19  
20  import java.io.ByteArrayInputStream;
21  import java.io.IOException;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.concurrent.TimeUnit;
25  
26  import javax.xml.stream.XMLInputFactory;
27  import javax.xml.stream.XMLStreamException;
28  import javax.xml.stream.XMLStreamReader;
29  import javax.xml.transform.Source;
30  import javax.xml.transform.sax.SAXSource;
31  import javax.xml.transform.stream.StreamSource;
32  
33  import org.junit.Ignore;
34  import org.junit.Test;
35  import org.junit.runners.Parameterized.Parameters;
36  import org.xml.sax.InputSource;
37  
38  import static org.junit.Assert.assertTrue;
39  
40  public class CloseStreamOnMuleExceptionTestCase extends AbstractServiceAndFlowTestCase
41  {
42      private final int timeoutMs = 3000;
43      private static Latch inputStreamLatch = new Latch();
44      private static Latch streamReaderLatch;
45      private String xmlText = "<test attribute=\"1\"/>";
46      private TestByteArrayInputStream inputStream;
47      private MuleClient client;
48  
49      @Parameters
50      public static Collection<Object[]> parameters()
51      {
52          return Arrays.asList(new Object[][]{
53              {ConfigVariant.SERVICE,
54              "org/mule/test/integration/streaming/close-stream-on-mule-exception-test-service.xml"},
55              {ConfigVariant.FLOW,
56              "org/mule/test/integration/streaming/close-stream-on-mule-exception-test-flow.xml"}});
57      }
58  
59      public CloseStreamOnMuleExceptionTestCase(ConfigVariant variant, String configResources)
60      {
61          super(variant, configResources);
62      }
63  
64      @Override
65      protected void doSetUp() throws Exception
66      {
67          super.doSetUp();
68          client = new MuleClient(muleContext);
69          inputStream = new TestByteArrayInputStream(xmlText.getBytes());
70          streamReaderLatch = new Latch();
71      }
72  
73      @Test
74      public void testCloseStreamOnComponentException() throws Exception
75      {
76          client.dispatch("vm://inEcho?connector=vm", inputStream, null);
77          streamReaderLatch.await(timeoutMs, TimeUnit.MILLISECONDS);
78          assertTrue(inputStream.isClosed());
79      }
80  
81      @Test
82      public void testCloseXMLInputSourceOnComponentException() throws Exception
83      {
84          InputSource stream = new InputSource(inputStream);
85  
86          client.dispatch("vm://inEcho?connector=vm", stream, null);
87  
88          streamReaderLatch.await(timeoutMs, TimeUnit.MILLISECONDS);
89          assertTrue(((TestByteArrayInputStream) stream.getByteStream()).isClosed());
90      }
91  
92      @Test
93      public void testCloseXMLStreamSourceOnComponentException() throws Exception
94      {
95          Source stream = XMLUtils.toXmlSource(XMLInputFactory.newInstance(), false, inputStream);
96  
97          client.dispatch("vm://inEcho?connector=vm", stream, null);
98  
99          streamReaderLatch.await(timeoutMs, TimeUnit.MILLISECONDS);
100         assertTrue(((TestByteArrayInputStream) ((StreamSource) stream).getInputStream()).isClosed());
101     }
102 
103     @Test
104     public void testCloseXMLStreamReaderOnComponentException() throws Exception
105     {
106         TestXMLStreamReader stream = new TestXMLStreamReader(XMLInputFactory.newInstance()
107             .createXMLStreamReader(inputStream));
108 
109         client.dispatch("vm://inEcho?connector=vm", stream, null);
110 
111         streamReaderLatch.await(timeoutMs, TimeUnit.MILLISECONDS);
112         assertTrue(stream.isClosed());
113     }
114 
115     @Test
116     public void testCloseSaxSourceOnComponentException() throws Exception
117     {
118         SAXSource stream = new SAXSource(new InputSource(inputStream));
119 
120         client.dispatch("vm://inEcho?connector=vm", stream, null);
121 
122         Thread.sleep(timeoutMs);
123         assertTrue(((TestByteArrayInputStream) stream.getInputSource().getByteStream()).isClosed());
124     }
125 
126     @Test
127     public void testCloseStaxSourceOnComponentException() throws Exception
128     {
129 
130         StaxSource stream = new StaxSource(new TestXMLStreamReader(XMLInputFactory.newInstance()
131             .createXMLStreamReader(inputStream)));
132 
133         client.dispatch("vm://inEcho?connector=vm", stream, null);
134 
135         Thread.sleep(timeoutMs);
136         assertTrue(((TestXMLStreamReader) stream.getXMLStreamReader()).isClosed());
137     }
138 
139     @Test
140     public void testCloseStreamOnDispatcherException() throws Exception
141     {
142         client.dispatch("vm://dispatcherExceptionBridge?connector=vm", inputStream, null);
143         Thread.sleep(timeoutMs);
144         assertTrue(inputStream.isClosed());
145     }
146 
147     // TODO MULE-3558 Streams are not closed if there are exceptions in the message
148     // receiver. Protocol/Transport workers should clean up after themselves if there
149     // is an error (MULE-3559) but exceptions thrown by AbstractMessageReciever will
150     // not result in stream being closed. These exceptions result in
151     // exceptionStrategy being called but because RequestContext is empty the message
152     // is not available in the AbstractExceptionListener and cannot be closed.
153     @Ignore
154     @Test
155     public void testCloseStreamOnInboundFilterException() throws Exception
156     {
157         client.dispatch("vm://inboundFilterExceptionBridge?connector=vm", inputStream, null);
158 
159         Thread.sleep(1000);
160 
161         assertTrue(inputStream.isClosed());
162     }
163 
164     static class TestByteArrayInputStream extends ByteArrayInputStream
165     {
166         private boolean closed;
167 
168         public boolean isClosed()
169         {
170             return closed;
171         }
172 
173         public TestByteArrayInputStream(byte[] arg0)
174         {
175             super(arg0);
176         }
177 
178         public TestByteArrayInputStream(byte[] buf, int offset, int length)
179         {
180             super(buf, offset, length);
181         }
182 
183         @Override
184         public void close() throws IOException
185         {
186             super.close();
187             closed = true;
188             inputStreamLatch.countDown();
189         }
190     }
191 
192     static class TestXMLStreamReader extends DelegateXMLStreamReader
193     {
194         private boolean closed;
195 
196         public boolean isClosed()
197         {
198             return closed;
199         }
200 
201         public TestXMLStreamReader(XMLStreamReader reader)
202         {
203             super(reader);
204         }
205 
206         @Override
207         public void close() throws XMLStreamException
208         {
209             super.close();
210             closed = true;
211             streamReaderLatch.countDown();
212         }
213     }
214 }