I have a service that is configured to listen to the default http-gateway with the url pattern "services/*"
<http-gateway name="services" payloadAs="STRING" urlPattern="services/*"/>
When I invoke the service the actions execute as expected expect when when the URL ends with "?wsdl".
When the service is invoked with "?wsdl".The service actions are never invoked (I've set break points with a debugger in addition to using org.jboss.soa.esb.actions.SystemPrintln to confirm this), and the value of "<definitions/>" is returned by the service.
I believe the behavior I am seeing relates to EBWS functionality, where the WSDL is generated from the contract defined for the service (inXsd and outXsd attributes on the actions element in the jboss-esb.xml file). I don't want to use EWBS since I already have a WSDL, and it appears that WSDL files generated EWBS can only ever have one operation per WSDL (since one WSDL is generated per service).
I tried setting the webservice attribute of the "actions" element to "false" to disable the EBWS in hopes to disable this functionality. After setting webservice="false" I tried the URL "/MyEsb/http/services?wsdl" and still received "<definitions/>" as a response, and my action classes were not invoked.
Is there anyway to disable the behavior that is intercepting the urls that end with "?wsdl", or is there a way to configure what WSDL is returned?
Thanks in advance,
- When there is no (wsdl) ContractProvider available to the HTTP gateway, and the URL accessed is http://.../http/category/service?wsdl, the expected behavior is indeed to return an empty <definitions/>. An example of when there would be a ContractProvider available is when you configure a "wsdl" property to the SOAPProxy action.
- When defining an EBWS service (using the inXsd, outXsd and possibly faultXsd attributes), the correct URL to access the WSDL would be http://.../ebws/category/service?wsdl, and yes, we would only be talking about one operation at a time here, with the input and output schema as defined in inXsd and outXsd.
- Links to both of the above are correctly provided by the Contract JSP application ( http://localhost:8080/contract/ ).
- It sounds to me that you would rather provide a different WSDL contract than what EBWS provides for you. But if you want to expose more than one operation here, I question why are you using EBWS to begin with? The purpose of EBWS is to easily "decorate" your ESB as a web service, and all you have to do is provide the expected input, output and (optionally) fault data structures. Again, if you want to do more than that, perhaps EBWS is the wrong solution?
- That being said, I can see that it would be a reasonable JIRA Feature Request so that accessing a URL of http://.../http/category/service?wsdl when there is no (wsdl) ContractProvider available would simply pass right through to execute the service rather than returning an empty wsdl contract. (FYI, this would be a brain-dead simple change.) Of course, we would need to review it publicly as a forum discussion first...
Thank you for the well thought out and put together response!
I've been thinking about your point #4 and maybe I am trying to use the wrong technology. Let me clarify what I'm trying to do.
I'd like to provide a place holder implementation for a web service the ESB will be proxying. Currently the service is not available so I've configured:
- an HTTP gateway to receive the SOAP message
- a content based router (CBR) to route the message to different service for each method
- each one of these service returns a "canned" SOAP response read in from a file
All of this works just fine until I try to proxy the WSDL request for the yet unavailable service. Instead of CBR routing the request to my WSDL service the EBWS functionality is automatically returning an empty service defination.
I'm not trying to use the EBWS functionality just the HTTP gateway functionality. It appears the EBWS functionality is intercepting the http request for the WSDL even when I've configured the actions element to say the service shouldn't be a web service. I hoped by disabling the EBWS functionality the WSDL request would be let through to the CBR (first action in the pipeline).
Another way I could do it is to generate the web service stub from the WSDL, and the stub could delegate the calls to the ESB using the service invoker. I think this would be more work as the "canned" SOAP responses would have to mapped into Java objects (perhaps using SMOOKS) before they are returned from the action pipeline. Then these objects are returned to the stub web service, which in turn returns the objects to web service servlet that turns the Java objects into a SOAP response. Seems like more work (writing SMOOKS scripts) and CPU (XML->Java->XML) cycles to me.
In point #1 you mentioned a ContractProvider. Is there some way I can configure the ContractProvider at the HTTP gateway or the HTTP listener? Perhaps then I could configure a ContractProvider to return a WSDL file of my choosing. This might be a way from me to define my own contract and avoid altering anything. If there isn't way to configure a ContractProvider maybe that is a good JIRA?
- First, a clarrification. There is no point in adding a <http-gateway name="..."/> to a Service which uses EBWS, as EBWS dynamically creates a JBossWS web service, accessible via http://.../ebws/category/service . (WSDL being exposed, as you know, here: http://.../ebws/category/service?wsdl .) It does feel like you using EBWS is the wrong approach here, but more on that in a bit. If you're using EBWS, you should be hitting the service here: http://.../ebws/category/service , not here: http://.../http/category/service .
- Me suggestion before of: "that it would be a reasonable JIRA Feature Request so that accessing a URL of http://.../http/category/service?wsdl when there is no (wsdl) ContractProvider available would simply pass right through to execute the service rather than returning an empty wsdl contract" would be kind of a hack in your case, given my statement in #1 above. Although, I think it would still be better default behavior than the current behavior of returning an empty <definitions/>, so I'll most likely create a jira for that.
- Your statement "EBWS functionality is intercepting the http request for the WSDL" is incorrect. It is actually the HttpGatewayServlet that is intercepting the request. Absolutely nothing to do with EBWS. In the HttpGatewayServlet's service method, it first looks for a query string of ?wsdl (or ?WSDL) and short-circuits to code that depends upon a ContractProvider to have provided the WSDL. Right now the only functionality in JBoss ESB that implements ContractProvider is the SOAPProxy stuff. Other WSDL contracts are published in different ways in JBoss ESB, depending on their type (like EBWS, for example).
- No, there is no way to configure a custom ContractProvider in jboss-esb.xml, at the http-gateway level or anywhere. Technically you could have a custom action in your pipeline that is annotated with a Publisher subclass which also implements the ContractProvider interface, then simply return your own custom WSDL. This is a bit more work than what I will describe next, but it would provide one extra bit of functionality, if you care: your WSDL would show up in the contract JSP application ( http://.../contract/ ). Not sure if that's a requirement for you or not.
- If you don't care about having your custom WSDL show up in the contract application, so long as your custom WSDL is available at http://.../http/category/service?wsdl , then here is a suggestion. First, check out http://community.jboss.org/wiki/HTTPGateway . What you can do is write a custom action that uses HttpRequest requestInfo = HttpRequest.getRequest(message); then use the properties of requestInfo to determine of the user asked for the WSDL (?wsdl), then serve up your custom wsdl yourself, otherwise, use ServiceInvoker to execute another Service defined in jboss-esb.xml that uses the ContentBasedRouter to do as you described above.
Hope all that made sense,