Author: veithen Date: Sun Oct 31 15:09:18 2010 New Revision: 1029377 URL: http://svn.apache.org/viewvc?rev=1029377&view=rev Log: AXIS2-4752: Added a regression test and modified SOAPConnectionImpl to ensure proper cleanup in all cases, in particular if the service returns a SOAP fault.
Modified: axis/axis2/java/core/trunk/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java axis/axis2/java/core/trunk/modules/saaj/test/org/apache/axis2/saaj/integration/IntegrationTest.java Modified: axis/axis2/java/core/trunk/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java?rev=1029377&r1=1029376&r2=1029377&view=diff ============================================================================== --- axis/axis2/java/core/trunk/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java (original) +++ axis/axis2/java/core/trunk/modules/saaj/src/org/apache/axis2/saaj/SOAPConnectionImpl.java Sun Oct 31 15:09:18 2010 @@ -79,7 +79,6 @@ public class SOAPConnectionImpl extends private boolean closed = false; private final ConfigurationContext configurationContext; - private ServiceClient serviceClient; SOAPConnectionImpl() throws SOAPException { // Create a new ConfigurationContext that will be used by all ServiceClient instances. @@ -134,6 +133,7 @@ public class SOAPConnectionImpl extends options.setTo(new EndpointReference(url.toString())); // initialize the Sender + ServiceClient serviceClient; OperationClient opClient; try { serviceClient = new ServiceClient(configurationContext, null); @@ -197,35 +197,38 @@ public class SOAPConnectionImpl extends requestMsgCtx.setProperty(HTTPConstants.HTTP_HEADERS, httpHeaders); } - MessageContext responseMsgCtx; try { - requestMsgCtx.setEnvelope(envelope); - opClient.addMessageContext(requestMsgCtx); - opClient.execute(true); - responseMsgCtx = - opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE); - } catch (AxisFault ex) { - throw new SOAPException(ex.getMessage(), ex); - } - - SOAPMessage response = getSOAPMessage(responseMsgCtx.getEnvelope()); - Attachments attachments = requestMsgCtx.getAttachmentMap(); - for (String contentId : attachments.getAllContentIDs()) { - if (!contentId.equals(attachments.getSOAPPartContentID())) { - AttachmentPart ap = response.createAttachmentPart( - attachments.getDataHandler(contentId)); - ap.setContentId(contentId); - response.addAttachmentPart(ap); + MessageContext responseMsgCtx; + try { + requestMsgCtx.setEnvelope(envelope); + opClient.addMessageContext(requestMsgCtx); + opClient.execute(true); + responseMsgCtx = + opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE); + } catch (AxisFault ex) { + throw new SOAPException(ex.getMessage(), ex); + } + + SOAPMessage response = getSOAPMessage(responseMsgCtx.getEnvelope()); + Attachments attachments = requestMsgCtx.getAttachmentMap(); + for (String contentId : attachments.getAllContentIDs()) { + if (!contentId.equals(attachments.getSOAPPartContentID())) { + AttachmentPart ap = response.createAttachmentPart( + attachments.getDataHandler(contentId)); + ap.setContentId(contentId); + response.addAttachmentPart(ap); + } + } + + return response; + } finally { + try { + serviceClient.cleanupTransport(); + serviceClient.cleanup(); + } catch (AxisFault ex) { + throw new SOAPException(ex); } } - - try { - requestMsgCtx.getTransportOut().getSender().cleanup(requestMsgCtx); - } catch (AxisFault axisFault) { - // log error - } - - return response; } private static boolean isMTOM(SOAPMessage soapMessage) { @@ -270,16 +273,14 @@ public class SOAPConnectionImpl extends * already closed */ public void close() throws SOAPException { - if (serviceClient != null) { - try { - serviceClient.cleanup(); - } catch (AxisFault axisFault) { - throw new SOAPException(axisFault.getMessage()); - } - } if (closed) { throw new SOAPException("SOAPConnection Closed"); } + try { + configurationContext.terminate(); + } catch (AxisFault axisFault) { + throw new SOAPException(axisFault.getMessage()); + } closed = true; } Modified: axis/axis2/java/core/trunk/modules/saaj/test/org/apache/axis2/saaj/integration/IntegrationTest.java URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/saaj/test/org/apache/axis2/saaj/integration/IntegrationTest.java?rev=1029377&r1=1029376&r2=1029377&view=diff ============================================================================== --- axis/axis2/java/core/trunk/modules/saaj/test/org/apache/axis2/saaj/integration/IntegrationTest.java (original) +++ axis/axis2/java/core/trunk/modules/saaj/test/org/apache/axis2/saaj/integration/IntegrationTest.java Sun Oct 31 15:09:18 2010 @@ -38,6 +38,7 @@ import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; +import org.w3c.dom.Element; import org.w3c.dom.Node; import javax.activation.DataHandler; @@ -76,6 +77,9 @@ public class IntegrationTest extends Ass System.getProperty("basedir", ".") + "/" + "target/test-classes/saaj-repo"; private String lastSoapAction; // Stores the last SOAP action received by the server + + // Set this to true to let the Echo service trigger a SOAPFault + private boolean triggerFault; protected static String getAddress() { return "http://127.0.0.1:" + @@ -105,17 +109,21 @@ public class IntegrationTest extends Ass throws AxisFault { lastSoapAction = inMessage.getSoapAction(); - outMessage.setEnvelope(inMessage.getEnvelope()); - Attachments inAttachments = inMessage.getAttachmentMap(); - Attachments outAttachments = outMessage.getAttachmentMap(); - for (String contentId : inAttachments.getAllContentIDs()) { - if (!contentId.equals(inAttachments.getSOAPPartContentID())) { - outAttachments.addDataHandler(contentId, - inAttachments.getDataHandler(contentId)); + if (triggerFault) { + throw new AxisFault("Triggered SOAP fault as requested"); + } else { + outMessage.setEnvelope(inMessage.getEnvelope()); + Attachments inAttachments = inMessage.getAttachmentMap(); + Attachments outAttachments = outMessage.getAttachmentMap(); + for (String contentId : inAttachments.getAllContentIDs()) { + if (!contentId.equals(inAttachments.getSOAPPartContentID())) { + outAttachments.addDataHandler(contentId, + inAttachments.getDataHandler(contentId)); + } } + outMessage.setDoingSwA(inMessage.isDoingSwA()); + outMessage.setDoingMTOM(inMessage.isDoingMTOM()); } - outMessage.setDoingSwA(inMessage.isDoingSwA()); - outMessage.setDoingMTOM(inMessage.isDoingMTOM()); } }; UtilServer.deployService( @@ -370,4 +378,40 @@ public class IntegrationTest extends Ass AttachmentPart ap = response.getAttachment((SOAPElement)textElement.getChildNodes().item(0)); assertNotNull(ap); } + + /** + * Checks that {...@link org.apache.axis2.saaj.SOAPConnectionImpl} correctly performs transport + * cleanup. If there is a problem with transport cleanup, then this test will fail with an error + * caused by a timeout waiting for an available connection. This is a regression test for + * AXIS2-4752. + * + * @throws Exception + */ + @Test + public void testConnectionCleanup() throws Exception { + MessageFactory mf = MessageFactory.newInstance(); + SOAPMessage request = mf.createMessage(); + SOAPBodyElement bodyElement = request.getSOAPBody().addBodyElement(new QName("urn:test", "echo")); + for (int i=0; i<1000; i++) { + bodyElement.addChildElement(new QName("test")).addTextNode("some text"); + } + SOAPConnection conn = SOAPConnectionFactory.newInstance().createConnection(); + for (int i=0; i<100; i++) { + // Let the Echo service trigger a SOAP fault on every second call. This allows us to check + // that the connection cleanup is done correctly also if the response is a SOAP fault. + triggerFault = i % 2 == 0; + if (triggerFault) { + try { + conn.call(request, getAddress()); + fail("Expected SOAPException"); + } catch (SOAPException ex) { + // Expected + } + } else { + SOAPMessage response = conn.call(request, getAddress()); + assertEquals(1000, ((Element)response.getSOAPBody().getFirstChild()).getChildNodes().getLength()); + } + } + conn.close(); + } }