We are developing an MDA platform that has support for Web Services. The user can provide a WSDL in runtime and we generate all the artifacts (service interface and implementation for the server, and consumer for the client) using JAX-WS internally.
We want to add validation on the WSDL document provided by the user. Right now the user has to validate that with an external tool like Oxygen, XMLSpy or a web tool, but we want to add that as a part of our system. A nice-to-have feature would be schema validation aswell, including the embedded schemas of the WSDLs.
In JAX-WS (RI) there is support for schema validation in runtime (using the #SchemaValidation annotation) but we haven't found any support for WSDL validation.
We've tried to integrate Eclipse's WSDL validator but it doesn't seem to work for us.
Is there any way of doing this with JAX-WS?
If not, is there any other validation framework that we can integrate?
Thanks
There is a bit of confusion in your question that I need to clarify first.
You seem to want the ability to validate the WSDL (syntax + WS-I) and XSDs, either embedded or referenced externally by the WSDL. On the other hand you bring in #SchemaValidation, which is actually used to validate instance documents.
In a traditional development approach, one might say you want at least the ability to validate design-time artifacts (WSDL+XSDs).
For this scenario then, I would recommend the following:
WSDL: for WS-I compliance testing, please take a look at the test tools section of the WS-I site. It is not clear how the licensing they have with their test tooling would work with yours, but at least it should give you an idea for what to look if it doesn't work for you.
UPDATE: Additional WSDL validation resources:
- Eclipse based, how to use outside Eclipse.
XSDs: if you really need separate validation for XSD files, things may get tricky for a production quality product; WSDL4J is not much help here, and I believe XSOM is the way to go for this kind of job. You have to extract content from the types section as one or more XSD files (could be more than one XSD file, take a look at some examples, Microsoft's SharePoint WSDLs come to my mind as a good test case), assign a base uri for each extracted XSD that matches the WSDLs location, then use XSOM to validate those.
Since you're generating the client, you're most likely not concerned with validating, say of the HTTP headers (SOAP 1.1/HTTP, SOAPAction, if it matches the WSDL operation definition). If you end up developing an interest in that as well, which I call runtime validation, then I would recommend a different layout in your approach (i.e. I would not rely on #SchemaValidation but rather do it through a transparent, and generic, proxy service).
Related
My messaging provider gives me two different kinds of WSDLs to use.
http://my.amazonaws.com:8000/webservice/?wsdl
http://my.amazonaws.com:8000/webservice/?singleWsdl
The first one is an embedded WSDL. Can NOT use it to generate WSDL2java packages and
can NOT use JAX-WS to create a connection.
The second one is a single WSDL. It can generate Java packages with CXF 3.0's WSDL2java and can use JAX-WS to create a connection. It works very well.
Please let me know what is the difference between these two kinds of WSDLs.
Without knowing what those links return we can only guess, but here are some details that might help you....
Suffixing the web service endpoint with ?wsdl get's you a WSDL file. The WSDL can be generated by the framework at runtime based on the web service skeleton code or can be an actual physical file that the server just sends back when the URL parameter is specified.
The WSDL contains an XML Schema that can be specified either inside the WSDL itself or as separate files that are imported by the WSDL. And now a problem occurs...
Some web service stub generators can only handle a full WSDL, with the Schema inside. If the WSDL imports other files the tools can't resolve the imports and fails. This made web services hard to consume because clients had issues creating stubs to interact with the web service. So much so that service providers either used an actual WSDL to respond to the ?wsdl request or started writing all sorts of hacks and plugins to make the web service generate the full WSDL.
But some providers didn't even bother so clients had to write the hacks to parse the WSDL or they had to download all files, assemble them manually into a single file and use that instead.
With time people recognized this as a problem and frameworks adapted to provide the full WSDL, not one with imports. But this generated another problem. Changing what the ?wsdl URL returned could break all those hacks created around it to fix the import problem. For this reason another convention was chosen to return the full WSDL: ?singleWsdl.
So there are frameworks that generate a full WSDL, some that generate it with imports, some allow you to specify an actual physical file, some that support the ?singleWsdl convention, some that don't. Not relevant to this question, but just for completion, there is also a ?wsdl2 convention that get's you a WSDL 2.0 definition (?wsdl get you a WSDL 1.1). Some frameworks support ?wsdl2, some don't.
My guess is the issues you have are caused by Schema imports, but without the WSDLs themselves I can't tell. Hope at least that these details help you better identify the problem.
Is it mandated by any standard that a web service should provide a WSDL by appending ?wsdl to the endpoint address?
Is it OK if the WSDL is hosted at a different URL (without appending ?wsdl)?
For example:
Endpoint: http://abc.xyz.com/MyService
WSDL: http://abc.xyz.com/MyServiceDefinition.pqr
Note that I'm even using a different extension for the WSDL definition.
Does using this approach violate any standards or one can host the thing the way they want?
Is it mandatory to have a WSDL definition accessible using ?wsdl?
No, it's not.
A WSDL is used to describe a web service contract and is provided because it allows tools to automate generation of client stub code for calling the specified web service. Exposing the WSDL at the same location as the web service with ?wsdl appended to it is just very handy and that's the convention everybody uses.
People and tools look for the WSDL at that location and frameworks automatically expose it at that location but it's just a convention. As to my knowledge this isn't specified in any specification (or at least none that I could find).
Sometimes though you don't want to provide a WSDL that everybody can look at and try to create a client because it's a private web service and you only want to give access to your partners, not to everybody. At that point you can disallow the ?wsdl URL and provide the WSDL only to your partners by using an alternative channel. You can even e-mail it if you don't want it exposed online.
So you can choose whatever channel to expose it. Just remember that because people and tools are following this convention they are used to see it there and some (poorly written) tools might choke in a different extension, for example.
P.S. One other thing I wanted to mention - which isn't strictly related to this answer but kinda reinforces the convention - is the new ?singleWsdl option in WCF 4.5.
WCF, as most other tools, exposes the WSDL at the ?wsdl address but uses xsd:import statements with external schemas. Some frameworks were not able to process WSDL with imported dependencies so people started to write customizations over WCF to have a flat WSDL exposed, so much so that in the latest version of WCF Microsoft decided to add this feature out of the box.
But for backward compatibility they needed to keep the ?wsdl endpoint as it was (returning a WSDL document with xsd:import statements inside) and were forced to add a new query parameter for the flat WSDL: ?singleWsdl. I'm sure this idea will be picked up by other web service vendors and providers as well.
No, Its not mandatory to have ?wsdl access, but its recommended way.
Its worth noting that most clients will try to append "?wsdl" to your URL and will try to access WSDL file, Hence its highly recommended to setup it.
What is the reason why hitting, for example, http:///_vti_bin/UserGroup.asmx?wsdl gives me a not full wsdl specification (if compared with http://msdn.microsoft.com/en-us/library/dd965659%28v=office.12%29.aspx)?
What I mean about not full: it does not contain some of complex types definition, e.g. User (unlike the full one), so this types are no generated by the wsdl.exe.
I have a question in regard of this: is it safe to generate c# web service stub basing on specification from MSDN or this approach is dangerous due to possible changes in contract?
For your first question as to the WSDL not being the same: it really should be equivalent and contain all the types! Whenever you append /_vti_bin/UserGroup.asmx?wsdl to your site's URL, SharePoint should definitely display the FULL WSDL, including the complex type definitions, etc. I just tried it now against my own SharePoint instance and the WSDL returned from http:// mysite.com/ ...snip... /pierre/_vti_bin/UserGroup.asmx?wsdl is pretty much the same size as the one from http://msdn.microsoft.com/en-us/library/dd965659%28v=office.12%29.aspx and a quick check to make sure complex types are in both places confirm that.
To answer your second question: I think you should NOT create your Web Service stubs and skeletons based on the WSDL in the documentation. Instead use the WSDL returned from your site. If you're not getting all the complex types in the WSDL returned from SharePoint, you should fix that issue first.
First thing I would try: download SOAPui (free) and simply plugin the URL that ends with ?wsdl and create sample requests. Maybe you'll run into access issues (UAG or other) but at least you'll know that the WSDL is well formed. If SOAPui can generate the client code based on the WSDL, you can too (using wsdl2java or the wsdl2dotnet equivalent; I can't remember the name of the .net version).
And yes, it's dangerous to copy the WSDL from the docs but I'd be more worried about some things being abbreviated or documentation going stale, etc.
As for the contract changing, I'm using the UserGroup.asmx?wsdl endpoint since 2009 and it still works on newer versions of SharePoint (even after the upgrade to SP2010). And I'm using java as the client code. Microsoft really nailed the Web Services in SharePoint, it was surprisingly easy to integrate our java stack and make calls to/from the SharePoint web services. And it was also very inter-operable with the other tools we use to test Web Services like SOAPui, etc.
I need to use the SOAP service of a printer. There is a windows tool to access this service and I used it to generate SOAP requests and responses of the important functions that I need.
Now I should write a client for Linux using Python and I found the easiest way would be to use the suds library with an WSDL file. But I don't have this WSDL!
As I investigated the windows tool (looked at the hexdump of the executables), I came to the conclusion that there probably is no WSDL file at all.
Now my question is, has anybody experience with "reverse engineering" SOAP services and knows tools which could be useful for creating WSDL files for existing services? (Googleing hasn't brought up anything useful yet).
You mentioned this is the SOAP service of a printer. Is the printer's API documented on the manufacturer's site? Does the documentation include the WSDL? Can you get the WSDL from the manufacturer?
If you can get the WSDL from the manufacturer then you're done!
If not, then you have to build the WSDL by yourself because I doubt you can find a tool that generates WSDLs given SOAP samples (when working with SOAP web services you mainly get two kinds of tools: those that generate code from WSDL + those that generate WSDL from code).
It's not hard to create the WSDL if you are familiar with SOAP, WSDL and XSD. You just need a text editor or maybe even a WSDL editor to speed things up.
If you don't have full confidence in your WSDL knowledge, there are still some tools that can get you most of the way to the complete WSDL. Here is a way you could do it:
1 - First you need to create the XML schema for the SOAP payloads. For this you can find tools, even some online. After you have the schema, tweak it to your needs by adding, changing or removing elements.
2 - Now you can use the XSD to generate a WSDL. There is an online tool that does that. It just needs the request/response element types to end with Request/Response. Make sure you read the instructions.
You take your XSD file, change the names of the operations to add the Request/Response suffix and feed it to the WSDL Generator - Web Tool. You will get your WSDL.
Now tweak this WSDL as you like (remove the Request/Response suffixes if you don't need them) then ...
3 - ... make sure you end up with a valid WSDL.
4 - Now you can take your WSDL and use a tool like SoapUI to generate sample requests and responses from it just to verify that you get the proper results back.
Do the SoapUI messages match the messages you started with? If yes, you are done and can feed the WSDL to suds to create the Linux client. If not, tweak the WSDL until you get the result you are after.
I used WCF to create a restful web service in .NET, by means of a .svc file. The web application automatically produces a WSDL file. AFAIK, the WADL is more natural for a restful web service.
How could I create a restful service in .NET (preferably with wcf) that produces a WADL description?
Note An answer like "RTFM" is accepted, as long as you indicate a suitable manual/tutorial.
This is an old question but having consumed restful services with WADLs they do offer some value. You can import them straight into SOAPUI and it will build a test suite for you automatically. Secondly they tend to contains all the required XSDs for XML based services and are useful for automatically building serialisable classes that your endpoints accept and receive.
Looks like REST Describe & Compile should do the trick.
On the WADL developer site Marc Hadley
maintains a command line tool named
WADL2Java. The ambitious goal of REST
Describe & Compile is to provide sort
of WADL2Anything. So what REST
Describe & Compile does is that it:
Generates new WADL files in a completely interactive way.
Lets you upload and edit existing WADL files.
Allows you to compile WADL files to source code in various programming
languages.
Forgive me for answering a question with a question, but do you really want to do REST? REST really has no need for things like WADL.
Update:
The "hypermedia constraint" (aka HATEOAS) dictates that the user agent discovers content based on links embedded in previously retrieved content. It really is unnecessary to have a separate document that describes all the available content.
Imagine using a web browser to go to a site and instead of going to the home page and navigating from there, you are presented with a page which is a list of all the URLs on the site. You must then looks through the list of available urls, choose the one you are interested in and copy it into the address bar.
WADL is effectively you list of site urls. You just don't need it if your main content is linked together.
Linking content instead of using a WADL "site map" has other advantages. The available links can be dynamic based on particular data values in the content. This capability can vastly reduce the complexity of clients, because the client no longer needs to host the logic to decide when it is allowed to follow a link.