CXF web service issue when using #WebParam (header=true) - web-services

I need help here. I have at work a CXF web service working really well running in a WebLogic server. I recently was asked to pass some extra parameters (for extra authentication purposes). We want these extra parameters to travel in the header, not as normal parameters.
I have two different scenarios to explain. In fact, in scenario number 1, everything works really well, I am very please with it as my web service received the header parameters and I can validate them. But then, in scenario number 2, in running time, all these new parameters in the header are NULL (and normal parameters are correctly populated!). So I cannot validate the header ones. And I need scenario 2 to work as we want these extra parameters to be in the header.
Why this binding is not working in my second scenario ? there is a bug ? Am I missing something ? Please help me. Here I describe both scenarios with some code for clarification:
1) Here everything works fine. In my cxf-servlet.xml file I have the endpoint defined as:
<jaxws:endpoint id="omniWebService"
implementor="server.com.omnipay.webservice.webService.ServiceImpl"
address="/omniWS" />
And one of the calls that my CXF web service interface is offering is for instance this one where you can see that the 3 first parameters are header=true, not the others.
#WebResult (name="merchantHierarchyParentResponse") MerchantHierarchyParentResponseDTO
getParent(
#WebParam(header=true, name="callerId") String callerId,
#WebParam(header=true, name="timestamp") String timestamp,
#WebParam(header=true, name="signature") String signature,
#WebParam(name="institutionNumber") #XmlElement(required=true) String institutionNumber,
#WebParam(name="clientNumber") String clientNumber,
#WebParam(name="ourReference") String ourReference,
#WebParam(name="accessMerch") String accessMerch
);
That's all. I don't think I need to show more. This is working fine. I deploy in WebLogic and my client or soapUI or debugging or whatever I do, the web service receives all these parameters and I can work with them.
2) The real endpoint I want to use in my cxf-servlet.xml is the following:
<jaxws:endpoint id="omniWebService"
implementor="server.com.omnipay.webservice.webService.ServiceImpl"
address="/omniWS" wsdlLocation="WEB-INF/omniWebService.wsdl">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
And the reason to use this one is because I need a "local" WSDL that I can edit and make changes. This "local" WSDL is the exact WSDL that WebLogic provided me after my first deployment plus adding things like this plus using them instead of type="xs:string":
<!-- Institution Number is a required 8 numeric positions IN parameter -->
<xs:simpleType name="institutionNumber">
<xs:restriction base="xs:string">
<xs:length value="8"/>
<xs:pattern value="[0-9]+"/>
</xs:restriction>
</xs:simpleType>
This is, adding some restrictions so the WSDL will validate the user input. For instance 00000123 is a valid institution number but 000000XX is not.
This functionality works really nice. To be honest, it forces me to maintain a "local" WSDL file which I would prefer not but I didn't find any other way to do it.
And here is where I have my problem. Even if I put as "local" WSDL the exact content of the "automatic" WSDL that WebLogic provided me after deploying (the original without any of my changes!), the result is that in execution time my normal parameters (institution number, client number, etc) are correctly populated but my 3 header parameters (callerId, timestamps and signature) are NULL.
Please any suggestion ? what I am doing wrong ? Both functionalities works very nicely when not working together but the moment I put them together I am having this problem in execution. Why the binding is working fine in scenario 1 but not in scenario 2 ?
thanks

I found the problem. Well, I tried something mad and it works. I put the 3 header parameters at the end, and then it works ! I find this very strange. Why can't I put them on the beginning ? Is it maybe a WebLogic problem ? Am I using old CXF classes with a bug ? Very strange but happy it is fixed now !
#WebResult (name="merchantHierarchyParentResponse") MerchantHierarchyParentResponseDTO
getParent(
#WebParam(name="institutionNumber") #XmlElement(required=true) String institutionNumber,
#WebParam(name="clientNumber") String clientNumber,
#WebParam(name="ourReference") String ourReference,
#WebParam(name="accessMerch") String accessMerch,
#WebParam(header=true, name="callerId") String callerId,
#WebParam(header=true, name="timestamp") String timestamp,
#WebParam(header=true, name="signature") String signature
);

Related

Web service - SOAPui - Receiver Failed to serialize node AXIS2

Hy Guys,
I have a Web service problem. The used environment: SOAP - TOMCAT+AXIS2 - Gigaspace - Magic XPA 3.3
I have made 2 closely same external xpa program what gives back a blob in the Task's property sheet's Return value. It's "answer" back an XML, the simle different is that the first one make (XPA merge) a smaller (18KB) file (from a Filtered DB source), the bigger is write out the whole record aggregation. (1025KB)
When the soap UI receives the first one, everything is fine, i got the result XML on SOAP side. The bigger one shows this error:
With11Endpoint:
<soapenv:Fault>
<faultcode>soapenv:**Server**</faultcode>
<faultstring>**Failed to serialize node**</faultstring>
With12Endpoint:
<soapenv:Fault>
<soapenv:Code>
<soapenv:Value>soapenv:**Receiver**</soapenv:Value>
</soapenv:Code>
<soapenv:Reason>
<soapenv:Text xml:lang="en-US">**Failed to serialize node**</soapenv:Text>
</soapenv:Reason>
The only different is the size of files i think so. I have read some option to solve it like BasicHttpBinding's MaxReivedMessageSize and MaxBuffer size, but i could not find them to change values.
Does anyone have experience in this solutions?
Best Regards,
Gábor
For the future. The XML what has sent contained wrong values. Not tipical XML invalid character, instead an character. So i you have a SOAP error like that, try to Validate your XML file to search an option to solve your problem. ;)

Apache CXF wsdl2java InternalError: unresolved reference

I'm trying to generate Java sources for a Web Service with Apache CXF wsdl2java executable (I've tried 2.7.8 and 3.2.0 versions).
My wsdl file come from an external agency (TMDD), so I assume is well generated
When I tried to generate files first time, a "Non-unique body parts" error occur:
org.apache.cxf.tools.common.ToolException: Non-unique body parts! In a port, operations must have unique operation signatures on the wire for successful dispatching. In port {http://www.tmdd.org/303/dialogs}tmddOCSoapHttpServicePort, operations "{http://www.tmdd.org/303/dialogs}dlVideoSwitchStatusRequest" and "{http://www.tmdd.org/303/dialogs}dlIntersectionSignalStatusRequest" have the same request body block {http://www.tmdd.org/303/messages}deviceInformationRequestMsg
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.validate(WSDLToJavaContainer.java:735)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:276)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:164)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:412)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:105)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:185)
I solved it creating a new input message type in dlVideoSwitchStatusRequest operation to avoid this. My steps were:
Create a new message type
<message name="MSG_VideoSwitchStatusRequest">
<part name="message" element="tmdd:videoSwitchStatusRequestMsg"/>
</message>
Declare videoSwitchStatusRequestMsg
<xs:element name="videoSwitchStatusRequestMsg" type="VideoSwitchStatusRequest">
<xs:annotation>
<xs:documentation>
<objectClass>VideoSwitch</objectClass>
<requirement>REQ1109</requirement>
</xs:documentation>
</xs:annotation>
</xs:element>
This one is defined in .xsd file as similar ones for other operations.
Modify input type for that operation
<operation name="dlVideoSwitchStatusRequest">
<documentation><objectClass>VideoSwitch</objectClass><objectClass>ExternalCenter</objectClass><objectClass>OwnerCenter</objectClass><msgPattern>R-R</msgPattern><requirement>REQ538</requirement></documentation>
<input message="tns:MSG_VideoSwitchStatusRequest"/> <!-- This is the new type -->
<!--<input message="tns:MSG_DeviceInformationRequest"/> This is the old one -->
<output message="tns:MSG_VideoSwitchStatus"/>
<fault name="errorReport" message="tns:MSG_ErrorReport"/>
</operation>
With this, that error was solved (i think), but now i get another error
Exception in thread "main" java.lang.InternalError: unresolved reference
at com.sun.xml.xsom.impl.parser.DelayedRef._get(DelayedRef.java:103)
at com.sun.xml.xsom.impl.parser.DelayedRef$Type.getType(DelayedRef.java:148)
at com.sun.xml.xsom.impl.ElementDecl.getType(ElementDecl.java:110)
at com.sun.xml.xsom.impl.ElementDecl.updateSubstitutabilityMap(ElementDecl.java:174)
at com.sun.xml.xsom.impl.parser.ParserContext.getResult(ParserContext.java:141)
at com.sun.xml.xsom.parser.XSOMParser.getResult(XSOMParser.java:214)
at com.sun.tools.xjc.ModelLoader.createXSOM(ModelLoader.java:538)
at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:269)
at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:95)
at org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:459)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.generateTypes(WSDLToJavaContainer.java:723)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:267)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:164)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:412)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:105)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:185)
This one is too generic and I didn't found any info or doc from Apache site.
First, you must no assume the TMDD wsdl is well generated. I worked with it some time ago and is plenty of errors.
I recommend you to re-create your own version of TMDD.wsdl file, limiting it only to those items you're going to use.
Try that and tell us what you got.
Well, as B. Leal suggest, i drop old tmdd.wsdl and re-do my wsdl files with separate files for each device i will need data for.
As most work has been re-done, i'm not 100% sure about where that error came from, but i'm pretty sure that it was related with some types used in the old wsdl that wasn't declared properly in xsd files.
I know this is not a big help, but if someone falls in this same error, i think you only have two choices:
Re-do your wsdl files, as i did. (I recommend this one, it's easier than it seems)
Check if every single type used in wsdl are present in xsd files and if they're correct.
Thanks for help.
I had the same problem and mine was in XSD. Forgot to add namespace before type. tns and targetNamespace are the same url.
Before:
<xs:element name="getRequest" type="Request">
After
<xs:element name="getRequest" type="tns:Request">
This simple change in all elements using complexType/simpleType fixed the problem.

Calling webservice from voice xml

How I can call webservice from voice xml (vxml) document. I am using an opensource IVR project and I need to run a webservice for any given option from within the vxml document.
This is similar to this query;
how can I call a webservice from voiceXML?
However, solution is provided there but it is not
You cannot call a web service directly from a VoiceXML application. There are generally two approaches for getting data into a VoiceXML application:
Use the data element tag to make an http request. The result must be XML. You will need to parse the result with the provided DOM functions. Note, some browsers have extended features to facilitate XML parsing. This also requires a VoiceXML 2.1 compliant browser.
Transfer control to a dynamic bit of server code that returns VXML to be processed populating your desired variables. This can be done with a goto element or subdialog element.
Your question is incomplete, but I suspect I know what's bothering you.
I get information from a webservice by using
<data name="return_data" srcexpr="some_url" method="post" namelist="var1 var2 var3" />
The data I get back is inside the return_data variable. In my case, the data are in XML format, and I use JavaScript functions to extract the data I need.
As an aside, for maintainability, re-usability, and ease of reading, I personally find it useful to create separate files for the JS functions and include them via <script> into my root VoiceXML document.

Regex filter for mule requester to define relative resource name

When a inbound-endpoint file is received, mule lets us define a regex filter to determine if it's the right file.
<file:inbound-endpoint responseTimeout="10000" doc:name="File" path="${Inbound_Path}" pollingFrequency="${PollingFrequency}" connector-ref="nameConnector">
<file:filename-regex-filter pattern="BOB\d+\.FILE" caseSensitive="true"/>
</file:inbound-endpoint>
Is there a similar function or method where we can do the same thing with the mule requester method. We need to import a file in the middle of our flow process, but the file name is not specifically defined. See below for an example for what I am trying to do.
<mulerequester:request config-ref="muleRequesterConfig" resource="file://${Inbound_Path}/<want to add a regex to define the relative file name>?connector=nameConnector" doc:name="Mule Requester"/>
Basically, we do not know the exact file name because the inbound file gets time stamped every time it is stored into the file system. This makes it hard to provide a specific file address to the mule application.
Does anybody know if we can use some similar regex filter function that mirrors the capability of the file:filename-regex-filter for mule requester.
Update - Per Anton's response, I did the following.
Created the file:endpoint element outside of the flow.
<file:endpoint doc:name="File" name="File_Name" path="Inbound_Path" responseTimeout="10000" connector-ref="FileConnector">
<file:filename-regex-filter pattern="BOB\d+\.FILE" caseSensitive="true"/>
</file:endpoint>
Had the resource attribute reference the file:endpoint element
<mulerequester:request config-ref="muleRequesterConfig" resource="File_Name" doc:name="Mule Requester"/>
You can use a file:endpoint as the resource for mulerequester:request. Just resource="myFileEndpointName".

TrimDuplicates element of Microsoft.Search.Query Webservice causes a FormatException

I'm trying to search through a site collection and find all sites that contain a particular file. TrimDuplicates is supposed to be the right way to do that. I'm calling QueryEx of the WebService object with the following XML as the string argument.
<QueryPacket xmlns='urn:Microsoft.Search.Query'>
<Query>
<TrimDuplicates includeid="false">False</TrimDuplicates>
<SupportedFormats>
<Format revision='1'>urn:Microsoft.Search.Response.Document:Document</Format>
</SupportedFormats>
<Context>
<QueryText language='en-us' type='STRING'>
"filenameForQuery"
</QueryText>
</Context>
</Query>
</QueryPacket>
The response from search.asmx is a 500 error with System.FormatException as the only piece of useful information.
It's only the TrimDuplicates element that is triggering the formatexception. Fiddling the case of the two Falses hasn't had any effect so far.
The answer is actually blindingly obvious - remove the includeid attribute and make the content of TrimDuplicates lower case.
Just wanted to point out that includeid should actually be an integer value.
More here
But as you said, it's not necessary.