At least one WSDL with at least one service definition needs to be provided - soap

I have defined my service on the WSDL file this way:
<wsdl:service name="guestbook">
<wsdl:port binding="tns:guestbookSOAP" name="guestbookSOAP">
<soap:address location="http://localhost:8080/soapguestbook"/>
</wsdl:port>
Still I am getting the following error message when running wsimport on it:
At least one WSDL with at least one service definition needs to be provided.
Is there anything else I need to add?

The problem in your case is that the definitions element is missing, which is like a root.
WSDL has a specific structure, for which the root element should be the DEFINITIONs, under it various other elements are present like types, messages, portType, binding, services etc.
The structure is like the below:
<definitions>
<types> data type definitions........ </types>
<message> definition of the data being communicated.... </message>
<portType> set of operations...... </portType>
<binding> protocol and data format specification.... </binding>
</definitions>
For the meaning of each WSDL element look into the link:
https://www.w3schools.com/xml/xml_wsdl.asp

Related

Is it possible to pass schemalocation as relative path in wsdl?

I'm using WsdlPull library to parse the WSDL file.
Is it possible to provide relative path in the schemaLocation whiling importing external XSD inside WSDL?
e.g.
<types>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://myprovider/namespace1/namespace1" schemaLocation="schema1.xsd"/>
</schema>
</types>
Schemas should be resolved relative to the containing document (in this case the WSDL's Url), so this should work. In fact we have WSDL files that do exactly what you appear to be trying to do.
However the implementation is given quite a lot of freedom during the resolution process (for example allowing it to transform the url causing it to load from a cache rather than the actual url).
As your positing this I assume this is not working?

Savon SOAP client finds 0 operations on this WSDL

I'm using Savon v 2.3.3 as my Rails application's SOAP client, and it appears to find zero operations on one of the wsdls which I query. (I've had no problems on for other wsdls which my application queries.) When I view the wsdl manually, it appears well formatted, and I find the operations that I seek:
http://dev.service.xrae.com/direct.svc?wsdl
Can you tell me what I need to change or what's unusual about this wsdl?
This wsdl doesn't have 'binding' section. Articles that can help:
http://predic8.com/wsdl-reading.htm
http://www.w3schools.com/webservices/ws_wsdl_binding.asp
Adding
<wsdl:binding name="WSHttpBinding_XraeDirectApi" type="tns:XraeDirectApi">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="AddCase"/>
</wsdl:binding>
can fix it.

Order of unbounded elements in xmlschema sequence

I'm currently developing an application that uses webservices (SOAP 1.2). I'm interested in knowing if I can rely on the order of unbounded elements in a xmlschema sequence. Here is my definition of that sequence in the wsdl I'm using.
<xsd:complexType name="IdList">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="id" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType>
Does that give me any kind of guarantee on the order of the elements? Say this is an excerpt of the associated soap message:
<web:globalRecipientIds>
<!--Zero or more repetitions:-->
<web:id>1</web:id>
<web:id>15</web:id>
<web:id>7</web:id>
</web:globalRecipientIds>
Does that mean that the receiving end will treat it in the order that it appears in the SOAP message? Is this something that depends on the implementation of the receiving end? If it does, I generated the receiving end using wsdl2java from apache axis to generate the java code from the wsdl file. Can you tell me something specific about this?
The order of XML elements is significative - regardless of the schema - e.g.
<web:globalRecipientIds>
<web:id>1</web:id>
<web:id>15</web:id>
<web:id>7</web:id>
</web:globalRecipientIds>
and
<web:globalRecipientIds>
<web:id>15</web:id>
<web:id>1</web:id>
<web:id>7</web:id>
</web:globalRecipientIds>
are two different XML, and XML tools (should) preserve and recognize the order of elements.
Having said that, this does not guarantee that 'the receiving end will treat it in the order that it appears in the SOAP message' - depends on what the receiving end does with the XML. It receives an ordered list of ids, but if (for example) puts those ids in a dictionary or some other hashed structure the order is lost.

AXIS SOAP wsdlPortType

What do these parameters do and what are they used for?
<service name="...">
<parameter name="wsdlPortType" value="..."/>
</service>
Also, if anyone can explain the parameters wsdlServicePort, wsdlTargetNamespace, and wsdlServiceElement, that would be appreciated.
Axis 1.4 User's Guide:
When you deploy a service in Axis, users may then access your
service's URL with a standard web browser and by appending "?WSDL" to
the end of the URL, they will obtain an automatically-generated WSDL
document which describes your service.
Experimental results suggest that Axis is able to use a combination of the .wsdd deployment descriptor file and compiled Java .class files to generate the corresponding .wsdl for a given service. It's interesting to note that, for example, if you have a public method with a Generics return type such as Map, your generated .wsdl file will not contain the return type - it will contain "xsd:anyType" instead. I believe this is due to type erasure on the compiled .class file.
Anyway, the service options in the Axis .wsdd file (the parameters I referenced in my question such as wsdlPortType, wsdlServicePort, and wsdlTargetNamespace) are related to the .wsdl specifications. This can be inferred from the names themselves since they all contain 'wsdl' in them, but I wanted an explanation of what these parameters mean and I was unable to find relevant Axis documentation. Here are my findings:
wsdlPortType (portType): basically like a Java interface. Contains one "operation" element for each method name. Each "operation" contains "input" and "output" elements that are basically your input parameters and return parameter of the Java method.
wsdlServicePort (wsdl:binding) Associated with the portType. I think of it as a description of how to transmit the parameters for the portType. The spec has this to say:
A binding description component provides a framework for indicating
binding details for a portType description component. Binding details
SHOULD be used to indicate how messages MUST be formatted when they
are sent to or from the service. They SHOULD also be used to indicate
the transport protocol to be used to send the messages. A given
binding description component MUST NOT indicate more than one
protocol.
wsdl:service: Has a reference in it to the wsdl port binding (the implementation of the portType).
target namespace: Pretty much what I thought it was (same as a namespace anywhere else). It applies to all of the wsdl:definitions components, so anything in the wsdl file basically (wsdl:portType, wsdl:service, etc). There are a couple other rules that you can find in the spec though.
Problem:
When using Service?wsdl, the generated wsdl may not have
the same targetNamespace, portType, service element name, or
service port name as the original wsdl. This problem has
been reported by users and is a TCK issue.
Solution:
Four optional parameters are added to the deploy.wsdd and
queried by the JavaProvider (wsdlTargetNamespace, wsdlServiceElement,
wsdlServicePort and wsdlPortType).
Here is an example deploy.wsdd with the new parameters.
<!-- Services from AddressBookService WSDL service -->
<service name="AddressBook" provider="java:RPC">
<parameter name="wsdlTargetNamespace" value="urn:AddressFetcher2"/>
<parameter name="wsdlServiceElement" value="AddressBookService"/>
<parameter name="wsdlServicePort" value="AddressBook"/>
<parameter name="className" value="samples.addr.AddressBookSOAPBindingSkeleton"/>
<parameter name="wsdlPortType" value="AddressBook"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Session"/>
Source: http://mail-archives.apache.org/mod_mbox/axis-java-dev/200206.mbox/%3C20020621143740.41268.qmail#icarus.apache.org%3E

RESTful way to return location information

I have written a REST server based on RESTEasy.
In some of the resources, collections of objects are returned instead of single objects: the method that responds to the URL "/users/{user_id}" returns a single "user" object, but the method that responds to the URL "/users" returns all users. In the former case, I can include an HTTP header "Content-Location: URL" (although this is redundant since the caller has the correct URL). In the latter case, each item in the returned collection has its own location. I was thinking of added an XML attribute to each item specifying its location:
<users>
<user location="/users/1234">
...
</user>
<user location="/users/5678">
...
</user>
</users>
Is there some conventional way of returning this information?
This is a very common practice when designing hypermedia APIs. It is also highly recommended. There is no official "right" way of doing it, however one media type that has very explicit rules as to how you can do it is hal. See http://stateless.co/hal_specification.html
In hal your document would look like:
<resource href="/users">
<resource rel="item" href="/users/1234">
...
</resource>
<resource rel="item" href="/users/5678">
...
</resource>
</resource>
I picked the term "item" because it has been psuedo standardized, but you could put your own link relation, there are just a few rules you should follow when identifying your own link relations. (See RFC5988 for details)