Failed comunication between Axis server and JAX-WSclient

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

Failed comunication between Axis server and JAX-WSclient

Gianluca84

Hi, I'm using ofbiz branch 13.07, and launching it from an Eclipse environment.
I was trying to call a service from a jax-ws client (using websphere jax-ws library but I tried also with cxf) generating the client starting from the WSDL, but while the request is sent and executed correctly the response is sent back and fail silently in the unmarshalling fase.
Let's take the ping service as an example.
This is the request message :

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
  <ns0:ping xmlns:se="http://ofbiz.apache.org/service/">
   <map-Map>
    <ns0:map-Entry>
     <ns0:map-Key>
      <ns0:std-String value="login.username"/>
     </ns0:map-Key>
     <ns0:map-Value>
      <ns0:std-String value="admin"/>
     </ns0:map-Value>
    </ns0:map-Entry>
    <ns0:map-Entry>
     <ns0:map-Key>
      <ns0:std-String value="login.password"/>
     </ns0:map-Key>
     <ns0:map-Value>
      <ns0:std-String value="ofbiz"/>
     </ns0:map-Value>
    </ns0:map-Entry>
   </map-Map>
  </ns0:ping>
 </soapenv:Body>
</soapenv:Envelope>

And this is the response:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
  <pingResponse xmlns="http://ofbiz.apache.org/service/">
   <map-Map>
    <map-Entry>
     <map-Key>
      <std-String value="message"/>
     </map-Key>
     <map-Value>
      <std-String value="PONG"/>
     </map-Value>
    </map-Entry>
    <map-Entry>
     <map-Key>
      <std-String value="responseMessage"/>
     </map-Key>
     <map-Value>
      <std-String value="success"/>
     </map-Value>
    </map-Entry>
   </map-Map>
  </pingResponse>
 </soapenv:Body>
</soapenv:Envelope>

As stated here:
http://www.ws-i.org/profiles/basicprofile-1.1.html#R2735
The expected response should be something like this:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
  <se:pingResponse xmlns:se="http://ofbiz.apache.org/service/">
   <map-Map>
    <se:map-Entry>
     <se:map-Key>
      <se:std-String value="message"/>
     </se:map-Key>
     <se:map-Value>
      <se:std-String value="PONG"/>
     </se:map-Value>
    </se:map-Entry>
    <se:map-Entry>
     <se:map-Key>
      <se:std-String value="responseMessage"/>
     </se:map-Key>
     <se:map-Value>
      <se:std-String value="success"/>
     </se:map-Value>
    </se:map-Entry>
   </map-Map>
  </se:pingResponse>
 </soapenv:Body>
</soapenv:Envelope>


Which works flawlessy client side.

Does anyone know how to make this work?
Can it be fixed on the server side without changing ofbiz functionality?
Are there any annotations on the client side that can solve this? External bindings?

Any suggestion will be much appreciated!


 
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Jacopo Cappellato-4
Hi Gianluca,

I didn't play with this part of OFBiz since long but I had a look at the code and I have tried to change it in order to produce the output you need.
Could you please try to apply the attached patch? I didn't test it so it may not work.
Let me know how it goes.

Jacopo


On Wed, Nov 12, 2014 at 7:29 PM, [hidden email] <[hidden email]> wrote:

Hi, I'm using ofbiz branch 13.07, and launching it from an Eclipse environment.
I was trying to call a service from a jax-ws client (using websphere jax-ws library but I tried also with cxf) generating the client starting from the WSDL, but while the request is sent and executed correctly the response is sent back and fail silently in the unmarshalling fase.
Let's take the ping service as an example.
This is the request message :

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
  <ns0:ping xmlns:se="http://ofbiz.apache.org/service/">
   <map-Map>
    <ns0:map-Entry>
     <ns0:map-Key>
      <ns0:std-String value="login.username"/>
     </ns0:map-Key>
     <ns0:map-Value>
      <ns0:std-String value="admin"/>
     </ns0:map-Value>
    </ns0:map-Entry>
    <ns0:map-Entry>
     <ns0:map-Key>
      <ns0:std-String value="login.password"/>
     </ns0:map-Key>
     <ns0:map-Value>
      <ns0:std-String value="ofbiz"/>
     </ns0:map-Value>
    </ns0:map-Entry>
   </map-Map>
  </ns0:ping>
 </soapenv:Body>
</soapenv:Envelope>

And this is the response:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
  <pingResponse xmlns="http://ofbiz.apache.org/service/">
   <map-Map>
    <map-Entry>
     <map-Key>
      <std-String value="message"/>
     </map-Key>
     <map-Value>
      <std-String value="PONG"/>
     </map-Value>
    </map-Entry>
    <map-Entry>
     <map-Key>
      <std-String value="responseMessage"/>
     </map-Key>
     <map-Value>
      <std-String value="success"/>
     </map-Value>
    </map-Entry>
   </map-Map>
  </pingResponse>
 </soapenv:Body>
</soapenv:Envelope>

As stated here:
http://www.ws-i.org/profiles/basicprofile-1.1.html#R2735
The expected response should be something like this:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
  <se:pingResponse xmlns:se="http://ofbiz.apache.org/service/">
   <map-Map>
    <se:map-Entry>
     <se:map-Key>
      <se:std-String value="message"/>
     </se:map-Key>
     <se:map-Value>
      <se:std-String value="PONG"/>
     </se:map-Value>
    </se:map-Entry>
    <se:map-Entry>
     <se:map-Key>
      <se:std-String value="responseMessage"/>
     </se:map-Key>
     <se:map-Value>
      <se:std-String value="success"/>
     </se:map-Value>
    </se:map-Entry>
   </map-Map>
  </se:pingResponse>
 </soapenv:Body>
</soapenv:Envelope>


Which works flawlessy client side.

Does anyone know how to make this work?
Can it be fixed on the server side without changing ofbiz functionality?
Are there any annotations on the client side that can solve this? External bindings?

Any suggestion will be much appreciated!


 

Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Gianluca84
I think you forgot to attach the patch cos I'm not seeing it...
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Gianluca84
In reply to this post by Jacopo Cappellato-4
Hey thanks! I've got the patch, unfortunately those are the exact modifications I already made,
and they're not sufficient.

The result is something like this:

 <?xml version="1.0" encoding="utf-8"?>
 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
   <se:pingResponse xmlns:se="http://ofbiz.apache.org/service/">
    <map-Map>
     <map-Entry>
      <map-Key>
       <std-String value="message"/>
      </map-Key>
      <map-Value>
       <std-String value="PONG"/>
      </map-Value>
     </map-Entry>
     <map-Entry>
      <map-Key>
       <std-String value="responseMessage"/>
      </map-Key>
      <map-Value>
       <std-String value="success"/>
      </map-Value>
     </map-Entry>
    </map-Map>
   </se:pingResponse>
  </soapenv:Body>
 </soapenv:Envelope>


Client side this one returns an empty mapMap.

I'm thinking to add a series of methods to XmlSerializer like serializeSingleNS(Object, Document, Namespace) so this
String xmlResults = SoapSerializer.serialize(serviceResults);
would return a string fully qualified
and then I have just to remove the namespace from the mapMap (the first child of the response)

I'm unsure of the implication of this though.

Actually the entire createAndSendSoapResponse should produce an Axiom OMElement mapMap fully qualified without the need to build a partial DOM response and parse it back don't you think?
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Jacopo Cappellato-4
In reply to this post by Gianluca84
ouch... this mailing list doesn't allow most of the attachments. Here is
the patch:

Index: framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java

===================================================================

--- framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java (revision
1638915)

+++ framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java (working
copy)

@@ -37,6 +37,7 @@

 import org.apache.axiom.om.OMAbstractFactory;

 import org.apache.axiom.om.OMAttribute;

 import org.apache.axiom.om.OMElement;

+import org.apache.axiom.om.OMNamespace;

 import org.apache.axiom.om.impl.builder.StAXOMBuilder;

 import org.apache.axiom.om.util.StAXUtils;

 import org.apache.axiom.soap.SOAPBody;

@@ -245,18 +246,12 @@

             SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();

             SOAPEnvelope resEnv = factory.createSOAPEnvelope();

             SOAPBody resBody = factory.createSOAPBody();

-            OMElement resService = factory.createOMElement(new
QName(serviceName + "Response"));

+            OMNamespace namespace =
factory.createOMNamespace(ModelService.TNS, "se");

+            OMElement resService = factory.createOMElement(serviceName +
"Response", namespace);

             resService.addChild(resultSer.getFirstElement());

             resBody.addChild(resService);

             resEnv.addChild(resBody);



-            // The declareDefaultNamespace method doesn't work see (
https://issues.apache.org/jira/browse/AXIS2-3156)

-            // so the following doesn't work:

-            // resService.declareDefaultNamespace(ModelService.TNS);

-            // instead, create the xmlns attribute directly:

-            OMAttribute defaultNS = factory.createOMAttribute("xmlns",
null, ModelService.TNS);

-            resService.addAttribute(defaultNS);

-

             // log the response message

             if (Debug.verboseOn()) {

                 try {


On Wed, Nov 12, 2014 at 8:38 PM, Gianluca84 <[hidden email]> wrote:

> I think you forgot to attach the patch cos I'm not seeing it...
>
>
>
> --
> View this message in context:
> http://ofbiz.135035.n4.nabble.com/Failed-comunication-between-Axis-server-and-JAX-WSclient-tp4658126p4658128.html
> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Jacques Le Roux
Administrator
In reply to this post by Gianluca84
Not sure it's related (too late to think) but did you read https://issues.apache.org/jira/browse/OFBIZ-4245

Jacques

Le 12/11/2014 21:40, Gianluca84 a écrit :

> Hey thanks! I've got the patch, unfortunately those are the exact
> modifications I already made,
> and they're not sufficient.
>
> *The result is something like this:*
>
>   <?xml version="1.0" encoding="utf-8"?>
>   <soapenv:Envelope
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
>    <soapenv:Body>
>     <se:pingResponse xmlns:se="http://ofbiz.apache.org/service/">
>      <map-Map>
>       <map-Entry>
>        <map-Key>
>         <std-String value="message"/>
>        </map-Key>
>        <map-Value>
>         <std-String value="PONG"/>
>        </map-Value>
>       </map-Entry>
>       <map-Entry>
>        <map-Key>
>         <std-String value="responseMessage"/>
>        </map-Key>
>        <map-Value>
>         <std-String value="success"/>
>        </map-Value>
>       </map-Entry>
>      </map-Map>
>     </se:pingResponse>
>    </soapenv:Body>
>   </soapenv:Envelope>
>
>
> Client side this one returns an empty mapMap.
>
> I'm thinking to add a series of methods to XmlSerializer like
> serializeSingleNS(Object, Document, Namespace) so this
> String xmlResults = SoapSerializer.serialize(serviceResults);
> would return a string fully qualified
> and then I have just to remove the namespace from the mapMap (the first
> child of the response)
>
> I'm unsure of the implication of this though.
>
> Actually the entire createAndSendSoapResponse should produce an Axiom
> OMElement mapMap fully qualified without the need to build a partial DOM
> response and parse it back don't you think?
>
>
>
>
> --
> View this message in context: http://ofbiz.135035.n4.nabble.com/Failed-comunication-between-Axis-server-and-JAX-WSclient-tp4658126p4658130.html
> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Gianluca84
Yes, I've seen it. (that's where I got the link for the RPC-Literal specifications that I posted)
These are the solutions suggested: (quoting)

Daniel Kulp wrote
1) Download the wsdl and edit it to match what the service really produces.  
In this case, all the part names of "parameters" need to be mapped into the
appropriate name.   ("createLearningActivityReturn")    Then use this wsdl
instead of the "live" wsdl.

2) Write an interceptor that would run just before the RPCInInterceptor that
takes the XmlStreamReader and wrappers it with a new XmlStreamReader that
would map the QNames to the expected names.  
As for 1) I don't think it will work in this case, since the problem is that RPC-literal style isn't followed to the standards. Better yet, let's say I don't know how to 'doctor' a wsdl file to get that result.

2) I'm not really sure how to approch this but I suppose that is possible to trasform the response xml using an interceptor to get the result that is expected. I'd prefer a more integrated solution though.
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Jacopo Cappellato-4
Gianluca, when you have a chance please try to apply the patch that I sent
you.

Jacopo

On Wed, Nov 12, 2014 at 11:34 PM, Gianluca84 <[hidden email]> wrote:

> Yes, I've seen it. (that's where I got the link for the RPC-Literal
> specifications that I posted)
> These are the solutions suggested: (quoting)
>
>
> Daniel Kulp wrote
> > 1) Download the wsdl and edit it to match what the service really
> > produces.
> > In this case, all the part names of "parameters" need to be mapped into
> > the
> > appropriate name.   ("createLearningActivityReturn")    Then use this
> wsdl
> > instead of the "live" wsdl.
> >
> > 2) Write an interceptor that would run just before the RPCInInterceptor
> > that
> > takes the XmlStreamReader and wrappers it with a new XmlStreamReader that
> > would map the QNames to the expected names.
>
> As for 1) I don't think it will work in this case, since the problem is
> that
> RPC-literal style isn't followed to the standards. Better yet, let's say I
> don't know how to 'doctor' a wsdl file to get that result.
>
> 2) I'm not really sure how to approch this but I suppose that is possible
> to
> trasform the response xml using an interceptor to get the result that is
> expected. I'd prefer a more integrated solution though.
>
>
>
> --
> View this message in context:
> http://ofbiz.135035.n4.nabble.com/Failed-comunication-between-Axis-server-and-JAX-WSclient-tp4658126p4658138.html
> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Gianluca84
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Gianluca84
In reply to this post by Jacopo Cappellato-4
This is what I ended up doing:

Index: framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java
===================================================================
--- framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java	(revisione 1638710)
+++ framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java	(copia locale)
@@ -37,17 +37,21 @@
 import org.apache.axiom.om.OMAbstractFactory;
 import org.apache.axiom.om.OMAttribute;
 import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
 import org.apache.axiom.om.util.StAXUtils;
 import org.apache.axiom.soap.SOAPBody;
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.soap.SOAPFactory;
 import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+import org.apache.axis2.util.XMLUtils;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.serialize.SerializeException;
+import org.ofbiz.entity.serialize.XmlSerializer;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
@@ -57,7 +61,9 @@
 import org.ofbiz.webapp.control.ConfigXMLReader.Event;
 import org.ofbiz.webapp.control.ConfigXMLReader.RequestMap;
 import org.ofbiz.webapp.control.RequestHandler;
+import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 /**
  * SOAPEventHandler - SOAP Event Handler implementation
@@ -230,33 +236,46 @@
             throw new EventHandlerException("One service call expected, but received: " + numServiceCallRequests.toString());
         }
     }
+    
+    private OMElement buildResponseOMElement(String serviceName, SOAPFactory factory, Map<String, Object> serviceResults) throws DOMException, SerializeException, Exception{
+    	Document document = UtilXml.makeEmptyXmlDocument(serviceName);
+    	Element rootElement = document.getDocumentElement();
+    	rootElement.appendChild(XmlSerializer.serializeSingle(serviceResults, document));
+    	OMNamespace namespace = factory.createOMNamespace(ModelService.TNS,"tns");
 
+    	OMElement rootOM=XMLUtils.toOM(document.getDocumentElement(), true);
+    	rootOM.setNamespaceWithNoFindInCurrentScope(namespace);
+
+    	enforceNameSpace(rootOM.getFirstElement(), namespace);
+    	return rootOM;
+    }
+    
+    private void enforceNameSpace(OMElement element, OMNamespace namespace){
+    	@SuppressWarnings("unchecked")
+    	Iterator<OMElement> allChildren = (Iterator<OMElement>)element.getChildElements();
+    	if(allChildren!=null){
+    		while (allChildren.hasNext()) {
+    			OMElement el = (OMElement) allChildren.next();
+    			el.setNamespaceWithNoFindInCurrentScope(namespace);
+    			enforceNameSpace(el, namespace);
+    		}
+    	}
+    }
+    
     private void createAndSendSOAPResponse(Map<String, Object> serviceResults, String serviceName, HttpServletResponse response) throws EventHandlerException {
         try {
         // setup the response
             Debug.logVerbose("[EventHandler] : Setting up response message", module);
-            String xmlResults = SoapSerializer.serialize(serviceResults);
-            //Debug.logInfo("xmlResults ==================" + xmlResults, module);
-            XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(xmlResults));
-            StAXOMBuilder resultsBuilder = new StAXOMBuilder(reader);
-            OMElement resultSer = resultsBuilder.getDocumentElement();
 
             // create the response soap
             SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
             SOAPEnvelope resEnv = factory.createSOAPEnvelope();
             SOAPBody resBody = factory.createSOAPBody();
-            OMElement resService = factory.createOMElement(new QName(serviceName + "Response"));
-            resService.addChild(resultSer.getFirstElement());
+            OMElement resService=buildResponseOMElement(serviceName + "Response",factory, serviceResults);
+            //Debug.logInfo("resService ==================" + resService, module);
             resBody.addChild(resService);
             resEnv.addChild(resBody);
 
-            // The declareDefaultNamespace method doesn't work see (https://issues.apache.org/jira/browse/AXIS2-3156)
-            // so the following doesn't work:
-            // resService.declareDefaultNamespace(ModelService.TNS);
-            // instead, create the xmlns attribute directly:
-            OMAttribute defaultNS = factory.createOMAttribute("xmlns", null, ModelService.TNS);
-            resService.addAttribute(defaultNS);
-
             // log the response message
             if (Debug.verboseOn()) {
                 try {
<nabble_a href="patchRPC-LiteralFix.txt">patchRPC-LiteralFix.txt</nabble_a>

Not particurarly fond of it but works.
Now I am unsure if it breaks some webservices calls

Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Gianluca84
In reply to this post by Jacopo Cappellato-4
Launched test-result ant target, test results:
Tests 321

Failures 1

Errors 0

Skipped 0

Success rate 99.69%

Time 1326.873

The failed one:
basetests testBasicDisk Failure is-empty

junit.framework.AssertionFailedError: is-empty
        at org.ofbiz.base.util.cache.test.UtilCacheTests.assertHasSingleKey(UtilCacheTests.java:225)
        at org.ofbiz.base.util.cache.test.UtilCacheTests.basicTest(UtilCacheTests.java:301)
        at org.ofbiz.base.util.cache.test.UtilCacheTests.testBasicDisk(UtilCacheTests.java:321)
        at org.ofbiz.testtools.TestRunContainer.start(TestRunContainer.java:147)
        at org.ofbiz.base.container.ContainerLoader.start(ContainerLoader.java:235)
        at org.ofbiz.base.start.Start.startStartLoaders(Start.java:353)
        at org.ofbiz.base.start.Start.start(Start.java:379)
        at org.ofbiz.base.start.Start.main(Start.java:135)
 
I assume that failure is not related to my modifications.
This is the patch that includes the modifications I made for the sendError too:


Index: framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java
===================================================================
--- framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java (revisione 1638710)
+++ framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java (copia locale)
@@ -20,7 +20,6 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.io.StringReader;
 import java.io.Writer;
 import java.util.Iterator;
 import java.util.List;
@@ -30,34 +29,37 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.wsdl.WSDLException;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamReader;
 
 import org.apache.axiom.om.OMAbstractFactory;
-import org.apache.axiom.om.OMAttribute;
 import org.apache.axiom.om.OMElement;
-import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.util.StAXUtils;
 import org.apache.axiom.soap.SOAPBody;
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.soap.SOAPFactory;
 import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+import org.apache.axis2.util.XMLUtils;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.serialize.SerializeException;
+import org.ofbiz.entity.serialize.XmlSerializer;
 import org.ofbiz.service.DispatchContext;
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ModelService;
 import org.ofbiz.service.ServiceUtil;
 import org.ofbiz.service.engine.SoapSerializer;
+import org.ofbiz.webapp.control.ConfigXMLReader;
 import org.ofbiz.webapp.control.ConfigXMLReader.Event;
 import org.ofbiz.webapp.control.ConfigXMLReader.RequestMap;
 import org.ofbiz.webapp.control.RequestHandler;
+import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 /**
  * SOAPEventHandler - SOAP Event Handler implementation
@@ -230,33 +232,46 @@
             throw new EventHandlerException("One service call expected, but received: " + numServiceCallRequests.toString());
         }
     }
+    
+    private OMElement buildResponseOMElement(String serviceName, SOAPFactory factory, Object serviceResults) throws DOMException, SerializeException, Exception{
+     Document document = UtilXml.makeEmptyXmlDocument(serviceName);
+     Element rootElement = document.getDocumentElement();
+     rootElement.appendChild(XmlSerializer.serializeSingle(serviceResults, document));
+     OMNamespace namespace = factory.createOMNamespace(ModelService.TNS,"tns");
 
+     OMElement rootOM=XMLUtils.toOM(document.getDocumentElement(), true);
+     rootOM.setNamespaceWithNoFindInCurrentScope(namespace);
+
+     enforceNameSpace(rootOM.getFirstElement(), namespace);
+     return rootOM;
+    }
+    
+    private void enforceNameSpace(OMElement element, OMNamespace namespace){
+     @SuppressWarnings("unchecked")
+     Iterator<OMElement> allChildren = (Iterator<OMElement>)element.getChildElements();
+     if(allChildren!=null){
+     while (allChildren.hasNext()) {
+     OMElement el = (OMElement) allChildren.next();
+     el.setNamespaceWithNoFindInCurrentScope(namespace);
+     enforceNameSpace(el, namespace);
+     }
+     }
+    }
+    
     private void createAndSendSOAPResponse(Map<String, Object> serviceResults, String serviceName, HttpServletResponse response) throws EventHandlerException {
         try {
         // setup the response
             Debug.logVerbose("[EventHandler] : Setting up response message", module);
-            String xmlResults = SoapSerializer.serialize(serviceResults);
-            //Debug.logInfo("xmlResults ==================" + xmlResults, module);
-            XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(xmlResults));
-            StAXOMBuilder resultsBuilder = new StAXOMBuilder(reader);
-            OMElement resultSer = resultsBuilder.getDocumentElement();
 
             // create the response soap
             SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
             SOAPEnvelope resEnv = factory.createSOAPEnvelope();
             SOAPBody resBody = factory.createSOAPBody();
-            OMElement resService = factory.createOMElement(new QName(serviceName + "Response"));
-            resService.addChild(resultSer.getFirstElement());
+            OMElement resService=buildResponseOMElement(serviceName + "Response",factory, serviceResults);
+            //Debug.logInfo("resService ==================" + resService, module);
             resBody.addChild(resService);
             resEnv.addChild(resBody);
 
-            // The declareDefaultNamespace method doesn't work see (https://issues.apache.org/jira/browse/AXIS2-3156)
-            // so the following doesn't work:
-            // resService.declareDefaultNamespace(ModelService.TNS);
-            // instead, create the xmlns attribute directly:
-            OMAttribute defaultNS = factory.createOMAttribute("xmlns", null, ModelService.TNS);
-            resService.addAttribute(defaultNS);
-
             // log the response message
             if (Debug.verboseOn()) {
                 try {
@@ -285,27 +300,15 @@
         try {
             // setup the response
             res.setContentType("text/xml");
-            String xmlResults= SoapSerializer.serialize(object);
-            XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(xmlResults));
-            StAXOMBuilder resultsBuilder = new StAXOMBuilder(xmlReader);
-            OMElement resultSer = resultsBuilder.getDocumentElement();
-
             // create the response soap
             SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
             SOAPEnvelope resEnv = factory.createSOAPEnvelope();
             SOAPBody resBody = factory.createSOAPBody();
-            OMElement errMsg = factory.createOMElement(new QName((serviceName != null ? serviceName : "") + "Response"));
-            errMsg.addChild(resultSer.getFirstElement());
-            resBody.addChild(errMsg);
+            OMElement resService=buildResponseOMElement(serviceName + "Response",factory, object);
+            //Debug.logInfo("resService ==================" + resService, module);
+            resBody.addChild(resService);
             resEnv.addChild(resBody);
 
-            // The declareDefaultNamespace method doesn't work see (https://issues.apache.org/jira/browse/AXIS2-3156)
-            // so the following doesn't work:
-            // resService.declareDefaultNamespace(ModelService.TNS);
-            // instead, create the xmlns attribute directly:
-            OMAttribute defaultNS = factory.createOMAttribute("xmlns", null, ModelService.TNS);
-            errMsg.addAttribute(defaultNS);
-
             // log the response message
             if (Debug.verboseOn()) {
                 try {
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Jacques Le Roux
Administrator

Le 13/11/2014 10:52, Gianluca84 a écrit :

> Launched test-result ant target, test results:
> Tests 321
>
> Failures 1
>
> Errors 0
>
> Skipped 0
>
> Success rate 99.69%
>
> Time 1326.873
>
> The failed one:
> basetests testBasicDisk Failure is-empty
>
> junit.framework.AssertionFailedError: is-empty
> at
> org.ofbiz.base.util.cache.test.UtilCacheTests.assertHasSingleKey(UtilCacheTests.java:225)
> at
> org.ofbiz.base.util.cache.test.UtilCacheTests.basicTest(UtilCacheTests.java:301)
> at
> org.ofbiz.base.util.cache.test.UtilCacheTests.testBasicDisk(UtilCacheTests.java:321)
> at org.ofbiz.testtools.TestRunContainer.start(TestRunContainer.java:147)
> at org.ofbiz.base.container.ContainerLoader.start(ContainerLoader.java:235)
> at org.ofbiz.base.start.Start.startStartLoaders(Start.java:353)
> at org.ofbiz.base.start.Start.start(Start.java:379)
> at org.ofbiz.base.start.Start.main(Start.java:135)
>  
> I assume that failure is not related to my modifications.
> This is the patch that includes the modifications I made for the sendError
> too:

Yes this happens randomly, though not recently. Do you use the trunk HEAD?

Jacques

>
> Index: framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java
> ===================================================================
> --- framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java
> (revisione 1638710)
> +++ framework/webapp/src/org/ofbiz/webapp/event/SOAPEventHandler.java (copia
> locale)
> @@ -20,7 +20,6 @@
>  
>   import java.io.IOException;
>   import java.io.OutputStream;
> -import java.io.StringReader;
>   import java.io.Writer;
>   import java.util.Iterator;
>   import java.util.List;
> @@ -30,34 +29,37 @@
>   import javax.servlet.http.HttpServletRequest;
>   import javax.servlet.http.HttpServletResponse;
>   import javax.wsdl.WSDLException;
> -import javax.xml.namespace.QName;
> -import javax.xml.stream.XMLInputFactory;
>   import javax.xml.stream.XMLStreamReader;
>  
>   import org.apache.axiom.om.OMAbstractFactory;
> -import org.apache.axiom.om.OMAttribute;
>   import org.apache.axiom.om.OMElement;
> -import org.apache.axiom.om.impl.builder.StAXOMBuilder;
> +import org.apache.axiom.om.OMNamespace;
>   import org.apache.axiom.om.util.StAXUtils;
>   import org.apache.axiom.soap.SOAPBody;
>   import org.apache.axiom.soap.SOAPEnvelope;
>   import org.apache.axiom.soap.SOAPFactory;
>   import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
> +import org.apache.axis2.util.XMLUtils;
>   import org.ofbiz.base.util.Debug;
>   import org.ofbiz.base.util.UtilGenerics;
>   import org.ofbiz.base.util.UtilProperties;
>   import org.ofbiz.base.util.UtilXml;
>   import org.ofbiz.entity.Delegator;
> +import org.ofbiz.entity.serialize.SerializeException;
> +import org.ofbiz.entity.serialize.XmlSerializer;
>   import org.ofbiz.service.DispatchContext;
>   import org.ofbiz.service.GenericServiceException;
>   import org.ofbiz.service.LocalDispatcher;
>   import org.ofbiz.service.ModelService;
>   import org.ofbiz.service.ServiceUtil;
>   import org.ofbiz.service.engine.SoapSerializer;
> +import org.ofbiz.webapp.control.ConfigXMLReader;
>   import org.ofbiz.webapp.control.ConfigXMLReader.Event;
>   import org.ofbiz.webapp.control.ConfigXMLReader.RequestMap;
>   import org.ofbiz.webapp.control.RequestHandler;
> +import org.w3c.dom.DOMException;
>   import org.w3c.dom.Document;
> +import org.w3c.dom.Element;
>  
>   /**
>    * SOAPEventHandler - SOAP Event Handler implementation
> @@ -230,33 +232,46 @@
>               throw new EventHandlerException("One service call expected, but
> received: " + numServiceCallRequests.toString());
>           }
>       }
> +
> +    private OMElement buildResponseOMElement(String serviceName,
> SOAPFactory factory, Object serviceResults) throws DOMException,
> SerializeException, Exception{
> +     Document document = UtilXml.makeEmptyXmlDocument(serviceName);
> +     Element rootElement = document.getDocumentElement();
> +     rootElement.appendChild(XmlSerializer.serializeSingle(serviceResults,
> document));
> +     OMNamespace namespace =
> factory.createOMNamespace(ModelService.TNS,"tns");
>  
> +     OMElement rootOM=XMLUtils.toOM(document.getDocumentElement(), true);
> +     rootOM.setNamespaceWithNoFindInCurrentScope(namespace);
> +
> +     enforceNameSpace(rootOM.getFirstElement(), namespace);
> +     return rootOM;
> +    }
> +
> +    private void enforceNameSpace(OMElement element, OMNamespace
> namespace){
> +     @SuppressWarnings("unchecked")
> +     Iterator<OMElement> allChildren =
> (Iterator<OMElement>)element.getChildElements();
> +     if(allChildren!=null){
> +     while (allChildren.hasNext()) {
> +     OMElement el = (OMElement) allChildren.next();
> +     el.setNamespaceWithNoFindInCurrentScope(namespace);
> +     enforceNameSpace(el, namespace);
> +     }
> +     }
> +    }
> +
>       private void createAndSendSOAPResponse(Map<String, Object>
> serviceResults, String serviceName, HttpServletResponse response) throws
> EventHandlerException {
>           try {
>           // setup the response
>               Debug.logVerbose("[EventHandler] : Setting up response
> message", module);
> -            String xmlResults = SoapSerializer.serialize(serviceResults);
> -            //Debug.logInfo("xmlResults ==================" + xmlResults,
> module);
> -            XMLStreamReader reader =
> XMLInputFactory.newInstance().createXMLStreamReader(new
> StringReader(xmlResults));
> -            StAXOMBuilder resultsBuilder = new StAXOMBuilder(reader);
> -            OMElement resultSer = resultsBuilder.getDocumentElement();
>  
>               // create the response soap
>               SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
>               SOAPEnvelope resEnv = factory.createSOAPEnvelope();
>               SOAPBody resBody = factory.createSOAPBody();
> -            OMElement resService = factory.createOMElement(new
> QName(serviceName + "Response"));
> -            resService.addChild(resultSer.getFirstElement());
> +            OMElement resService=buildResponseOMElement(serviceName +
> "Response",factory, serviceResults);
> +            //Debug.logInfo("resService ==================" + resService,
> module);
>               resBody.addChild(resService);
>               resEnv.addChild(resBody);
>  
> -            // The declareDefaultNamespace method doesn't work see
> (https://issues.apache.org/jira/browse/AXIS2-3156)
> -            // so the following doesn't work:
> -            // resService.declareDefaultNamespace(ModelService.TNS);
> -            // instead, create the xmlns attribute directly:
> -            OMAttribute defaultNS = factory.createOMAttribute("xmlns",
> null, ModelService.TNS);
> -            resService.addAttribute(defaultNS);
> -
>               // log the response message
>               if (Debug.verboseOn()) {
>                   try {
> @@ -285,27 +300,15 @@
>           try {
>               // setup the response
>               res.setContentType("text/xml");
> -            String xmlResults= SoapSerializer.serialize(object);
> -            XMLStreamReader xmlReader =
> XMLInputFactory.newInstance().createXMLStreamReader(new
> StringReader(xmlResults));
> -            StAXOMBuilder resultsBuilder = new StAXOMBuilder(xmlReader);
> -            OMElement resultSer = resultsBuilder.getDocumentElement();
> -
>               // create the response soap
>               SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
>               SOAPEnvelope resEnv = factory.createSOAPEnvelope();
>               SOAPBody resBody = factory.createSOAPBody();
> -            OMElement errMsg = factory.createOMElement(new
> QName((serviceName != null ? serviceName : "") + "Response"));
> -            errMsg.addChild(resultSer.getFirstElement());
> -            resBody.addChild(errMsg);
> +            OMElement resService=buildResponseOMElement(serviceName +
> "Response",factory, object);
> +            //Debug.logInfo("resService ==================" + resService,
> module);
> +            resBody.addChild(resService);
>               resEnv.addChild(resBody);
>  
> -            // The declareDefaultNamespace method doesn't work see
> (https://issues.apache.org/jira/browse/AXIS2-3156)
> -            // so the following doesn't work:
> -            // resService.declareDefaultNamespace(ModelService.TNS);
> -            // instead, create the xmlns attribute directly:
> -            OMAttribute defaultNS = factory.createOMAttribute("xmlns",
> null, ModelService.TNS);
> -            errMsg.addAttribute(defaultNS);
> -
>               // log the response message
>               if (Debug.verboseOn()) {
>                   try {
>
>
>
>
> --
> View this message in context: http://ofbiz.135035.n4.nabble.com/Failed-comunication-between-Axis-server-and-JAX-WSclient-tp4658126p4658146.html
> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Jacques Le Roux
Administrator
In reply to this post by Gianluca84

Le 12/11/2014 23:34, Gianluca84 a écrit :

> Yes, I've seen it. (that's where I got the link for the RPC-Literal
> specifications that I posted)
> These are the solutions suggested: (quoting)
>
>
> Daniel Kulp wrote
>> 1) Download the wsdl and edit it to match what the service really
>> produces.
>> In this case, all the part names of "parameters" need to be mapped into
>> the
>> appropriate name.   ("createLearningActivityReturn")    Then use this wsdl
>> instead of the "live" wsdl.
>>
>> 2) Write an interceptor that would run just before the RPCInInterceptor
>> that
>> takes the XmlStreamReader and wrappers it with a new XmlStreamReader that
>> would map the QNames to the expected names.
> As for 1) I don't think it will work in this case, since the problem is that
> RPC-literal style isn't followed to the standards. Better yet, let's say I
> don't know how to 'doctor' a wsdl file to get that result.
>
> 2) I'm not really sure how to approch this but I suppose that is possible to
> trasform the response xml using an interceptor to get the result that is
> expected. I'd prefer a more integrated solution though.

This solution worked for a client (I did not write the CXF patch nor I have it in hand) but I agree an integrated solution fixing OFBIZ-4245 would be
great!

Jacques

>
>
> --
> View this message in context: http://ofbiz.135035.n4.nabble.com/Failed-comunication-between-Axis-server-and-JAX-WSclient-tp4658126p4658138.html
> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Jacopo Cappellato-4
Gianluca,

I had a cursory review at the OFBiz code you mentioned and there could be
issues; I see that Jacques modified the same code (e.g. in rev. 1243026)
and it may be that the solution he implemented is not generic enough but I
will let Jacques review it and comment before I spend more time on this.

Jacopo

On Thu, Nov 13, 2014 at 11:22 AM, Jacques Le Roux <
[hidden email]> wrote:

>
> Le 12/11/2014 23:34, Gianluca84 a écrit :
>
>> Yes, I've seen it. (that's where I got the link for the RPC-Literal
>> specifications that I posted)
>> These are the solutions suggested: (quoting)
>>
>>
>> Daniel Kulp wrote
>>
>>> 1) Download the wsdl and edit it to match what the service really
>>> produces.
>>> In this case, all the part names of "parameters" need to be mapped into
>>> the
>>> appropriate name.   ("createLearningActivityReturn")    Then use this
>>> wsdl
>>> instead of the "live" wsdl.
>>>
>>> 2) Write an interceptor that would run just before the RPCInInterceptor
>>> that
>>> takes the XmlStreamReader and wrappers it with a new XmlStreamReader that
>>> would map the QNames to the expected names.
>>>
>> As for 1) I don't think it will work in this case, since the problem is
>> that
>> RPC-literal style isn't followed to the standards. Better yet, let's say I
>> don't know how to 'doctor' a wsdl file to get that result.
>>
>> 2) I'm not really sure how to approch this but I suppose that is possible
>> to
>> trasform the response xml using an interceptor to get the result that is
>> expected. I'd prefer a more integrated solution though.
>>
>
> This solution worked for a client (I did not write the CXF patch nor I
> have it in hand) but I agree an integrated solution fixing OFBIZ-4245 would
> be great!
>
> Jacques
>
>
>
>>
>> --
>> View this message in context: http://ofbiz.135035.n4.nabble.
>> com/Failed-comunication-between-Axis-server-and-JAX-
>> WSclient-tp4658126p4658138.html
>> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>>
>>
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Gianluca84
In reply to this post by Jacques Le Roux
Jacques Le Roux wrote
Yes this happens randomly, though not recently. Do you use the trunk HEAD?

Jacques
Actually no, I use branch release13.07
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Gianluca84
In reply to this post by Jacopo Cappellato-4
Ok. Thanks Jacopo!
Oh by the way.. to whom it may concern...it seems that branch release13.07 lacks this jar:
framework\base\lib\avalon-util-exception-1.0.0.jar
Reply | Threaded
Open this post in threaded view
|

Re: Failed comunication between Axis server and JAX-WSclient

Jacques Le Roux
Administrator
This lib was removed with http://svn.apache.org/viewvc?view=revision&revision=r1619043
Why do you need it?

Thanks

Jacques

Le 13/11/2014 11:43, Gianluca84 a écrit :

> Ok. Thanks Jacopo!
> Oh by the way.. to whom it may concern...it seems that branch release13.07
> lacks this jar:
> framework\base\lib\avalon-util-exception-1.0.0.jar
>
>
>
> --
> View this message in context: http://ofbiz.135035.n4.nabble.com/Failed-comunication-between-Axis-server-and-JAX-WSclient-tp4658126p4658154.html
> Sent from the OFBiz - Dev mailing list archive at Nabble.com.
>