/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.impl.wsdl.support.wsrm; import com.eviware.soapui.SoapUI; import com.eviware.soapui.config.HttpRequestConfig; import com.eviware.soapui.config.WsaConfigConfig; import com.eviware.soapui.config.WsrmConfigConfig; import com.eviware.soapui.config.WsrmVersionTypeConfig; import com.eviware.soapui.impl.support.wsa.WsaRequest; import com.eviware.soapui.impl.wsdl.WsdlOperation; import com.eviware.soapui.impl.wsdl.WsdlRequest; import com.eviware.soapui.impl.wsdl.WsdlSubmit; import com.eviware.soapui.impl.wsdl.WsdlSubmitContext; import com.eviware.soapui.impl.wsdl.support.soap.SoapMessageBuilder; import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils; import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion; import com.eviware.soapui.impl.wsdl.support.wsa.WsaConfig; import com.eviware.soapui.impl.wsdl.support.wsa.WsaContainer; import com.eviware.soapui.impl.wsdl.support.wsa.WsaContainerImpl; import com.eviware.soapui.impl.wsdl.support.wsa.WsaUtils; import com.eviware.soapui.model.iface.Request.SubmitException; import com.eviware.soapui.model.iface.Response; import com.eviware.soapui.model.iface.Submit.Status; import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext; import com.eviware.soapui.support.StringUtils; import com.eviware.soapui.support.xml.XmlUtils; import org.apache.log4j.Logger; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import org.w3c.dom.Element; import org.w3c.dom.Text; import java.util.UUID; public class WsrmUtils { private static final String WSRM_CREATE_SEQUENCE = "CreateSequence"; private static final String WSRM_REQUEST_ACK = "AckRequested"; private static final String WSRM_EXPIRES = "Expires"; private static final String WSRM_ACKNOWLEDGMENTS_TO = "AcksTo"; private static final String WSRM_CLOSE_SEQUENCE = "CloseSequence"; private static final String WSRM_IDENTIFIER = "Identifier"; private static final String WSRM_LAST_MSG = "LastMsgNumber"; private static final String WSRM_CREATE_SEQUENCE_ACTION = "/CreateSequence"; private static final String WSRM_CLOSE_SEQUENCE_ACTION = "/CloseSequence"; private static final String WSRM_TERMINATE_SEQUENCE_ACTION = "/TerminateSequence"; private static final String WSRM_REQUEST_ACK_ACTION = "/AckRequested"; public final static String WSRM_NS_1_0 = "http://schemas.xmlsoap.org/ws/2005/02/rm"; public final static String WSRM_NS_1_1 = "http://docs.oasis-open.org/ws-rx/wsrm/200702"; public final static String WSRM_NS_1_2 = "http://docs.oasis-open.org/ws-rx/wsrm/200702"; private SoapVersion soapVersion; private XmlObject xmlContentObject; private String content; public WsrmUtils(SoapVersion soapVersion) { this.soapVersion = soapVersion; } public WsrmUtils(String content, SoapVersion soapVersion) { this.soapVersion = soapVersion; this.content = content; try { xmlContentObject = XmlUtils.createXmlObject(content); } catch (Exception e) { SoapUI.logError(e); } } public String createNewWSReliableMessagingRequest(WsdlRequest wsrmContainer, String identifier, long msgNumber, String endpoint) { try { Element header = getHeader(); header.setAttribute("xmlns:" + "wsrm", wsrmContainer.getWsrmConfig().getVersionNameSpace()); Element sequence = header.getOwnerDocument().createElementNS( wsrmContainer.getWsrmConfig().getVersionNameSpace(), "Sequence"); Element identifierElement = sequence.getOwnerDocument().createElementNS( wsrmContainer.getWsrmConfig().getVersionNameSpace(), "Identifier"); Text txtElm = identifierElement.getOwnerDocument().createTextNode(identifier); identifierElement.appendChild(txtElm); sequence.appendChild(identifierElement); Element messageId = sequence.getOwnerDocument().createElementNS( wsrmContainer.getWsrmConfig().getVersionNameSpace(), "MessageNumber"); Text txtElm2 = identifierElement.getOwnerDocument().createTextNode(String.valueOf(msgNumber)); messageId.appendChild(txtElm2); sequence.appendChild(messageId); header.appendChild(sequence); content = xmlContentObject.xmlText(); wsrmContainer.getWsaConfig().setWsaEnabled(true); if (wsrmContainer.getWsaConfig().getAction() == null) { wsrmContainer.getWsaConfig().setAddDefaultAction(true); } wsrmContainer.getWsaConfig().setTo(endpoint); wsrmContainer.getWsaConfig().setGenerateMessageId(true); WsaUtils wsaUtils = new WsaUtils(content, wsrmContainer.getOperation().getInterface().getSoapVersion(), null, new DefaultPropertyExpansionContext(wsrmContainer)); content = wsaUtils.addWSAddressingRequest(wsrmContainer); } catch (Exception e) { SoapUI.logError(e); } return content; } private Element getHeader() throws XmlException { return (Element) SoapUtils.getHeaderElement(xmlContentObject, soapVersion, true).getDomNode(); } public WsrmSequence createSequence(String endpoint, SoapVersion soapVersion, String wsrmNamespace, String ackTo, Long expires, WsdlOperation operation, String wsaTo, String offerEndpoint) { String uuid = UUID.randomUUID().toString(); WsaRequest startSequenceRequest = buildStartSequenceRequest(endpoint, soapVersion, wsrmNamespace, ackTo, expires, operation, uuid, offerEndpoint); try { Response response = submitCreateSequenceRequest(uuid, startSequenceRequest); String responseContent = response.getContentAsString(); // XmlObject xml = XmlObject.Factory.parse( responseContent ); XmlObject xml = XmlUtils.createXmlObject(responseContent); XmlCursor cursor = xml.newCursor(); cursor.toFirstContentToken(); cursor.toFirstChild(); cursor.toNextSibling(); cursor.toFirstChild(); cursor.toFirstChild(); String sequenceIdentifier = cursor.getTextValue(); Logger.getLogger("wsrm").info("Sequence response Received, sequence ID: " + sequenceIdentifier); // WsmcInjection receiveInjection = new WsmcInjection(request); // request.setAfterRequestInjection(receiveInjection); return new WsrmSequence(sequenceIdentifier.trim(), uuid, soapVersion, wsrmNamespace, operation); } catch (SubmitException e1) { SoapUI.logError(e1); return null; } catch (XmlException e) { SoapUI.logError(e); return null; } } private Response submitCreateSequenceRequest(String uuid, WsaRequest startSequenceRequest) throws SubmitException { WsdlSubmit wsdlSubmit = startSequenceRequest.submit(new WsdlSubmitContext(null), true); Logger.getLogger("wsrm").info("StartSequence Request Sent: " + uuid); // startSequenceRequest.getWsaConfig().setWsaEnabled(false); while (wsdlSubmit.getStatus() != Status.FINISHED) { wsdlSubmit.waitUntilFinished(); } return wsdlSubmit.getResponse(); } WsaRequest buildStartSequenceRequest(String endpoint, SoapVersion soapVersion, String wsrmNamespace, String ackTo, Long expires, WsdlOperation operation, String uuid, String offerEndpoint) { HttpRequestConfig httpRequestConfig = (HttpRequestConfig) (XmlObject.Factory.newInstance() .changeType(HttpRequestConfig.type)); httpRequestConfig.setEndpoint(endpoint); httpRequestConfig.setMediaType(soapVersion.getContentType()); WsaConfigConfig wsaConfigConfig = (WsaConfigConfig) (XmlObject.Factory.newInstance() .changeType(WsaConfigConfig.type)); WsaContainer wsaContainer = new WsaContainerImpl(); wsaContainer.setOperation(operation); WsaConfig wsaConfig = new WsaConfig(wsaConfigConfig, wsaContainer); wsaConfig.setTo(endpoint); WsrmConfigConfig wsrmConfigConfig = (WsrmConfigConfig) (XmlObject.Factory.newInstance() .changeType(WsrmConfigConfig.type)); WsrmConfig wsrmConfig = new WsrmConfig(wsrmConfigConfig, null); WsaRequest startSequenceRequest = new WsaRequest(httpRequestConfig, wsaConfig, wsrmConfig, false); startSequenceRequest.setOperation(operation); String openSequenceMessageContent = SoapMessageBuilder.buildEmptyMessage(soapVersion); startSequenceRequest.getWsaConfig().setWsaEnabled(true); startSequenceRequest.getWsaConfig().setAction(wsrmNamespace + WSRM_CREATE_SEQUENCE_ACTION); // if (wsaTo == null) { // startSequenceRequest.getWsaConfig().setTo( // WsaUtils.getNamespace(startSequenceRequest.getWsaConfig() // .getVersion()) // + "/anonymous?id="+ uuid); // } else { // startSequenceRequest.getWsaConfig().setTo(wsaTo); // } startSequenceRequest.getWsaConfig().setReplyTo(ackTo); startSequenceRequest.getWsaConfig().setGenerateMessageId(true); try { XmlObject object = XmlUtils.createXmlObject(openSequenceMessageContent); XmlCursor cursor = object.newCursor(); cursor.toFirstContentToken(); cursor.toFirstChild(); cursor.toNextSibling(); cursor.toNextToken(); cursor.insertNamespace("wsrm", wsrmNamespace); cursor.beginElement(WSRM_CREATE_SEQUENCE, wsrmNamespace); String wsaNamespace = wsrmNamespace.equals(WSRM_NS_1_0) ? WsaUtils.WS_A_NAMESPACE_200408 : WsaUtils.WS_A_NAMESPACE_200508; if (!wsrmNamespace.equals(WSRM_NS_1_0) && !StringUtils.isNullOrEmpty(offerEndpoint)) { cursor.beginElement("Offer", wsrmNamespace); cursor.beginElement("Endpoint", wsrmNamespace); cursor.beginElement("Address", wsaNamespace); cursor.insertChars(offerEndpoint); cursor.toParent(); cursor.toParent(); cursor.beginElement("Identifier", wsrmNamespace); cursor.insertChars("urn:soapui:" + uuid); cursor.toParent(); cursor.toParent(); } cursor.beginElement(WSRM_ACKNOWLEDGMENTS_TO, wsrmNamespace); cursor.insertNamespace("wsa", wsaNamespace); cursor.beginElement("Address", wsaNamespace); if (ackTo == null || ackTo.length() < 1) { ackTo = WsaUtils.getNamespace(startSequenceRequest.getWsaConfig().getVersion()) + "/anonymous" + "?id=" + uuid; } cursor.insertChars(ackTo); // cursor.insertChars(request.getWsrmConfig().getAckTo()); if (expires != 0) { cursor.toParent(); cursor.beginElement(WSRM_EXPIRES, wsrmNamespace); cursor.insertChars(expires.toString()); } cursor.dispose(); WsaUtils wsaUtils = new WsaUtils(object.xmlText(), soapVersion, null, new DefaultPropertyExpansionContext( startSequenceRequest)); content = wsaUtils.addWSAddressingRequest(startSequenceRequest); startSequenceRequest.setRequestContent(content); } catch (XmlException e) { // TODO Auto-generated catch block e.printStackTrace(); } return startSequenceRequest; } public static String getWsrmVersionNamespace(WsrmVersionTypeConfig.Enum wsrmVersion) { if (wsrmVersion == WsrmVersionTypeConfig.X_1_0) { return WSRM_NS_1_0; } else if (wsrmVersion == WsrmVersionTypeConfig.X_1_1) { return WSRM_NS_1_1; } else { return WSRM_NS_1_2; } } public void closeSequence(String endpoint, SoapVersion soapVersion, String wsrmNamespace, String uuid, String identifier, long lastMsgNum, WsdlOperation operation) { HttpRequestConfig httpRequestConfig = (HttpRequestConfig) (XmlObject.Factory.newInstance() .changeType(HttpRequestConfig.type)); httpRequestConfig.setEndpoint(endpoint); httpRequestConfig.setMediaType(soapVersion.getContentType()); WsaConfigConfig wsaConfigConfig = (WsaConfigConfig) (XmlObject.Factory.newInstance() .changeType(WsaConfigConfig.type)); WsaContainer wsaContainer = new WsaContainerImpl(); wsaContainer.setOperation(operation); WsaConfig wsaConfig = new WsaConfig(wsaConfigConfig, wsaContainer); WsrmConfigConfig wsrmConfigConfig = (WsrmConfigConfig) (XmlObject.Factory.newInstance() .changeType(WsrmConfigConfig.type)); WsrmConfig wsrmConfig = new WsrmConfig(wsrmConfigConfig, null); if (!wsrmNamespace.equals(WSRM_NS_1_0)) { WsaRequest closeSequenceRequest = new WsaRequest(httpRequestConfig, wsaConfig, wsrmConfig, false); closeSequenceRequest.setOperation(operation); String openSequenceMessageContent = SoapMessageBuilder.buildEmptyMessage(soapVersion); closeSequenceRequest.getWsaConfig().setWsaEnabled(true); closeSequenceRequest.getWsaConfig().setAction(wsrmNamespace + WSRM_CLOSE_SEQUENCE_ACTION); closeSequenceRequest.getWsaConfig().setTo(endpoint); closeSequenceRequest.getWsaConfig().setGenerateMessageId(true); try { // XmlObject object = XmlObject.Factory.parse( // openSequenceMessageContent ); XmlObject object = XmlUtils.createXmlObject(openSequenceMessageContent); XmlCursor cursor = object.newCursor(); cursor.toFirstContentToken(); cursor.toFirstChild(); cursor.toNextSibling(); cursor.toNextToken(); cursor.insertNamespace("wsrm", wsrmNamespace); cursor.beginElement(WSRM_CLOSE_SEQUENCE, wsrmNamespace); cursor.beginElement(WSRM_IDENTIFIER, wsrmNamespace); cursor.insertChars(identifier); cursor.toParent(); cursor.beginElement(WSRM_LAST_MSG, wsrmNamespace); cursor.insertChars(String.valueOf(lastMsgNum)); cursor.dispose(); WsaUtils wsaUtils = new WsaUtils(object.xmlText(), soapVersion, null, new DefaultPropertyExpansionContext( closeSequenceRequest)); content = wsaUtils.addWSAddressingRequest(closeSequenceRequest); closeSequenceRequest.setRequestContent(content); Logger.getLogger("wsrm").info("CloseSequence Request Sent for Sequence: " + identifier); } catch (XmlException e) { SoapUI.logError(e); } try { WsdlSubmit wsdlSubmit = closeSequenceRequest.submit(new WsdlSubmitContext(null), true); while (wsdlSubmit.getStatus() != Status.FINISHED) { wsdlSubmit.waitUntilFinished(); } Response response = wsdlSubmit.getResponse(); String responseContent = response.getContentAsString(); // XmlObject xml = XmlObject.Factory.parse( responseContent ); XmlObject xml = XmlUtils.createXmlObject(responseContent); XmlOptions options = new XmlOptions(); String namespaceDeclaration = "declare namespace wsrm='" + wsrmNamespace + "';"; XmlObject result[] = xml.selectPath(namespaceDeclaration + "//wsrm:AcknowledgementRange", options); if (result.length > 0) { for (XmlObject aResult : result) { String upper = aResult.selectAttribute(null, "Upper").getDomNode().getNodeValue(); String lower = aResult.selectAttribute(null, "Lower").getDomNode().getNodeValue(); if (lower.equals(upper)) { Logger.getLogger("wsrm").info( "Acknowledgment for message " + upper + " received for identifier: " + identifier); } else { Logger.getLogger("wsrm").info( "Acknowledgment for messages " + lower + " to " + upper + " received for identifier: " + identifier); } } } else { Logger.getLogger("wsrm").info("No Acknowledgments received for identifier: " + identifier); } } catch (SubmitException e1) { SoapUI.logError(e1); } catch (XmlException e) { SoapUI.logError(e); } } // The Terminate Sequence Message WsaRequest terminateSequenceRequest = new WsaRequest(httpRequestConfig, wsaConfig, wsrmConfig, false); terminateSequenceRequest.setOperation(operation); String terminateSequenceRequestContent = SoapMessageBuilder.buildEmptyMessage(soapVersion); terminateSequenceRequest.getWsaConfig().setWsaEnabled(true); terminateSequenceRequest.getWsaConfig().setAction(wsrmNamespace + WSRM_TERMINATE_SEQUENCE_ACTION); terminateSequenceRequest.getWsaConfig().setTo(endpoint); terminateSequenceRequest.getWsaConfig().setGenerateMessageId(true); try { // XmlObject object = XmlObject.Factory.parse( // terminateSequenceRequestContent ); XmlObject object = XmlUtils.createXmlObject(terminateSequenceRequestContent); XmlCursor cursor = object.newCursor(); cursor.toFirstContentToken(); cursor.toFirstChild(); cursor.toNextSibling(); cursor.toNextToken(); cursor.insertNamespace("wsrm", wsrmNamespace); cursor.beginElement("TerminateSequence", wsrmNamespace); cursor.beginElement(WSRM_IDENTIFIER, wsrmNamespace); cursor.insertChars(identifier); cursor.dispose(); // startSequenceRequest.getOperation().setAction(""); // startSequenceRequest.setRequestContent(object.xmlText()); WsaUtils wsaUtils = new WsaUtils(object.xmlText(), soapVersion, null, new DefaultPropertyExpansionContext( terminateSequenceRequest)); terminateSequenceRequestContent = wsaUtils.addWSAddressingRequest(terminateSequenceRequest); terminateSequenceRequest.setRequestContent(terminateSequenceRequestContent); } catch (XmlException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { terminateSequenceRequest.submit(new WsdlSubmitContext(null), true); } catch (SubmitException e1) { SoapUI.logError(e1); } } public void getAcks(String endpoint, SoapVersion soapVersion, String wsrmNamespace, String uuid, String identifier, WsdlOperation operation) { HttpRequestConfig httpRequestConfig = (HttpRequestConfig) (XmlObject.Factory.newInstance() .changeType(HttpRequestConfig.type)); httpRequestConfig.setEndpoint(endpoint); httpRequestConfig.setMediaType(soapVersion.getContentType()); WsaConfigConfig wsaConfigConfig = (WsaConfigConfig) (XmlObject.Factory.newInstance() .changeType(WsaConfigConfig.type)); WsaContainer wsaContainer = new WsaContainerImpl(); wsaContainer.setOperation(operation); WsaConfig wsaConfig = new WsaConfig(wsaConfigConfig, wsaContainer); WsrmConfigConfig wsrmConfigConfig = (WsrmConfigConfig) (XmlObject.Factory.newInstance() .changeType(WsrmConfigConfig.type)); WsrmConfig wsrmConfig = new WsrmConfig(wsrmConfigConfig, null); WsaRequest startSequenceRequest = new WsaRequest(httpRequestConfig, wsaConfig, wsrmConfig, false); startSequenceRequest.setOperation(operation); String openSequenceMessageContent = SoapMessageBuilder.buildEmptyMessage(soapVersion); startSequenceRequest.getWsaConfig().setWsaEnabled(true); startSequenceRequest.getWsaConfig().setAction(wsrmNamespace + WSRM_REQUEST_ACK_ACTION); startSequenceRequest.getWsaConfig().setTo(endpoint); startSequenceRequest.getWsaConfig().setGenerateMessageId(true); try { // XmlObject object = XmlObject.Factory.parse( // openSequenceMessageContent ); XmlObject object = XmlUtils.createXmlObject(openSequenceMessageContent); XmlCursor cursor = object.newCursor(); cursor.toFirstContentToken(); cursor.toFirstChild(); cursor.toNextSibling(); cursor.toNextToken(); cursor.insertNamespace("wsrm", wsrmNamespace); cursor.beginElement(WSRM_REQUEST_ACK, wsrmNamespace); cursor.beginElement(WSRM_IDENTIFIER, wsrmNamespace); cursor.insertChars(identifier); cursor.dispose(); WsaUtils wsaUtils = new WsaUtils(object.xmlText(), soapVersion, null, new DefaultPropertyExpansionContext( startSequenceRequest)); content = wsaUtils.addWSAddressingRequest(startSequenceRequest); startSequenceRequest.setRequestContent(content); // WsmcInjection wsmcInjection = new WsmcInjection(endpoint, // operation, soapVersion, uuid); // startSequenceRequest.setAfterRequestInjection(wsmcInjection); Logger.getLogger("wsrm").info("Acknowledgments Requested for Sequence: " + identifier); } catch (XmlException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { WsdlSubmit wsdlSubmit = startSequenceRequest.submit(new WsdlSubmitContext(null), true); while (wsdlSubmit.getStatus() != Status.FINISHED) { wsdlSubmit.waitUntilFinished(); } Response response = wsdlSubmit.getResponse(); String responseContent = response.getContentAsString(); // XmlObject xml = XmlObject.Factory.parse( responseContent ); XmlObject xml = XmlUtils.createXmlObject(responseContent); XmlObject result = xml.selectPath("Envelope/Header/SequenceAcknowledgment")[0]; } catch (SubmitException e1) { SoapUI.logError(e1); } catch (XmlException e) { SoapUI.logError(e); } } }