2
votes

Backstory:

I have a WSDL that was created by the customer (non-negotiable) that mixes several web standards into a single service. This one soap service has four soap ports that refer to bindings in referenced (wsdl:import) WSDL files that import XSDs resulting in a dependency tree that is significantly complex.

Since this is done by imports, the top level WSDL isn't that big. WSDL2Java and wsimport choke on it, but I have a library of the schemas compiled into JAXB objects to work with. So I created a CXF service that has all of the required operations and I was able to test it with SoapUI (it imported the top level WSDL fine since it didn't have to make java classes).

Since all the soap ports point to the same address, and that service handles all the operations from the various ports, the client doesn't know that the server thinks all the operations belong to the same port.

Problem:

This breaks down when it comes to CXF generating the WSDL. It puts all the operations on one port with the same namespace. In the customer provided WSDL, the service, ports and bindings are not all in the same namespace. I have tried to supply the service with the WSDL using the @WebService(wsdlLocation="") annotation, but it tries to parse it and match it to the code (as it would in a sane world).

Question:

I would like to intercept/override the http://example.com/service?wsdl operation and return the customer provided wsdl. Is there a way to do this in CXF?

1
An idea rather than an answer - I haven't used CXF but have used XFire (its older incarnation). That was based on a central servlet. Have a look into CXF and see if its the same. You can then hack through the CXF code and see if there's a hook to do this, or alternatively introduce a standard servlet filter or subclass their servlet to allow you to examine each request and run your code if the request URL matches your XXX?wsdl string. Sounds possible, done similar things with XFire.davidfrancis
Try using wsimport to generate JAXB class files as follows: wsimport -extension -XadditonalHeaders -keep -verbose -d <DIR> <WSDL> and see if it generates all your classes for you.Buhake Sindi

1 Answers

2
votes

I ended up splitting the ports out into separate services, but I still needed a custom WSDL that had info for all the ports. The way to do this with CXF is to create an interceptor.

I followed the example of the CXF interceptor that regularly handles WSDL generation: http://grepcode.com/file/repo1.maven.org/maven2/org.apache.cxf/cxf-rt-frontend-simple/2.4.0/org/apache/cxf/frontend/WSDLGetInterceptor.java. I read in my custom WSDL and replace the placeholder hostname with the hostname that comes from the request URL.

You need to then add the custom interceptor when you make your service (I use spring for my configuration). More info on that at http://cxf.apache.org/docs/interceptors.html.