Creating typed WSDL’s for generic WCF services of the ESB Toolkit
- by charlie.mott
source: http://geekswithblogs.net/charliemott
Question
How do you make it easy for client systems to consume the generic WCF services exposed by the ESB Toolkit using messages that conform to agreed schemas\contracts?
Usually the developer of a system consuming a web service adds a service reference using a WSDL. However, the WSDL’s for the generic services exposed by the ESB Toolkit do not make it easy to develop clients that conform to agreed schemas\contracts.
Recommendation
Take a copy of the generic WSDL’s and modify it to use the proper contracts.
This is very easy. It will work with the generic on ramps so long as the <part>?</part> wrapping is removed from the WCF adapter configuration in the BizTalk receive locations.
Attempting to create a WSDL where the input and output messages are sent/returned with a <part> wrapper is a nightmare. I have not managed it.
Consequences
I can only see the following consequences of removing the <part> wrapper:
ESB Test Client – I needed to modify the out-of-the-box ESB Test Client source code to make it send non-wrapped messages.
Flat file formatted messages – the endpoint will no longer support flat file message formats. However, even if you needed to support this integration pattern through WCF, you would most-likely want to create a separate receive location anyway with its’ own independently configured XML disassembler pipeline component.
Instructions
These steps show how to implement a request-response implementation of this.
WCF Receive Locations
In BizTalk, for the WCF receive location for the ESB on-ramp, set the adapter Message settings\bindings to “UseBodyPath”:
Inbound BizTalk message body = Body
Outbound WCF message body = Body
Create a WSDL’s for each supported integration use-case
Save a copy of the WSDL for the WCF generic receive location above that you intend the client system to use. Give it a name that mirrors the interface agreement (e.g. Esb_SuppliersSearchCommand_wsHttpBinding.wsdl).
Add any xsd schemas files imported below to this same folder.
Edit the WSDL to import schemas
For example, this:
<xsd:schema targetNamespace=http://microsoft.practices.esb/Imports />
… would become something like:
<xsd:schema targetNamespace="http://microsoft.practices.esb/Imports">
<xsd:import schemaLocation="SupplierSearchCommand_V1.xsd"
namespace="http://schemas.acme.co.uk/suppliersearchcommand/1.0"/>
<xsd:import schemaLocation="SuppliersDocument_V1.xsd"
namespace="http://schemas.acme.co.uk/suppliersdocument/1.0"/>
<xsd:import schemaLocation="Types\Supplier_V1.xsd"
namespace="http://schemas.acme.co.uk/types/supplier/1.0"/>
<xsd:import schemaLocation="GovTalk\bs7666-v2-0.xsd"
namespace="http://www.govtalk.gov.uk/people/bs7666"/>
<xsd:import schemaLocation="GovTalk\CommonSimpleTypes-v1-3.xsd"
namespace="http://www.govtalk.gov.uk/core"/>
<xsd:import schemaLocation="GovTalk\AddressTypes-v2-0.xsd"
namespace="http://www.govtalk.gov.uk/people/AddressAndPersonalDetails"/>
</xsd:schema>
Modify the Input and Output message
For example, this:
<wsdl:message name="ProcessRequestResponse_SubmitRequestResponse_InputMessage">
<wsdl:part name="part" type="xsd:anyType"/>
</wsdl:message>
<wsdl:message name="ProcessRequestResponse_SubmitRequestResponse_OutputMessage">
<wsdl:part name="part" type="xsd:anyType"/>
</wsdl:message>
… would become something like:
<wsdl:message name="ProcessRequestResponse_SubmitRequestResponse_InputMessage">
<wsdl:part name="part"
element="ssc:SupplierSearchEvent"
xmlns:ssc="http://schemas.acme.co.uk/suppliersearchcommand/1.0" />
</wsdl:message>
<wsdl:message name="ProcessRequestResponse_SubmitRequestResponse_OutputMessage">
<wsdl:part name="part"
element="sd:SuppliersDocument"
xmlns:sd="http://schemas.acme.co.uk/suppliersdocument/1.0"/>
</wsdl:message>
This WSDL can now be added as a service reference in client solutions.