wsimport pass no value to an enumerated parameter - soap

I have a SOAP URL with one of the input parameters of enumerated type as below. With SOAPUI I'm just able to remove the ? mark and able to execute the request successfully. <urn:Comm_Source></urn:Comm_Source>
I created client code using wsimport and it creates the input method parameter as CommSourceType object. If I pass null for this value the web service fails.
<xsd:element maxOccurs="1" minOccurs="0" name="Comm_Source" nillable="false" type="s0:Comm_SourceType"/>

There is a lack of information for the complete answer (eg the whole wsdl/xsd or what means: If I pass null for this value the web service fails.).
In general:
null is not the same as an empty string.
<urn:Comm_Source></urn:Comm_Source> - is an empty string
<urn:Comm_Source xsi:nil="true" /> - is a null value (xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance")
the specified element <xsd:element maxOccurs="1" minOccurs="0" name="Comm_Source" nillable="false" type="s0:Comm_SourceType" /> does not support null because there is nillable="false".
The element can either be omitted or an empty string can be written in it.

Related

WSDL contract list occuring with numbers

When I define the fields of a contract in XSD I define a list field with maxOccurs= and minOccurs>0.
Can i declare the XSD in such a way that when the request is received the fields with occurs have occurance number?
e.g.
I hope i make my self clear.
<xsd:complexType name="FieldNameType">
<xsd:sequence>
<xsd:element name="FieldName" type="FieldNameType" minOccurs="1" maxOccurs="8"/>
</xsd:sequence>
</xsd:complexType>
and when the request is send i get something like:
<FieldName_1></FieldName_1>
<FieldName_2></FieldName_2>
<FieldName_3></FieldName_3>
Thanks in advance!
I found a work-around! As i saw i can iterate through the same nodes in an XSLT file.

Creating Soap messages with objectTypes using SUDS library in Robot Framework

i am struggling to create this part of the soap message using robot framework with SUDS library.
<ns1:Request>
<ns0:ID objectType="SomeType">Value</ns0:ID>
</ns1:Request>
If i do like this, then i get all i need but not the objectType.
${object}= Create Wsdl Object ns19:RequestTypeSingle
Set Wsdl Object Attribute ${object} ID 1234
Output
<ns1:Request>
<ns0:ID>1234</ns0:ID>
</ns1:Request>
If i check what my ns19:RequestTypeSingle wants i get this:
${object} = (RequestTypeSingle){
ID =
(ID){
_objectType = ""
}
}
"RequestTypeSingle" definition
<xs:complexType name="RequestTypeSingle">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="ID" nillable="true">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="objectType" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
So how can i declare this "(ID){_objectType = ""} with SUDS or some other?
Thanks to ombre42 this can be done like this (first question answered):
${req}= Create WSDL Object ns19:RequestTypeSingle # may need namespace prefix here
Set Wsdl Object Attribute ${req.ID} _objectType SomeType
(Continuing question).
How ever this will not set the value as i mentioned in my request example. It would seem that this kind of syntax would work but it did not. Any great ideas on this one?
This will give an error: "ValueError: Object must be a WSDL object (suds.sudsobject.Object)."
${req}= Create WSDL Object ns19:RequestTypeSingle # may need namespace prefix here
Set Wsdl Object Attribute ${req} ID 1234
Set Wsdl Object Attribute ${req.ID} _objectType SomeType
And this will overwrite the first _objectType definition.
${req}= Create WSDL Object ns19:RequestTypeSingle # may need namespace prefix here
Set Wsdl Object Attribute ${req.ID} _objectType SomeType
Set Wsdl Object Attribute ${req} ID 1234
What i mean by overwrite is that i get this:
<ns1:Request>
<ns0:ID>1234</ns0:ID>
</ns1:Request>
When assigning a value to property that is expressed as an XML attribute instead of an element, prefix the name with an underscore (why _objectType instead of objectType).
${req}= Create WSDL Object RequestTypeSingle # may need namespace prefix here
Set Wsdl Object Attribute ${req.ID} _objectType SomeType

Mark one of the elements in xsd mandatory (soap) and both element can also be present

I have schema where I want either of element is mandatory and they should not repeat.
EDITED -- Here valid request can contain both query and id in request or with only query or id element is also valid.
e.g:
<soapenv:Body>
<ws:SomeOperation>
<SoapOperation>
<query>test</query>
<id>1</id>
</SoapOperation>
</ws:SomeOperation>
</soapenv:Body>
Valid Requests:
with query and id element.
with only query element.
with only id element.
Invalid Requests:
without query and id element.
with multiple query element.
with multiple id element.
I want query or id must be present. One of them is mandatory.
I tried below things:
<xs:sequence>
<xs:element minOccurs="0" name="id">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element minOccurs="0" name="query">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
Here the problem is none of them is mandatory and making any one as minoccurs=1 will make that field mandatory ( e.g. if i mark id as minoccurs=1 then id field is mandatory but my valid request can have only query and not id) and there can be possibility of both tags to be present as well.
Also I tried choice tag.
Using simple choice with will make these tags repeat which also i do not want. The tag should not repeat.

How to extract JAX-WS #RequestWrapper attribute (or full bean)

Is it possible to extract an attribute (as in XML attribute value) from a RequestWrapper object?
In my implementation, I'd like to use the value of the attribute, but can't reference it with #WebParam, as that is only for elements (I believe)
#SOAPBinding is defined "Document/Literal/Wrapped"
WSDL (relevant sections, target attribute at **):
<s:element name="GetStatus">
<s:complexType>
<s:element minOccurs="0" maxOccurs="1" name="Entity" type="s0:Entity"/>
**<s:attribute name="Handle" type="s:string"/>
</s:complexType>
</s:element>
<s:element name="GetStatusResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="StatusCode" type="s0:StatusCode"/>
<s:element minOccurs="0" maxOccurs="1" name="Server" type="s0:Server"/>
</s:sequence>
</s:complexType>
</s:element>
<message name="GetStatusIn">
<part name="parameters" element="s0:GetStatus"/>
</message>
<message name="GetStatusOut">
<part name="parameters" element="s0:GetStatusResponse"/>
</message>
<portType name="Service">
<operation name="GetStatus">
<input message="s0:GetStatusIn"/>
<output message="s0:GetStatusOut"/>
</operation>
</portType>
SEI abstract method (able to specify XML elements with WebParam):
#WebMethod(operationName="GetStatus")
#RequestWrapper(localName=“GetStatus",className="com.example.GetStatus")
#ResponseWrapper(localName=“GetStatusResponse",className="com.example.GetStatusResponse")
public void getStatus(
#WebParam(name="Entity”)Entity entity,
#WebParam(name="StatusCode",mode=WebParam.Mode.OUT)Holder<StatusCode> statusCode,
#WebParam(name="Server", mode=WebParam.Mode.OUT)Holder<Server> server
);
Implementation:
#Override
public void getStatus(
Entity entity,
Holder<StatusCode> statusCode,
Holder<Server> server
) { ... }
It’s obvious how I can read the value of the #RequestWrapper bean Status (Entity via #WebParam), but is there any way to access the value (Handle) within Status. WebParam, as far as I understand, does not support attributes, only elements.
An alternate way to ask/seek solution might be asking how to access the full bean being referenced by RequestWrapper, in this case GetStatus.
I know if I transition to Document/Literal/Bare I can simply have the parameters and return value reflect the bean, but I'd prefer to solve this using wrapped as all information points to this being the most widely preferred binding.
Self-answered for posterity.
No. To qualify as wrapped style, only elements must be present.
Was reviewing the JAX-WS specification overnight
2.3.1.2 Wrapper Style
A WSDL operation qualifies for wrapper style mapping only if the following criteria are met:
(i) The operation’s input and output messages (if present) each contain only a single part
(ii) The input message part refers to a global element declaration whose localname is equal to the operation name
(iii) The output message (if present) part refers to a global element declaration
(iv) The elements referred to by the input and output message (if present) parts (henceforth referred to as
wrapper elements) are both complex types defined using the xsd:sequence compositor
(v) The wrapper elements only contain child elements, they MUST not contain other structures such
as wildcards (element or attribute), xsd:choice, substitution groups (element references are not
permitted) or attributes; furthermore, they MUST not be nillable.
Non-elements can be present too, as long as they are contained inside an javax.xml.ws.Holder object.

SOAP Response Schema Validation

Short version:
I'm trying to write an XSD that will validate my SOAP service's responses. I feel compelled to just import http:// schemas.xmlsoap.org/soap/envelope/ instead of redefining the SOAP elements like Envelope, Head, and Body, but that xmlsoap.org schema definition of Body is too broad for my use--as soon as I import the SOAP Schema, suddenly my XSD (that I've carefully tailored to my service) validates all SOAP messages.
How should I handle the definition of the SOAP envelope, head, body in my XSD?
I suspect the problem is that I'm trying to re-use other schemas that I shouldn't be trying to re-use. Certainly, those Schemas for SOAP are intended to define what (all) SOAP messages should look like. And maybe I just need to define in my schema what I want my particular soap body to look like.
I might have just answered my own question. Maybe someone has a different solution?
Long version:
I'm having a little trouble authoring an XSD to describe the response message from one of my SOAP services.
Here's an example response from my service that I'm trying to validate:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<helloResponse xmlns="http://justinfaulkner/wsdl/1.0">
<Message>Hello, Justin!</Message>
<Message>Your lucky numbers are: 329, 9</Message>
</helloResponse>
</soap:Body>
</soap:Envelope>
My goal is to validate responses from my service with an XSD.
So, I hand-authored an XSD that describes all the types that belong in my service's soap:Body
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://justinfaulkner/wsdl/1.0" xmlns:tns="http://justinfaulkner/wsdl/1.0">
<xsd:complexType name="helloResponseType">
<xsd:sequence>
<xsd:element name="Message" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="helloResponse" type="tns:helloResponseType"/>
</xsd:schema>
When I tried to validate the example response (first XML snippet) with the Schema (2nd snippet) using PHP's DOMDocument::schemaValidateSource() functionality, the validator pointed out my first obvious mistake:
Element 'soap:Envelope': No matching global declaration available
"Oops, duh," I thought, "Those elements are defined in SOAP's namespace, so I need to import SOAP's XSD."
So I edited my XSD and added an import:
<xsd:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
And it worked! DOMDocument::schemaValidateSource returns true when I validate the soap response with the XSD.
Then, as a sanity check, I took a different soap response XSD I had lying around:
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://justinfaulkner/wsdl/1.0" xmlns:tns="http://justinfaulkner/wsdl/1.0">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
<xsd:complexType name="OtherServiceResponseType">
<xsd:all>
<xsd:element name="CompletionCode" type="xsd:string"/>
<xsd:element name="ResponseMessage" type="xsd:string"/>
</xsd:all>
</xsd:complexType>
<xsd:element name="OtherServiceResponse" type="tns:OtherServiceResponseType"/>
</xsd:schema>
And I tried to validate my soap response with this completely unrelated Schema...
And the schema that, at first glance, doesn't describe this message at all, also validates the soap response.
Then I realize that XSD's Schema must be the reason the response is validating against these two different schemas. The SOAP schema I'm importing from http://schemas.xmlsoap.org/soap/envelope/ defines the Body element to be:
<xs:element name="Body" type="tns:Body" />
<xs:complexType name="Body" >
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" >
<xs:annotation>
<xs:documentation>
Prose in the spec does not specify that attributes are allowed on the Body element
</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>
Which allows the contents of the Body tag to be basically anything.
That makes sense, the purpose of XSD's XSD is to define what ALL XSDs should look like, not just mine.
So my question is, how should I build an XSD to validate these SOAP responses, reusing existing SOAP XSDs if possible?
Here's the direction I've been pursuing...
I guess I could throw xmlsoap.org's XSD schema out the window and redefine Envelope and Body myself, specifying exactly what should show up in the Body element. But I feel like I'll end up basically having a copy of all the soap elements inside my own XSD, with a slightly different Head and Body definition, and that feels like a violation of DRY.
Is there a way I can import xmlsoap.org's XSD but then override the definition of soap:Body from inside my XSD?
You should use a SOAP web service framework to do that. There are many for various programming languages listed on the wikipedia page. You write a WSDL to specify your web service API, and in which you import your XSD to define the payload formats (contract-first approach). Use the wsdl2xxx tool provided by the framework to generate the API stub. You write the API implementation code. The framework will take care of the rest (processing the SOAP messages and binding to your implementation code).