[jboss-svn-commits] JBL Code SVN: r34641 - in labs/jbossesb/branches/JBESB_4_7_CP/product: rosetta/src/org/jboss/soa/esb/dom and 5 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Aug 11 12:06:32 EDT 2010
Author: kevin.conner at jboss.com
Date: 2010-08-11 12:06:29 -0400 (Wed, 11 Aug 2010)
New Revision: 34641
Added:
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/soap-message-02.xml
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/JBESB_3327_SoapUIClientServiceMBeanUnitTest.java
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/collectionresponse.wsdl
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/expected_JBESB_3327_01.xml
Modified:
labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/internal/soa/esb/soap/OGNLUtils.java
labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/soa/esb/dom/YADOMUtil.java
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/MBeanSoapUIInvoker.java
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/SOAPClient.java
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/SoapUIInvoker.java
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/SOAPClient_Response_UnitTest.java
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/request/MockSOAPClient.java
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/main/java/org/jboss/soa/esb/services/soapui/SoapUIClientService.java
labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/main/java/org/jboss/soa/esb/services/soapui/SoapUIClientServiceMBean.java
Log:
Pulled across fix for SOAPClient's OGNL util does not map collections properly from SOAP responses: JBESB-3452
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/internal/soa/esb/soap/OGNLUtils.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/internal/soa/esb/soap/OGNLUtils.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/internal/soa/esb/soap/OGNLUtils.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -23,6 +23,7 @@
public static final String OGNL_ATTRIB = "ognl";
public static final String IS_COLLECTION_ATTRIB = "is-collection";
public static final String SOAPUI_CLONE_COMMENT = " repetitions:";
+ public static final String CLONED_POSTFIX = " - cloned";
private enum SOAPNameSpaces
{
@@ -117,6 +118,9 @@
if (assertIsParentCollection(element)) {
int count = YADOMUtil.countElementsBefore(element, element.getTagName());
ognlToken = "[" + count + "]";
+ } else if (assertIsCollection(element)) {
+ int count = YADOMUtil.countElementsBefore(element, element.getTagName());
+ ognlToken = "." + localName + "[" + count + "]";
} else {
ognlToken = "." + localName;
}
@@ -148,32 +152,54 @@
return parentNS.equalsIgnoreCase( namespace );
}
+ /**
+ * Assert if the given element is part of a collection.
+ *
+ * @param element The element to be asserted
+ * @return <code>true</code> if the element is part of a collection.
+ */
private static boolean assertIsCollection(Element element) {
- if(element.getAttributeNS(JBOSSESB_SOAP_NS, IS_COLLECTION_ATTRIB).equals("true")) {
- // It's already been attributed... no need to check for the soapui comment...
- return true;
- }
+ Node parent = element.getParentNode();
+ if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
+ Element firstSibling = YADOMUtil.getFirstChildElementByName((Element) parent, element.getTagName());
+ Comment commentBefore = YADOMUtil.getCommentBefore(firstSibling);
- Comment comment = (Comment)YADOMUtil.getFirstChildByType(element, Node.COMMENT_NODE);
- if (comment != null
- && comment.getTextContent().endsWith(SOAPUI_CLONE_COMMENT)) {
- //possible array
- Element first = YADOMUtil.getFirstChildElement(element);
- Element last = YADOMUtil.getLastChildElement(element);
- if (first != null && last != null && first.getTagName().equals(last.getTagName())) {
- //The children are of same tag so the parent is a collection holder (array)
+ if(commentBefore != null
+ && (commentBefore.getTextContent().endsWith(SOAPUI_CLONE_COMMENT)
+ || commentBefore.getTextContent().endsWith(SOAPUI_CLONE_COMMENT + CLONED_POSTFIX))) {
return true;
}
}
-
return false;
}
+ /**
+ * Assert if the parent of the given element is the collection holder.
+ *
+ * @param element The element to be asserted
+ * @return <code>true</code> if the parent is the collection holder.
+ */
private static boolean assertIsParentCollection(Element element) {
Node parent = element.getParentNode();
- if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE && assertIsCollection((Element)parent)) {
- return true;
+ if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
+ Element pelement = (Element)parent;
+ if(pelement.getAttributeNS(JBOSSESB_SOAP_NS, IS_COLLECTION_ATTRIB).equals("true")) {
+ // It's already been attributed... no need to check for the soapui comment...
+ return true;
+ }
+
+ Comment comment = (Comment)YADOMUtil.getFirstChildByType(pelement, Node.COMMENT_NODE);
+ if (comment != null
+ && comment.getTextContent().endsWith(SOAPUI_CLONE_COMMENT)) {
+ //possible array
+ Element first = YADOMUtil.getFirstChildElement(pelement);
+ Element last = YADOMUtil.getLastChildElement(pelement);
+ if (first != null && last != null && first.getTagName().equals(last.getTagName())) {
+ //The children are of same tag so it is an array
+ return true;
+ }
+ }
}
return false;
}
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/soa/esb/dom/YADOMUtil.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/soa/esb/dom/YADOMUtil.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/rosetta/src/org/jboss/soa/esb/dom/YADOMUtil.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -508,4 +508,28 @@
return null;
}
+
+ /**
+ * Get the first child of the supplied element that matches a given tag name.
+ *
+ * @param element The element.
+ * @param name The name of the child element to search for.
+ * @return The first child element with the matching tag name.
+ */
+ public static Element getFirstChildElementByName(Element element, String name) {
+ NodeList children = element.getChildNodes();
+ int childCount = children.getLength();
+
+ for(int i = 0; i < childCount; i++) {
+ Node child = children.item(i);
+ if (child != null
+ && child.getNodeType() == Node.ELEMENT_NODE
+ && ((Element)child).getTagName() != null
+ && ((Element)child).getTagName().equals(name) ) {
+ return (Element) child;
+ }
+ }
+
+ return null;
+ }
}
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/MBeanSoapUIInvoker.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/MBeanSoapUIInvoker.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/MBeanSoapUIInvoker.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -37,6 +37,7 @@
private static final String[] buildRequestSig = new String[] {String.class.getName(), String.class.getName(), Map.class.getName(), Properties.class.getName(), String.class.getName(), String.class.getName()};
private static final String[] buildFaultSig = new String[] {String.class.getName(), String.class.getName(), String.class.getName(), Map.class.getName(), Properties.class.getName(), String.class.getName(), String.class.getName()};
private static final String[] getEndpointSig = new String[] {String.class.getName(), Properties.class.getName()};
+ private static final String[] mergeResponseSig = new String[] {String.class.getName(), String.class.getName(), String.class.getName(), Properties.class.getName(), String.class.getName(), String.class.getName()};
private MBeanServer mbeanServer;
private ObjectName serviceName;
@@ -155,6 +156,42 @@
}
}
+ /**
+ * Merge a SOAP response for the specified operation on the specified WSDL with its template.
+ *
+ * @param wsdl WSDL URL.
+ * @param operation Operation name.
+ * @param response The actual response.
+ * @param httpClientProps {@link org.apache.commons.httpclient.HttpClient} creation properties.
+ * @param smooksResource {@link org.milyn.Smooks} transformation configuration resource file.
+ * Null if no transformations are to be performed on the SOAP message before serializing it
+ * for return.
+ * @param soapNs the SOAP namespace. If null one of the defaults will be used:
+ * http://schemas.xmlsoap.org/soap/envelope/
+ * http://www.w3.org/2003/05/soap-envelope
+ * @return The SOAP Message.
+ * @throws java.io.IOException Failed to load WSDL.
+ * @throws UnsupportedOperationException Operation not supported on specified WSDL.
+ * @throws org.xml.sax.SAXException Failed to parse the SOAP UI generated request message.
+ */
+ public String mergeResponseTemplate(String wsdl, String operation, String response, Properties httpClientProps, String smooksResource, String soapNs) throws IOException, UnsupportedOperationException, SAXException {
+ try {
+ return (String) mbeanServer.invoke(serviceName, "mergeResponseTemplate", new Object[] {wsdl, operation, response, httpClientProps, smooksResource, soapNs}, mergeResponseSig);
+ } catch (InstanceNotFoundException e) {
+ throw new UnsupportedOperationException("SOAP UI Client Service not found under name '" + serviceName.getCanonicalName() + "'. This service must be deployed before this action can be used.", e);
+ } catch (MBeanException e) {
+ if(e.getCause() instanceof IOException) {
+ throw (IOException)e.getCause();
+ }
+ throw new RuntimeException(e);
+ } catch (ReflectionException e) {
+ if(e.getCause() instanceof IOException) {
+ throw (IOException)e.getCause();
+ }
+ throw new RuntimeException(e);
+ }
+ }
+
private void rethrowException(Throwable e) throws IOException, UnsupportedOperationException, SAXException {
Throwable cause = e.getCause();
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/SOAPClient.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/SOAPClient.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/SOAPClient.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -431,6 +431,17 @@
}
Response response = invokeEndpoint(request);
+ if(responseAsOgnlMap) {
+ try {
+ String mergedResponse = soapUIInvoker.mergeResponseTemplate(wsdl, getEndpointOperation(), response.getBody(), httpClientProps, null, soapNs);
+ response.setBody(mergedResponse);
+ } catch (IOException e) {
+ throw new ActionProcessingException("soapUI Client Service invocation failed.", e);
+ } catch (SAXException e) {
+ throw new ActionProcessingException("soapUI Client Service invocation failed.", e);
+ }
+ }
+
// And process the response into the message...
processResponse(message, response);
@@ -473,6 +484,9 @@
protected String getBody() {
return body;
}
+ protected void setBody(String body) {
+ this.body = body;
+ }
protected int getStatusCode() {
return statusCode;
}
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/SoapUIInvoker.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/SoapUIInvoker.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/main/java/org/jboss/soa/esb/actions/soap/SoapUIInvoker.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -17,4 +17,6 @@
String buildFault(String wsdl, String operation, String faultName, Map params, Properties httpClientProps, String smooksResource, String soapNs) throws IOException, UnsupportedOperationException, SAXException;
String getEndpoint(String wsdl, Properties httpClientProps) throws IOException;
+
+ String mergeResponseTemplate(String wsdl, String operation, String response, Properties httpClientProps, String smooksResource, String soapNs) throws IOException, UnsupportedOperationException, SAXException;
}
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/SOAPClient_Response_UnitTest.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/SOAPClient_Response_UnitTest.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/SOAPClient_Response_UnitTest.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -79,6 +79,34 @@
assertEquals("{customerOrder.orderheader.customerName=Tom Fennelly, customerOrder.items[0].partNumber=1, customerOrder.items[0].description=desc-1, customerOrder.items[0].quantity=1, customerOrder.items[0].price=1.1, customerOrder.items[0].extensionAmount=1, customerOrder.items[1].partNumber=2, customerOrder.items[1].description=desc-2, customerOrder.items[1].quantity=2, customerOrder.items[1].price=2.2, customerOrder.items[1].extensionAmount=2}", responseMap.toString());
}
+ public void test_OgnlMap_ResponseProcessing_4() throws ConfigurationException, ActionProcessingException {
+ ConfigTree actionConfig = configUtil.getActionConfig("OrderNotificationService", "soapui-client-action-02");
+ SOAPClient soapClient = new SOAPClient(actionConfig);
+ String responseString = new String(StreamUtils.readStream(getClass().getResourceAsStream("soap-message-02.xml")));
+ String expected = "{processOrderResponse.OrderStatus.id=1," +
+ " processOrderResponse.OrderStatus.comment=order processed," +
+ " processOrderResponse.OrderStatus.returnCode=1," +
+ " processOrderResponse.OrderStatus.lineItems[0].id=1," +
+ " processOrderResponse.OrderStatus.lineItems[0].name=Item1," +
+ " processOrderResponse.OrderStatus.lineItems[0].price=10," +
+ " processOrderResponse.OrderStatus.lineItems[0].comments[0]=Item1 Comments1," +
+ " processOrderResponse.OrderStatus.lineItems[0].comments[1]=Item1 Comments2," +
+ " processOrderResponse.OrderStatus.lineItems[1].id=2," +
+ " processOrderResponse.OrderStatus.lineItems[1].name=Item2," +
+ " processOrderResponse.OrderStatus.lineItems[1].price=15," +
+ " processOrderResponse.OrderStatus.lineItems[1].comments[0]=Item2 Comments1," +
+ " processOrderResponse.OrderStatus.lineItems[1].comments[1]=Item2 Comments2," +
+ " processOrderResponse.OrderStatus.lineItems[1].comments[2]=Item2 Comments3," +
+ " processOrderResponse.OrderStatus.lineItems[1].comments[3]=Item2 Comments4}";
+
+ Message message = MessageFactory.getInstance().getMessage();
+
+ soapClient.processResponse(message, new Response(responseString));
+ Map<String, String> responseMap = (Map<String, String>) message.getBody().get();
+
+ assertEquals(expected, responseMap.toString());
+ }
+
public void test_No_ResponseProcessing() throws ConfigurationException, ActionProcessingException {
ConfigTree actionConfig = configUtil.getActionConfig("OrderNotificationService", "soapui-client-action-03");
SOAPClient soapClient = new SOAPClient(actionConfig);
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/request/MockSOAPClient.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/request/MockSOAPClient.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/request/MockSOAPClient.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -62,6 +62,10 @@
public String getEndpoint(String wsdl, Properties httpClientProps) throws IOException {
return service.getEndpoint(wsdl, httpClientProps);
}
+
+ public String mergeResponseTemplate(String wsdl, String operation, String response, Properties httpClientProps, String smooksResource, String soapNs) throws IOException, UnsupportedOperationException, SAXException {
+ return service.mergeResponseTemplate(wsdl, operation, response, httpClientProps, smooksResource, soapNs);
+ }
};
setSoapUIInvoker(soapUIInvoker);
Copied: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/soap-message-02.xml (from rev 33435, labs/jbossesb/trunk/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/soap-message-02.xml)
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/soap-message-02.xml (rev 0)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soap/src/test/java/org/jboss/soa/esb/actions/soap/soap-message-02.xml 2010-08-11 16:06:29 UTC (rev 34641)
@@ -0,0 +1,32 @@
+<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ord='http://webservice_consumer_list/orderProcessor'>
+ <env:Header>
+ </env:Header>
+ <env:Body>
+ <ord:processOrderResponse>
+ <OrderStatus>
+ <id>1</id>
+ <comment>order processed</comment>
+ <returnCode>1</returnCode>
+ <!--Zero or more repetitions:-->
+ <lineItems>
+ <id>1</id>
+ <name>Item1</name>
+ <price>10</price>
+ <!--Zero or more repetitions:-->
+ <comments>Item1 Comments1</comments>
+ <comments>Item1 Comments2</comments>
+ </lineItems>
+ <lineItems>
+ <id>2</id>
+ <name>Item2</name>
+ <price>15</price>
+ <!--Zero or more repetitions:-->
+ <comments>Item2 Comments1</comments>
+ <comments>Item2 Comments2</comments>
+ <comments>Item2 Comments3</comments>
+ <comments>Item2 Comments4</comments>
+ </lineItems>
+ </OrderStatus>
+ </ord:processOrderResponse>
+ </env:Body>
+</env:Envelope>
\ No newline at end of file
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/main/java/org/jboss/soa/esb/services/soapui/SoapUIClientService.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/main/java/org/jboss/soa/esb/services/soapui/SoapUIClientService.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/main/java/org/jboss/soa/esb/services/soapui/SoapUIClientService.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -101,7 +101,6 @@
private DocumentBuilderFactory docBuilderFactory ;
private SmooksCache smooksCache;
private ESBProperties properties;
- private static final String CLONED_POSTFIX = " - cloned";
private static final String SOAPUI_OPTIONAL_COMMENT = "Optional:";
private static final String REMOVE_POSTFIX = " to be removed";
private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
@@ -416,6 +415,28 @@
return wsdlInterfaces[0].getEndpoints()[0];
}
+ /**
+ * Use soapUI to Merge a SOAP response for the specified operation on the specified WSDL with its template.
+ *
+ * @param wsdl WSDL URL.
+ * @param operation Operation name.
+ * @param response The actual response.
+ * @param smooksResource {@link org.milyn.Smooks} transformation configuration resource file.
+ * Null if no transformations are to be performed on the SOAP message before serializing it
+ * for return.
+ * @param soapNs optional SOAP namespace
+ * @return The SOAP Message.
+ * @throws IOException Failed to load WSDL.
+ * @throws UnsupportedOperationException Operation not supported on specified WSDL.
+ * @throws SAXException Failed to parse the SOAP UI generated request message.
+ */
+ public String mergeResponseTemplate(String wsdl, String operation, String response, Properties httpClientProps, String smooksResource, String soapNs) throws IOException, UnsupportedOperationException, SAXException {
+ Operation operationInst = getOperation(wsdl, operation, httpClientProps);
+ WsdlOperation wsdlOperation = (WsdlOperation)operationInst;
+ String responseTemplate = wsdlOperation.createResponse(true);
+ return mergeSOAPMessage(responseTemplate, response, smooksResource, soapNs);
+ }
+
private WsdlInterface[] getWsdlInterfaces(String wsdl, Properties httpClientProps) throws IOException {
try {
WsdlInterface[] wsdlInterfaces = wsdls.get(wsdl);
@@ -541,6 +562,96 @@
}
}
+ private String mergeSOAPMessage(String soapMessageTemplate, String response, String smooksResource, String soapNs) throws IOException, SAXException {
+ Document templateDoc = getDocument(soapMessageTemplate);
+ Element templateRoot = templateDoc.getDocumentElement();
+
+ Document messageDoc = getDocument(response);
+ Element messageRoot = messageDoc.getDocumentElement();
+
+ debugDoc(messageRoot);
+ debugDoc(templateRoot);
+
+ mergeTemplate(templateRoot, messageRoot, 0);
+
+ if(smooksResource != null) {
+ applySmooksTransform(smooksResource, messageDoc);
+ }
+
+ debugDoc(messageRoot);
+
+ try
+ {
+ final StringWriter sw = new StringWriter() ;
+ final XMLEventWriter writer = XMLHelper.getXMLEventWriter(sw) ;
+ XMLHelper.readDomNode(messageRoot, writer, true) ;
+ return sw.toString();
+ }
+ catch (final XMLStreamException xmlse)
+ {
+ final IOException ioe = new IOException("Failed to serialize the output SOAP message") ;
+ ioe.initCause(xmlse) ;
+ throw ioe ;
+ }
+ }
+
+ private void debugDoc(Element doc)
+ {
+ if(logger.isDebugEnabled()) {
+ logger.debug("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
+ try {
+ final StringWriter sw = new StringWriter() ;
+ final XMLEventWriter writer = XMLHelper.getXMLEventWriter(sw) ;
+ XMLHelper.readDomNode(doc, writer, true) ;
+ logger.debug(sw.toString());
+ } catch (final XMLStreamException xmlse) {
+ logger.debug("Failed to print the SOAP message") ;
+ }
+ logger.debug("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
+ }
+ }
+
+ /**
+ * Merge the template to accommodate data collections.
+ * <p/>
+ * It merges the soapUI cllection comment nodes to the message where appropriate.
+ *
+ * @param template The template element to be merged.
+ * @param instance The element to be processed.
+ * @param index The template's element instance index.
+ */
+ private void mergeTemplate(Element template, Element instance, int index) {
+ if (template != null && instance != null) {
+ if (index == 0) {
+ //Process only if this is the first element of its kind
+ Comment comment = YADOMUtil.getCommentBefore(template);
+ if (comment != null
+ && comment.getTextContent().endsWith(OGNLUtils.SOAPUI_CLONE_COMMENT)) {
+ Node parent = instance.getParentNode();
+ if (parent != null) {
+ Comment newComment = parent.getOwnerDocument().createComment(comment.getTextContent());
+ parent.insertBefore(newComment, instance);
+ }
+ }
+ }
+
+ NodeList children = template.getChildNodes();
+ int nodesCount = children.getLength();
+ for (int i = 0; i < nodesCount; i++) {
+ Node templateNode = children.item(i);
+ if (templateNode.getNodeType() == Node.ELEMENT_NODE) {
+ //We may have many instances of this template
+ //and each could have a nested collection so run through them
+ NodeList instances = instance.getElementsByTagNameNS(templateNode.getNamespaceURI(), templateNode.getLocalName());
+ int instancesSize = instances.getLength();
+ for (int j = 0; j < instancesSize; j++) {
+ mergeTemplate((Element) templateNode, (Element) instances.item(j), j);
+ }
+ }
+ }
+ }
+ }
+
private Document getDocument(String soapMessageTemplate) throws IOException {
try {
final XMLEventReader reader = XMLHelper.getXMLEventReader(new StringReader(soapMessageTemplate)) ;
@@ -588,14 +699,18 @@
* decide whether or not cloning is required.
*/
private void expandMessage(Element element, Map params) {
-
+ boolean elementRemoved = false;
// If this element is not a cloned element, check does it need to be cloned...
if (!element.hasAttributeNS(OGNLUtils.JBOSSESB_SOAP_NS, IS_CLONE_ATTRIB)) {
- String ognl = OGNLUtils.getOGNLExpression(element);
Element clonePoint = getClonePoint(element);
if(clonePoint != null) {
int collectionSize;
+ String ognl = OGNLUtils.getOGNLExpression(element);
+ //We don't need the index value when expanding the message
+ if (ognl.endsWith("]")) {
+ ognl = ognl.substring(0, ognl.lastIndexOf("["));
+ }
collectionSize = calculateCollectionSize(ognl, params);
@@ -604,6 +719,7 @@
if(clonePoint == element) {
// If the clonePoint is the element itself, we remove it... we're done with it...
clonePoint.getParentNode().removeChild(clonePoint);
+ elementRemoved = true;
} else {
// If the clonePoint is not the element itself (it's a child element), leave it
// and check it again when we get to it...
@@ -612,6 +728,7 @@
} else if(collectionSize == 0) {
// It's a collection, but has no entries, remove it...
clonePoint.getParentNode().removeChild(clonePoint);
+ elementRemoved = true;
} else if(collectionSize == 1) {
// It's a collection, but no need to clone coz we
// already have an entry for it...
@@ -620,7 +737,7 @@
// It's a collection and we need to do some cloning
if(clonePoint != null) {
// We already have one, so decrement by one...
- cloneCollectionTemplateElement(clonePoint, (collectionSize - 1), ognl);
+ cloneCollectionTemplateElement(clonePoint, (collectionSize - 1), ognl, params);
} else {
logger.warn("Collection/array template element <" + element.getLocalName() + "> would appear to be invalid. It doesn't contain any child elements.");
}
@@ -628,7 +745,13 @@
}
}
- // Now do the same for the child elements...
+ if (!elementRemoved){
+ // Now do the same for the child elements...
+ expandChildren(element, params);
+ }
+ }
+
+ private void expandChildren(Element element, Map params) {
List<Node> children = YADOMUtil.copyNodeList(element.getChildNodes());
for (Node node : children) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
@@ -682,16 +805,18 @@
// Is it this element...
comment = YADOMUtil.getCommentBefore(element);
if(comment != null && comment.getTextContent().endsWith(OGNLUtils.SOAPUI_CLONE_COMMENT)) {
- comment.setTextContent(comment.getTextContent() + CLONED_POSTFIX);
+ comment.setTextContent(comment.getTextContent() + OGNLUtils.CLONED_POSTFIX);
return element;
}
// Is it the first child element of this element...
Element firstChildElement = YADOMUtil.getFirstChildElement(element);
if(firstChildElement != null) {
+ Element lastChildElement = YADOMUtil.getLastChildElement(element);
comment = YADOMUtil.getCommentBefore(firstChildElement);
- if(comment != null && comment.getTextContent().endsWith(OGNLUtils.SOAPUI_CLONE_COMMENT)) {
- comment.setTextContent(comment.getTextContent() + CLONED_POSTFIX);
+ if(comment != null && comment.getTextContent().endsWith(OGNLUtils.SOAPUI_CLONE_COMMENT)
+ && lastChildElement != null && firstChildElement.getTagName().equals(lastChildElement.getTagName())) {
+ comment.setTextContent(comment.getTextContent() + OGNLUtils.CLONED_POSTFIX);
return firstChildElement;
}
}
@@ -707,11 +832,11 @@
}
String commentText = comment.getTextContent();
- if(!commentText.endsWith(CLONED_POSTFIX)) {
+ if(!commentText.endsWith(OGNLUtils.CLONED_POSTFIX)) {
throw new IllegalStateException("Call to reset a 'clonePoint' that doesn't have a proper clone comment before it.");
}
- comment.setTextContent(commentText.substring(0, commentText.length() - CLONED_POSTFIX.length()));
+ comment.setTextContent(commentText.substring(0, commentText.length() - OGNLUtils.CLONED_POSTFIX.length()));
}
/**
@@ -726,8 +851,9 @@
* @param cloneCount The number of times it needs to be cloned.
* @param ognl The OGNL expression for the collection/array. Not including the
* indexing part.
+ * @param params The message params.
*/
- private void cloneCollectionTemplateElement(Element element, int cloneCount, String ognl) {
+ private void cloneCollectionTemplateElement(Element element, int cloneCount, String ognl, Map params) {
if (element == null) {
return;
}
@@ -746,6 +872,8 @@
} else {
parent.insertBefore(clone, insertPoint);
}
+ //The clones can have collections too, so we need to expand them here
+ expandChildren(clone, params);
}
}
Modified: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/main/java/org/jboss/soa/esb/services/soapui/SoapUIClientServiceMBean.java
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/main/java/org/jboss/soa/esb/services/soapui/SoapUIClientServiceMBean.java 2010-08-11 15:42:19 UTC (rev 34640)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/main/java/org/jboss/soa/esb/services/soapui/SoapUIClientServiceMBean.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -85,6 +85,23 @@
public abstract String getEndpoint(String wsdl, Properties httpClientProps) throws IOException;
/**
+ * Use soapUI mockService to Merge a SOAP response for the specified operation on the specified WSDL with its template.
+ *
+ * @param wsdl WSDL URL.
+ * @param operation Operation name.
+ * @param response The actual response.
+ * @param smooksResource {@link org.milyn.Smooks} transformation configuration resource file.
+ * Null if no transformations are to be performed on the SOAP message before serializing it
+ * for return.
+ * @param soapNs optional SOAP namespace
+ * @return The SOAP Message.
+ * @throws IOException Failed to load WSDL.
+ * @throws UnsupportedOperationException Operation not supported on specified WSDL.
+ * @throws SAXException Failed to parse the SOAP UI generated request message.
+ */
+ public abstract String mergeResponseTemplate(String wsdl, String operation, String response, Properties httpClientProps, String smooksResource, String soapNs) throws IOException, UnsupportedOperationException, SAXException;
+
+ /**
* Get the property file.
* @return The name of the property file being used.
*/
Copied: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/JBESB_3327_SoapUIClientServiceMBeanUnitTest.java (from rev 33435, labs/jbossesb/trunk/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/JBESB_3327_SoapUIClientServiceMBeanUnitTest.java)
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/JBESB_3327_SoapUIClientServiceMBeanUnitTest.java (rev 0)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/JBESB_3327_SoapUIClientServiceMBeanUnitTest.java 2010-08-11 16:06:29 UTC (rev 34641)
@@ -0,0 +1,92 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and others contributors as indicated
+ * by the @authors tag. All rights reserved.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2005-2006, JBoss Inc.
+ */
+package org.jboss.soa.esb.services.soapui;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jboss.internal.soa.esb.util.XMLHelper;
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.http.HttpClientFactory;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ * @author <a href="mailto:mageshbk at jboss.com">Magesh Kumar B</a>
+ */
+public class JBESB_3327_SoapUIClientServiceMBeanUnitTest extends TestCase {
+
+ private static final String WSDL_LOCATAION = "src/test/java/org/jboss/soa/esb/services/soapui";
+ private Properties properties;
+
+ protected void setUp() throws Exception {
+ properties = new Properties();
+ }
+
+ public void test_collection_in_response() throws IOException, SAXException, ParserConfigurationException, ConfigurationException {
+ File wsdlFile = new File(WSDL_LOCATAION + "/collectionresponse.wsdl");
+ SoapUIClientService mbean = new SoapUIClientService();
+ String response =
+ "<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>\n" +
+ " <env:Header>\n" +
+ " </env:Header>\n" +
+ " <env:Body>\n" +
+ " <ord:processOrderResponse xmlns:ord='http://webservice_consumer_list/orderProcessor'>\n" +
+ " <OrderStatus>\n" +
+ " <id>1</id>\n" +
+ " <comment>order processed</comment>\n" +
+ " <returnCode>1</returnCode>\n" +
+ " <lineItems>\n" +
+ " <id>1</id>\n" +
+ " <name>Item1</name>\n" +
+ " <price>10</price>\n" +
+ " <comments>Item1 Comments1</comments>\n" +
+ " <comments>Item1 Comments2</comments>\n" +
+ " </lineItems>\n" +
+ " <lineItems>\n" +
+ " <id>2</id>\n" +
+ " <name>Item2</name>\n" +
+ " <price>15</price>\n" +
+ " <comments>Item2 Comments1</comments>\n" +
+ " <comments>Item2 Comments2</comments>\n" +
+ " <comments>Item2 Comments3</comments>\n" +
+ " <comments>Item2 Comments4</comments>\n" +
+ " </lineItems>\n" +
+ " </OrderStatus>\n" +
+ " </ord:processOrderResponse>\n" +
+ " </env:Body>\n" +
+ "</env:Envelope>\n";
+
+ String expected = "expected_JBESB_3327_01.xml";
+
+ properties.setProperty(HttpClientFactory.TARGET_HOST_URL, wsdlFile.toURI().toString());
+
+ String message = mbean.mergeResponseTemplate(wsdlFile.toURI().toString(), "processOrder", response, properties, null, null);
+
+ assertTrue("Generated SOAP message not as expected. See " + expected + ". Generated message: \n" +
+ message, XMLHelper.compareXMLContent(getClass().getResourceAsStream(expected), new ByteArrayInputStream(message.getBytes())));
+ }
+}
\ No newline at end of file
Copied: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/collectionresponse.wsdl (from rev 33435, labs/jbossesb/trunk/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/collectionresponse.wsdl)
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/collectionresponse.wsdl (rev 0)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/collectionresponse.wsdl 2010-08-11 16:06:29 UTC (rev 34641)
@@ -0,0 +1,58 @@
+<definitions name="OrderProcessorWSService" targetNamespace="http://webservice_consumer_list/orderProcessor" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webservice_consumer_list/orderProcessor" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <types>
+ <xs:schema targetNamespace="http://webservice_consumer_list/orderProcessor" version="1.0" xmlns:tns="http://webservice_consumer_list/orderProcessor" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType name="order">
+ <xs:sequence>
+ <xs:element minOccurs="0" name="id" type="xs:long"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="lineItems" nillable="true" type="tns:lineItem"/>
+ <xs:element minOccurs="0" name="shipTo" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="lineItem">
+ <xs:sequence>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="comments" nillable="true" type="xs:string"/>
+ <xs:element minOccurs="0" name="id" type="xs:long"/>
+ <xs:element minOccurs="0" name="name" type="xs:string"/>
+ <xs:element minOccurs="0" name="price" type="xs:float"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="orderStatus">
+ <xs:sequence>
+ <xs:element minOccurs="0" name="id" type="xs:long"/>
+ <xs:element minOccurs="0" name="comment" type="xs:string"/>
+ <xs:element name="returnCode" type="xs:int"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" name="lineItems" nillable="true" type="tns:lineItem"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:schema>
+ </types>
+ <message name="OrderProcessor_processOrder">
+ <part name="order" type="tns:order"/>
+ </message>
+ <message name="OrderProcessor_processOrderResponse">
+ <part name="OrderStatus" type="tns:orderStatus"/>
+ </message>
+ <portType name="OrderProcessor">
+ <operation name="processOrder" parameterOrder="order">
+ <input message="tns:OrderProcessor_processOrder"/>
+ <output message="tns:OrderProcessor_processOrderResponse"/>
+ </operation>
+ </portType>
+ <binding name="OrderProcessorBinding" type="tns:OrderProcessor">
+ <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <operation name="processOrder">
+ <soap:operation soapAction=""/>
+ <input>
+ <soap:body namespace="http://webservice_consumer_list/orderProcessor" use="literal"/>
+ </input>
+ <output>
+ <soap:body namespace="http://webservice_consumer_list/orderProcessor" use="literal"/>
+ </output>
+ </operation>
+ </binding>
+ <service name="OrderProcessorWSService">
+ <port binding="tns:OrderProcessorBinding" name="OrderProcessorPort">
+ <soap:address location="http://127.0.0.1:8080/Quickstart_webservice_consumer_list/OrderProcessorWS"/>
+ </port>
+ </service>
+</definitions>
\ No newline at end of file
Copied: labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/expected_JBESB_3327_01.xml (from rev 33435, labs/jbossesb/trunk/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/expected_JBESB_3327_01.xml)
===================================================================
--- labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/expected_JBESB_3327_01.xml (rev 0)
+++ labs/jbossesb/branches/JBESB_4_7_CP/product/services/soapui-client/src/test/java/org/jboss/soa/esb/services/soapui/expected_JBESB_3327_01.xml 2010-08-11 16:06:29 UTC (rev 34641)
@@ -0,0 +1,32 @@
+<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
+ <env:Header>
+ </env:Header>
+ <env:Body>
+ <ord:processOrderResponse xmlns:ord='http://webservice_consumer_list/orderProcessor'>
+ <OrderStatus>
+ <id>1</id>
+ <comment>order processed</comment>
+ <returnCode>1</returnCode>
+ <!--Zero or more repetitions:-->
+ <lineItems>
+ <id>1</id>
+ <name>Item1</name>
+ <price>10</price>
+ <!--Zero or more repetitions:-->
+ <comments>Item1 Comments1</comments>
+ <comments>Item1 Comments2</comments>
+ </lineItems>
+ <lineItems>
+ <id>2</id>
+ <name>Item2</name>
+ <price>15</price>
+ <!--Zero or more repetitions:-->
+ <comments>Item2 Comments1</comments>
+ <comments>Item2 Comments2</comments>
+ <comments>Item2 Comments3</comments>
+ <comments>Item2 Comments4</comments>
+ </lineItems>
+ </OrderStatus>
+ </ord:processOrderResponse>
+ </env:Body>
+</env:Envelope>
\ No newline at end of file
More information about the jboss-svn-commits
mailing list