nice article on WSDL design - it makes sense and it's practical...
http://www.ibm.com/developerworks/architecture/library/ar-servdsgn1/
Showing posts with label wsdl. Show all posts
Showing posts with label wsdl. Show all posts
Thursday, December 9, 2010
Monday, December 6, 2010
Non unique body parts!
If you get this message, you better fix it, don't rely on SOAPAction for dispatching. Every operation should have a unique body structure, carrying as root element the operation name.
Most likely, the mistake has been:
declaring multiple wsdl:message with the same "part" structure.
See here for a template you can use to write your WSDL.
I know, WSDL are a pain in the neck, especially the 1.1 version.
Most likely, the mistake has been:
declaring multiple wsdl:message with the same "part" structure.
See here for a template you can use to write your WSDL.
I know, WSDL are a pain in the neck, especially the 1.1 version.
Labels:
wsdl
Wednesday, June 9, 2010
Friday, May 7, 2010
Exception Handling in Web Services.... AKA Web Services suck - big time.
I have a WebService with a WebMethod
@WebMethod
public void updateCompany(Company company) throws CompanyException
where
public class CompanyException extends Exception
this generates this WSDL:
<s0:operation name="updateCompany" parameterOrder="parameters">
<s0:input message="s1:updateCompany"/>
<s0:output message="s1:updateCompanyResponse"/>
<s0:fault message="s1:CompanyException" name="CompanyException"/>
</s0:operation>
______________________
If I have 2 exceptions:
public void updateCompany(Company company) throws CompanyException, NamingException
I get 2 faults
<s0:fault message="s1:CompanyException" name="CompanyException"/>
<s0:fault message="s1:NamingException" name="NamingException"/>
______________________
If I add the annotation javax.xml.ws.WebFault:
@WebFault(name="companyFault")
before the public class CompanyException extends Exception, the WSDL SHOULD become
<s0:operation name="updateCompany" parameterOrder="parameters">
<s0:input message="s1:updateCompany"/>
<s0:output message="s1:updateCompanyResponse"/>
<s0:fault message="s1:companyFault" name="companyFault"/>
</s0:operation>
or something like that.... but unfortunately with WebLogic this doesn't seem to affect the WSDL!
______________________
Anyhow, if you construct the CompanyException without invoking the super(String message) constructor,
you will get this:
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring/>
<detail>
<com:string xsi:nil="true"/>
</detail>
</env:Fault>
</env:Body>
otherwise, if you do super(message),and you invoke
Java:
throw new CompanyException("UNABLE_TO_EXECUTE_SQL")
SOAP Fault:
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>UNABLE_TO_EXECUTE_SQL</faultstring>
<detail>
<com:string>UNABLE_TO_EXECUTE_SQL</com:string>
</detail>
</env:Fault>
</env:Body>
______________________
If your exception extends WebServiceException, AND you do super(message), you get something really exciting:
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>
Failed to invoke end component com.acme.dbaccess.CompanyDBWS (POJO), operation=insertCompany
-> Failed to invoke method
-> UNABLE_TO_EXECUTE_SQL
</faultstring>
<detail>
<bea_fault:stacktrace>
com.acme.dbaccess.CompanyException: UNABLE_TO_EXECUTE_SQL
at com.acme.dbaccess.CompanyDBWS.insertCompany(CompanyDBWS.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
..................
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
</bea_fault:stacktrace>
</detail>
</env:Fault>
</env:Body>
Better still if you use the super(message, Throwable) so you get also the stacktrace of the original exception!
YET the fault generated is not very usable.... the faultstring is very dirty and the faultcode useless....
I need to find a better way of doing this...
______________________
Now, if your service throws an Unchecked Exception (like NullPointerException), you will still get something decent:
Java:
throw new NullPointerException("I am a NPE") ;
SOAP Fault:
<env:Envelope>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>
Failed to invoke end component com.acme.dbaccess.CompanyDBWS (POJO), operation=updateCompany
-> Failed to invoke method
-> I am a NPE
</faultstring>
<detail>
<bea_fault:stacktrace>
java.lang.NullPointerException: I am a NPE
at com.acme.dbaccess.CompanyDBWS.updateCompany(CompanyDBWS.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
..............
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
</bea_fault:stacktrace>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
_____________________________
If I extend CompanyException from SOAPException, I get this fault:
<env:Envelope>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>UNABLE_TO_UPDATE</faultstring>
<detail>
<java:CompanyException/>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
that is, the Fault message is cleary readable (UNABLE_TO_UPDATE) but I have lost the Stacktrace.
_____________________________
On the whole, my impression is that Exception (Fault) generation and handling is, as everything else in WS, very poorly specified and implemented. Compare it to the level of technology in Java and you will only cry and feel lost in hyperspace with WS.
Let's face it, when you come from a Java background, you feel that Web Service technology has been designed by a bunch of fat old drunkards in a brothel running wildly after some young cheerful ladies in pink pajamas... two organs require a lot of blood: the brain and the penis, and we can only operate one at a time.
_______________
It is very educational to look at how a SOAP call is executed inside WebLogic:
JavaClassComponent.invoke(String, Object[], MessageContext) line: 124
ComponentHandler.handleRequest(MessageContext) line: 84
HandlerIterator.handleRequest(MessageContext, int) line: 141
ServerDispatcher.dispatch() line: 114
WsSkel.invoke(Connection, WsPort) line: 80
SoapProcessor.handlePost(BaseWSServlet, HttpServletRequest, HttpServletResponse) line: 66
SoapProcessor.process(HttpServletRequest, HttpServletResponse, BaseWSServlet) line: 44
BaseWSServlet$AuthorizedInvoke.run() line: 285
WebappWSServlet(BaseWSServlet).service(HttpServletRequest, HttpServletResponse) line: 169
WebappWSServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 820
StubSecurityHelper$ServletServiceAction.run() line: 227
StubSecurityHelper.invokeServlet(ServletRequest, HttpServletRequest, ServletRequestImpl, ServletResponse, HttpServletResponse, Servlet) line: 125
ServletStubImpl.execute(ServletRequest, ServletResponse, FilterChainImpl) line: 292
ServletStubImpl.execute(ServletRequest, ServletResponse) line: 175
WebAppServletContext$ServletInvocationAction.run() line: 3498
AuthenticatedSubject.doAs(AbstractSubject, PrivilegedAction) line: 321
SecurityManager.runAs(AuthenticatedSubject, AuthenticatedSubject, PrivilegedAction) line: not available
WebAppServletContext.securedExecute(HttpServletRequest, HttpServletResponse, boolean) line: 2180
WebAppServletContext.execute(ServletRequestImpl, ServletResponseImpl) line: 2086
ServletRequestImpl.run() line: 1406
ExecuteThread.execute(Runnable) line: 201
ExecuteThread.run() line: 173
MOST LIKELY it's the SoapProcessor who maps the Java Exception to the SOAP Fault.... ah, if only I had the source code!
_______________
JAX-WS specs define at least 4 exceptions (see http://www.ibm.com/developerworks/webservices/library/ws-jaxws-faults/index.html):
This post http://io.typepad.com/eben_hewitt_on_java/2009/07/using-soap-faults-and-exceptions-in-java-jaxws-web-services.html is excellent, yet I keep HATING this technology. I am a strong believer of Convention Over Configuration and when I see all the verbosity in WS it makes me mad.
@WebMethod
public void updateCompany(Company company) throws CompanyException
where
public class CompanyException extends Exception
this generates this WSDL:
<s0:operation name="updateCompany" parameterOrder="parameters">
<s0:input message="s1:updateCompany"/>
<s0:output message="s1:updateCompanyResponse"/>
<s0:fault message="s1:CompanyException" name="CompanyException"/>
</s0:operation>
______________________
If I have 2 exceptions:
public void updateCompany(Company company) throws CompanyException, NamingException
I get 2 faults
<s0:fault message="s1:CompanyException" name="CompanyException"/>
<s0:fault message="s1:NamingException" name="NamingException"/>
______________________
If I add the annotation javax.xml.ws.WebFault:
@WebFault(name="companyFault")
before the public class CompanyException extends Exception, the WSDL SHOULD become
<s0:operation name="updateCompany" parameterOrder="parameters">
<s0:input message="s1:updateCompany"/>
<s0:output message="s1:updateCompanyResponse"/>
<s0:fault message="s1:companyFault" name="companyFault"/>
</s0:operation>
or something like that.... but unfortunately with WebLogic this doesn't seem to affect the WSDL!
______________________
Anyhow, if you construct the CompanyException without invoking the super(String message) constructor,
you will get this:
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring/>
<detail>
<com:string xsi:nil="true"/>
</detail>
</env:Fault>
</env:Body>
otherwise, if you do super(message),and you invoke
Java:
throw new CompanyException("UNABLE_TO_EXECUTE_SQL")
SOAP Fault:
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>UNABLE_TO_EXECUTE_SQL</faultstring>
<detail>
<com:string>UNABLE_TO_EXECUTE_SQL</com:string>
</detail>
</env:Fault>
</env:Body>
______________________
If your exception extends WebServiceException, AND you do super(message), you get something really exciting:
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>
Failed to invoke end component com.acme.dbaccess.CompanyDBWS (POJO), operation=insertCompany
-> Failed to invoke method
-> UNABLE_TO_EXECUTE_SQL
</faultstring>
<detail>
<bea_fault:stacktrace>
com.acme.dbaccess.CompanyException: UNABLE_TO_EXECUTE_SQL
at com.acme.dbaccess.CompanyDBWS.insertCompany(CompanyDBWS.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
..................
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
</bea_fault:stacktrace>
</detail>
</env:Fault>
</env:Body>
Better still if you use the super(message, Throwable) so you get also the stacktrace of the original exception!
YET the fault generated is not very usable.... the faultstring is very dirty and the faultcode useless....
I need to find a better way of doing this...
______________________
Now, if your service throws an Unchecked Exception (like NullPointerException), you will still get something decent:
Java:
throw new NullPointerException("I am a NPE") ;
SOAP Fault:
<env:Envelope>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>
Failed to invoke end component com.acme.dbaccess.CompanyDBWS (POJO), operation=updateCompany
-> Failed to invoke method
-> I am a NPE
</faultstring>
<detail>
<bea_fault:stacktrace>
java.lang.NullPointerException: I am a NPE
at com.acme.dbaccess.CompanyDBWS.updateCompany(CompanyDBWS.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
..............
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
</bea_fault:stacktrace>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
_____________________________
If I extend CompanyException from SOAPException, I get this fault:
<env:Envelope>
<env:Body>
<env:Fault>
<faultcode>env:Server</faultcode>
<faultstring>UNABLE_TO_UPDATE</faultstring>
<detail>
<java:CompanyException/>
</detail>
</env:Fault>
</env:Body>
</env:Envelope>
that is, the Fault message is cleary readable (UNABLE_TO_UPDATE) but I have lost the Stacktrace.
_____________________________
On the whole, my impression is that Exception (Fault) generation and handling is, as everything else in WS, very poorly specified and implemented. Compare it to the level of technology in Java and you will only cry and feel lost in hyperspace with WS.
Let's face it, when you come from a Java background, you feel that Web Service technology has been designed by a bunch of fat old drunkards in a brothel running wildly after some young cheerful ladies in pink pajamas... two organs require a lot of blood: the brain and the penis, and we can only operate one at a time.
_______________
It is very educational to look at how a SOAP call is executed inside WebLogic:
JavaClassComponent.invoke(String, Object[], MessageContext) line: 124
ComponentHandler.handleRequest(MessageContext) line: 84
HandlerIterator.handleRequest(MessageContext, int) line: 141
ServerDispatcher.dispatch() line: 114
WsSkel.invoke(Connection, WsPort) line: 80
SoapProcessor.handlePost(BaseWSServlet, HttpServletRequest, HttpServletResponse) line: 66
SoapProcessor.process(HttpServletRequest, HttpServletResponse, BaseWSServlet) line: 44
BaseWSServlet$AuthorizedInvoke.run() line: 285
WebappWSServlet(BaseWSServlet).service(HttpServletRequest, HttpServletResponse) line: 169
WebappWSServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 820
StubSecurityHelper$ServletServiceAction.run() line: 227
StubSecurityHelper.invokeServlet(ServletRequest, HttpServletRequest, ServletRequestImpl, ServletResponse, HttpServletResponse, Servlet) line: 125
ServletStubImpl.execute(ServletRequest, ServletResponse, FilterChainImpl) line: 292
ServletStubImpl.execute(ServletRequest, ServletResponse) line: 175
WebAppServletContext$ServletInvocationAction.run() line: 3498
AuthenticatedSubject.doAs(AbstractSubject, PrivilegedAction) line: 321
SecurityManager.runAs(AuthenticatedSubject, AuthenticatedSubject, PrivilegedAction) line: not available
WebAppServletContext.securedExecute(HttpServletRequest, HttpServletResponse, boolean) line: 2180
WebAppServletContext.execute(ServletRequestImpl, ServletResponseImpl) line: 2086
ServletRequestImpl.run() line: 1406
ExecuteThread.execute(Runnable) line: 201
ExecuteThread.run() line: 173
MOST LIKELY it's the SoapProcessor who maps the Java Exception to the SOAP Fault.... ah, if only I had the source code!
_______________
JAX-WS specs define at least 4 exceptions (see http://www.ibm.com/developerworks/webservices/library/ws-jaxws-faults/index.html):
SOAPFaultExceptionjavax.xml.ws.WebServiceExceptionExecutionExceptionjavax.xml.soap.SOAPException (one is redefined also in XMLBeans)all this is simply ridiculous. Things have seriously gone out of control in WS technology. This post http://io.typepad.com/eben_hewitt_on_java/2009/07/using-soap-faults-and-exceptions-in-java-jaxws-web-services.html is excellent, yet I keep HATING this technology. I am a strong believer of Convention Over Configuration and when I see all the verbosity in WS it makes me mad.
If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization. (Weinberg's Second Law)
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. (Antoine de Saint-Exupery, French writer)
Thursday, May 6, 2010
Documenting your WSDL and WSDs
DocFlex/XML - XSDDoc - XML Schema Documentation Generator
http://www.filigris.com/products/docflex_xml/xsddoc/
The command line options are here
http://www.filigris.com/products/docflex_xml/docs/generator.php#cmdline
A sample "silent mode" generation command line is (for Widows):
@echo off
set JAVA_HOME=C:\bea1035\jdk160_24
set DFH=%~dp0
if %DFH:~-1%==\ set DFH=%DFH:~0,-1%
set JAVA_OPTIONS=-Xms256m -Xmx512m
set CLASS_PATH=%DFH%\lib\xml-apis.jar;%DFH%\lib\xercesImpl.jar;%DFH%\lib\resolver.jar;%DFH%\lib\docflex-xml.jar
"%JAVA_HOME%\bin\java" %JAVA_OPTIONS% -cp "%CLASS_PATH%" com.docflex.xml.Generator -config config/generator.config -nodialog
where the generator.config contains:
#Sat Mar 17 23:41:30 CET 2012
output.dir=../out
output.format=HTML
output.launchViewer=false
template.1=../templates/XSDDoc/FramedDoc.tpl
template.2=../templates/XSDDoc/PlainDoc.tpl
template.3=../templates/XMLDoc/PlainDoc.tpl
template.4=../templates/XMLDoc/FramedDoc.tpl
template.5=../samples/sales/sales.tpl
template.6=../samples/personal/personal.tpl
xml.catalogs=urn\:docflex-com\:xml\:defaultcatalog
xml.files.1=../../acme/sss/ssssvn/SSS_CommonServices/Schemas/Service/ShopOrderService.xsd
xml.files.2=../../acme/sss/nesoawsdl/ShopOrderService.xsd
xml.files.3=http\://www.w3.org/2001/XMLSchema.xsd
xml.files.4=../samples/HumanEvolution/HumanEvolution.xsd
xml.files.5=../samples/sales/sales.xml
xml.files.6=../samples/sales/sales.xsd
xml.files.7=../samples/personal/personal.xml
(this will generate only xml.files.1, all the rest seems to be ignored)
what you need to set is:
output.dir -> where to write the generated HTML
xml.files.1 -> the root XSD to parse
http://www.filigris.com/products/docflex_xml/xsddoc/
The command line options are here
http://www.filigris.com/products/docflex_xml/docs/generator.php#cmdline
A sample "silent mode" generation command line is (for Widows):
@echo off
set JAVA_HOME=C:\bea1035\jdk160_24
set DFH=%~dp0
if %DFH:~-1%==\ set DFH=%DFH:~0,-1%
set JAVA_OPTIONS=-Xms256m -Xmx512m
set CLASS_PATH=%DFH%\lib\xml-apis.jar;%DFH%\lib\xercesImpl.jar;%DFH%\lib\resolver.jar;%DFH%\lib\docflex-xml.jar
"%JAVA_HOME%\bin\java" %JAVA_OPTIONS% -cp "%CLASS_PATH%" com.docflex.xml.Generator -config config/generator.config -nodialog
where the generator.config contains:
#Sat Mar 17 23:41:30 CET 2012
output.dir=../out
output.format=HTML
output.launchViewer=false
template.1=../templates/XSDDoc/FramedDoc.tpl
template.2=../templates/XSDDoc/PlainDoc.tpl
template.3=../templates/XMLDoc/PlainDoc.tpl
template.4=../templates/XMLDoc/FramedDoc.tpl
template.5=../samples/sales/sales.tpl
template.6=../samples/personal/personal.tpl
xml.catalogs=urn\:docflex-com\:xml\:defaultcatalog
xml.files.1=../../acme/sss/ssssvn/SSS_CommonServices/Schemas/Service/ShopOrderService.xsd
xml.files.2=../../acme/sss/nesoawsdl/ShopOrderService.xsd
xml.files.3=http\://www.w3.org/2001/XMLSchema.xsd
xml.files.4=../samples/HumanEvolution/HumanEvolution.xsd
xml.files.5=../samples/sales/sales.xml
xml.files.6=../samples/sales/sales.xsd
xml.files.7=../samples/personal/personal.xml
(this will generate only xml.files.1, all the rest seems to be ignored)
what you need to set is:
output.dir -> where to write the generated HTML
xml.files.1 -> the root XSD to parse
Sunday, May 2, 2010
WebLogic WSDL generation
When WL recognizes a WS as a "WebLogic Web Service", it generates the WSDL in a single .wsdl file.
If it recognizes the WS as a plain "JAX-WS Web Service", it generates a .wsdl file AND a .xsd file with the parameters in the XSD.
Needless to say, I prefer having the parameters factored out in the .XSD file, and using an import:
<types>
<xsd:schema>
<xsd:import namespace="http://ws.testws.com/" schemaLocation="WSExceptionHandlingService_schema1.xsd"/>
</xsd:schema>
</types>
Another difference, for JAX-WS WebLogic doesn't populate the address element in the WSDL.
If it recognizes the WS as a plain "JAX-WS Web Service", it generates a .wsdl file AND a .xsd file with the parameters in the XSD.
Needless to say, I prefer having the parameters factored out in the .XSD file, and using an import:
<types>
<xsd:schema>
<xsd:import namespace="http://ws.testws.com/" schemaLocation="WSExceptionHandlingService_schema1.xsd"/>
</xsd:schema>
</types>
Another difference, for JAX-WS WebLogic doesn't populate the address element in the WSDL.
Labels:
wsdl
Saturday, February 20, 2010
WSDL sucks - anatomy of a WSDL, WSDL for dummies
A very good presentation on the differences between WSDL 1.1 and 2.0 is here
http://people.apache.org/~hughesj/woden/WodenWSDL2Processor_WE12.pdf
This is a sample WSDL 2.0 file:
service has binding, binding has interface, interface has operations, operation has input and output (and fault)
This is the same service in WSDL 1.1 - notice the verbosity compared to 2.0:
service has binding, binding has porttype, porttype has operations, operation has message... what a mess!
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://new.webservice.namespace" targetNamespace="http://new.webservice.namespace">
<wsdl:types>
<xs:schema targetNamespace="http://new.webservice.namespace" elementFormDefault="qualified"/>
</wsdl:types>
<wsdl:message name="NewMessageRequest">
<wsdl:part name="parameter" type="xs:string"/>
</wsdl:message>
<wsdl:message name="NewMessageResponse">
<wsdl:part name="parameter" type="xs:string"/>
</wsdl:message>
<wsdl:portType name="NewPortType">
<wsdl:operation name="NewOperation">
<wsdl:input message="tns:NewMessageRequest"/>
<wsdl:output message="tns:NewMessageResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="NewBinding" type="tns:NewPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="NewOperation">
<soap:operation soapAction="urn:#NewOperation"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="NewService">
<wsdl:port name="NewPort" binding="tns:NewBinding">
<soap:address location="No Target Adress"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I hate WSDL, and the whole XML paraphernalia created to implement distributed computing around the XML paradigm.
I am trying to understand why I hate this entire technology.
Being a Java developer, I like the extreme coherence of Data and Interfaces definitions implemented in Java:
if you break something, you will immediately notice at design time.
With XML and WSDL, you always have the impression of handling a wobbly jellyfish, overly complex and redundant, leaving open holes for ambiguity and crappy implementations.
In fact, in my own experience AXIS2, SOAPUI and Clientgen operate differently, a WSDL which works with the first 2 doesn't work in Clientgen.... CRAP!
http://en.wikipedia.org/wiki/Web_Services_Description_Language
In a WSDL you have DEFINITIONS of public services.
NAMESPACES are used to make names less ambiguous, and should regarded as packages. Their syntax in reality is obscure and ambiguous.
SERVICES are exposed in the service URL; http://host:port/WEB_CONTEXT_ROOT/service
A SERVICE is associated to a BINDING, which defines the protocol (SOAP) and the way to pass arguments (DOCUMENT).
in the BINDING you MAY redefine OPERATIONS, but they are already defined in the PORT TYPE.
OPERATIONS are associated at times with SOAP ACTION.
A PORT TYPE is a misnomer, in WSDL 2.0 it is called INTERFACE, which is what it actually is. It defines OPERATIONS (=method) and their MESSAGES (=parameters).
In TYPES there is the type definition of method parameters.
So all in all you have a very complex and articulated document to do very simple stuff:
defining ENDPOINTS, PROTOCOL, PUBLIC INTERFACES, DATA TYPES
Why all this could not be done in a simpler way....finally leaving the developer to rely on automated tools.... EJB 2.0 reloaded.... we already know that it will all end up in a EJB 3.0 where AT LAST the good stuff is done.... so why not do it since the beginning...
Let's look in Wikipedia the changes made in WSDL 2.0:
- Removal of message constructs
EXACTLY! There should be only OPERATIONS. MESSAGES are useless indirection.
- PortTypes renamed to interfaces
PortTypes are simply a list of Operations... so... call it Interface, no?
- Ports renamed to endpoints.
In fact it simply defines a URL for the Service
Furthermore, some definitions - like endpoint - have been inlined in WSDL 2.0, making the document more compact and readable.
WSDL 2.0 is barely tolerable, WDSL 1.0 is simply outrageous, my grand mother could have done a better job.
UNFORTUNATELY OSB 3.0 doesn't seem to recognize this WSDL 2.0 format, when I try to import the WSLD it complains about:
An error occurred creating the resource:
org.apache.xmlbeans.XmlException: error: The document is not a definitions@http://schemas.xmlsoap.org/wsdl/: document element mismatch got description@http://www.w3.org/ns/wsdl
http://people.apache.org/~hughesj/woden/WodenWSDL2Processor_WE12.pdf
This is a sample WSDL 2.0 file:
service has binding, binding has interface, interface has operations, operation has input and output (and fault)
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:description targetNamespace="http://new.webservice.namespace" xmlns:wsdl="http://www.w3.org/ns/wsdl" xmlns:wsoap="http://www.w3.org/ns/wsdl/soap" xmlns:whttp="http://www.w3.org/ns/wsdl/http" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://new.webservice.namespace">
<wsdl:types>
<xs:schema targetNamespace="http://new.webservice.namespace" elementFormDefault="qualified">
<xs:element name="NewMessageRequest" type="xs:string"/>
<xs:element name="NewMessageResponse" type="xs:string"/>
</xs:schema>
</wsdl:types>
<wsdl:interface name="NewInterface">
<wsdl:operation name="NewOperation" pattern="http://www.w3.org/ns/wsdl/in-out">
<wsdl:input messageLabel="In" element="tns:NewMessageRequest"/>
<wsdl:output messageLabel="Out" element="tns:NewMessageResponse"/>
</wsdl:operation>
</wsdl:interface>
<wsdl:binding name="NewBinding" interface="tns:NewInterface" type="http://www.w3.org/ns/wsdl/soap" wsoap:protocol="http://www.w3.org/2003/05/soap/bindings/HTTP/">
<wsdl:operation ref="tns:NewOperation" wsoap:mep="http://www.w3.org/2003/05/soap/mep/request-response/"/>
</wsdl:binding>
<wsdl:service name="NewService" interface="tns:NewInterface">
<wsdl:endpoint name="NewEndpoint" binding="tns:NewBinding"/>
</wsdl:service>
</wsdl:description>
This is the same service in WSDL 1.1 - notice the verbosity compared to 2.0:
service has binding, binding has porttype, porttype has operations, operation has message... what a mess!
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://new.webservice.namespace" targetNamespace="http://new.webservice.namespace">
<wsdl:types>
<xs:schema targetNamespace="http://new.webservice.namespace" elementFormDefault="qualified"/>
</wsdl:types>
<wsdl:message name="NewMessageRequest">
<wsdl:part name="parameter" type="xs:string"/>
</wsdl:message>
<wsdl:message name="NewMessageResponse">
<wsdl:part name="parameter" type="xs:string"/>
</wsdl:message>
<wsdl:portType name="NewPortType">
<wsdl:operation name="NewOperation">
<wsdl:input message="tns:NewMessageRequest"/>
<wsdl:output message="tns:NewMessageResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="NewBinding" type="tns:NewPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="NewOperation">
<soap:operation soapAction="urn:#NewOperation"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="NewService">
<wsdl:port name="NewPort" binding="tns:NewBinding">
<soap:address location="No Target Adress"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
I hate WSDL, and the whole XML paraphernalia created to implement distributed computing around the XML paradigm.
I am trying to understand why I hate this entire technology.
Being a Java developer, I like the extreme coherence of Data and Interfaces definitions implemented in Java:
if you break something, you will immediately notice at design time.
With XML and WSDL, you always have the impression of handling a wobbly jellyfish, overly complex and redundant, leaving open holes for ambiguity and crappy implementations.
In fact, in my own experience AXIS2, SOAPUI and Clientgen operate differently, a WSDL which works with the first 2 doesn't work in Clientgen.... CRAP!
http://en.wikipedia.org/wiki/Web_Services_Description_Language
In a WSDL you have DEFINITIONS of public services.
NAMESPACES are used to make names less ambiguous, and should regarded as packages. Their syntax in reality is obscure and ambiguous.
SERVICES are exposed in the service URL; http://host:port/WEB_CONTEXT_ROOT/service
A SERVICE is associated to a BINDING, which defines the protocol (SOAP) and the way to pass arguments (DOCUMENT).
in the BINDING you MAY redefine OPERATIONS, but they are already defined in the PORT TYPE.
OPERATIONS are associated at times with SOAP ACTION.
A PORT TYPE is a misnomer, in WSDL 2.0 it is called INTERFACE, which is what it actually is. It defines OPERATIONS (=method) and their MESSAGES (=parameters).
In TYPES there is the type definition of method parameters.
So all in all you have a very complex and articulated document to do very simple stuff:
defining ENDPOINTS, PROTOCOL, PUBLIC INTERFACES, DATA TYPES
Why all this could not be done in a simpler way....finally leaving the developer to rely on automated tools.... EJB 2.0 reloaded.... we already know that it will all end up in a EJB 3.0 where AT LAST the good stuff is done.... so why not do it since the beginning...
Let's look in Wikipedia the changes made in WSDL 2.0:
- Removal of message constructs
EXACTLY! There should be only OPERATIONS. MESSAGES are useless indirection.
- PortTypes renamed to interfaces
PortTypes are simply a list of Operations... so... call it Interface, no?
- Ports renamed to endpoints.
In fact it simply defines a URL for the Service
Furthermore, some definitions - like endpoint - have been inlined in WSDL 2.0, making the document more compact and readable.
WSDL 2.0 is barely tolerable, WDSL 1.0 is simply outrageous, my grand mother could have done a better job.
UNFORTUNATELY OSB 3.0 doesn't seem to recognize this WSDL 2.0 format, when I try to import the WSLD it complains about:
An error occurred creating the resource:
org.apache.xmlbeans.XmlException: error: The document is not a definitions@http://schemas.xmlsoap.org/wsdl/: document element mismatch got description@http://www.w3.org/ns/wsdl
Monday, February 15, 2010
WSDL import and XSD import
http://www.ibm.com/developerworks/xml/library/ws-tip-imports.html
an interesting article on the mysteries of WSDLs... its conclusions are:
an interesting article on the mysteries of WSDLs... its conclusions are:
- It is a good practice to use XSD imports to import schema, and to use WSDL imports to import WSDL.
- It is a good practice to import all of the namespaces that you use.
- An attribute value of the import namespace must match the imported targetNamespace value.
- The primary purpose of an import statement is to import namespaces. The
schemaLocationandlocationattributes, though sometimes necessary, are really only hints.
Labels:
wsdl
Subscribe to:
Posts (Atom)