I'm trying to use BizTalk for communicating between two web services. It has to be like this:
Service1
gets an input and sends message through BizTalk to Service2
, Service2
responds that message, forwards it to BizTalk, and delivers it to Service1
. Service1
returns the response to user.I'm trying hard to do it for days, but I couldn't manage to build orchestration without compiler errors, and I couldn't find a single piece of example with web services and web ports with typing inputs. I started to believe that this is impossible, at least with BizTalk.
The big question is: Is it possible? If yes, how?
The scope of your question is rather large, and I guess answering it is probably not well suited to the SO "Q+A" format.
However, providing a composite enterprise service which is composed of one or more underlying web services appears to be a common requirement.
I've built a quick and dirty example (BTS 2010 / VS 2010), and uploaded to GitHub here (download the source as a zip on the lower right)
Here's the 'cookbook' of steps taken to implement this from scratch, but I believe that you'll need to obtain the code to follow.
Create a new Solution in Visual Studio
Add a WCF service project and publish to IIS (scope not covered in this sample)
WCFService
basicHttpBinding
for simplicity, but obviously other bindings can be used
(but will require additional concerns such as security etc)NameSpace
on ServiceContract
, ServiceBehavior
, and in the web config for behaviour namespace
have all been set (Otherwise these will default to tempuri
)Add 4 new BizTalk Projects to the solution:
I've call them BizTalkWCF.Orch
, BizTalkWCF.Maps
, BizTalkWCF.WCFPorts
, and BizTalkWCF.Schemas
First is WCFPorts
WCFPorts
project and select "Add" then "Generated Items"http://localhost:57582/Service.svc
)Because we've split the project up in BizTalk (which is generally a good idea), unfortunately the wizard will have marked all the imported artifacts as internal, which isn't very helpful if they are referenced from other assemblies. Open the imported generated Orchestration (MyService.odx) (NB never delete or move this ODX as it contains the generated ports - just leave it with the generated WCF artifacts).
In the orchestration View, at the bottom, open up types. Under Port types, you should see the WCF Interface (IService
). Click it and change the property type modifier to "Public"
Do the same for the Multi-part message types (4 x IService_* - note that there are 2 x message types for each WCF Method on the Service (one for request, one for response).
The WCF Ports project should now build.
Next up is the Schemas project
Add 2 x Schemas representing what will be exposed (published) from the BizTalk (I've called them BizTalkServiceRequest
and BizTalkServiceResponse
)
This sample simply provides a thin façade onto the underlying WCF Service, so I've just got similar fields to the original WCF service on the request and response, with the same xs types. Note however that the concept of an "Entity" on the underlying WCF service has been replaced by request and response messages. It is possible however refactor and reuse common elements in the Schemas (xsd:import) across multiple messages.
I've just used the default namespaces, and 'Root' node, but note that these will be visible to your BizTalk service consumers, so in a real project you'll want to give this more thought.
Note that we haven't reused the imported / generated WCF Service schemas. In a comprehensive enterprise, a 3rd set of schemas can also be used, 'canonical' schemas, which are agnostic of both the formats used by the consumer of the BizTalk service and consumed service (and more maps would have been required as well).
Next up are the maps, between the incoming Request to the WCF Input Schema, and then another map for the Response from the WCF Output schema back to the BizTalk service consumer.
On the map project, add .Net references to both the WCFPorts project and to the Schemas project.
Add a new Map to the Map project
For the Source Schema find the Referenced Schemas - BizTalkServiceRequest schema.
For the Destination Schema, select the WCF Ports schema (the name mangled is awful, but it will be the one with MyService - not the datacontracts or microsoft schemas one). Note that you are then required to select which of the contained schemas you need to use. Select the GetDataUsingContract
schema. Under the elements, drag the mouse from the source Name element to the destination schema value, and from the IsAddSuffix
to the BoolValue
element.
Do the same for the return response message - obviously this time the WcfResponse message is the source, and the exposed BizTalk response is the destination. The boolean isn't useful in the repsonse, so just the string value is mapped.
Maps should now Compile.
Last up is the Orchestration project
Build + Publish
Everything should now build, so its time to publish to BizTalk (I've assumed a local server) For now we'll publish the orchestration using the Wizard, and will use IIS to front the exposed web service, although note that Biztalk can also self host. Remember to set the Application Name in the Deployment tab on all 4 of the Biztalk projects (else they'll wind up in the default app). Also, remember that BizTalk assemblies need to be signed, so create a .SNK (Signing tab)
Right click the solution, and click Deploy. (Note that the project must be built + deployed before you can use the publishing wizard to expose the service)
Assuming a successful deploy, you'll need to configure the orchestration (the other Orch is the one generated by the WCF import - it owns the WCF ports)
Create a send Static Solicit Response Send Port - WCF basicHttpBinding
, point it to your WCF Web Service URL.
You can get the SOAP action from the WCF WSDL e.g. YourNameSpaceHere/IService/GetDataUsingDataContract
Add a Filter to the send port for the message (xmlns#root), e.g., YourNameSpaceHere#GetDataUsingDataContract
Back in Visual Studio, you can now publish the Orch as a WebService (Tools : BizTalk WCF Services publishing Wizard) Enable metadata publishing. I've used basicHttpBinding again. And create the Receive Port, selecting the application (BizTalkWCFSample)
When prompted, select the assembly containing the Orchestrations (BizTalkWCF.Orchs) You will also be prompted to set the target namespace of the WCF service - keep a record of this as if you need to republish your service, you'll likely want to keep the namespace the same.
The location at the end is where it will be published in IIS. Select "allow anonymous access" if you don't want to be bothered with locking the exposed service security. AFAIK there is no way to control the name given to the auto created receive port.
You now need to start up the BizTalk app - address any outstanding config issues (e.g. assigning orchs to processes)
You'll need a new .Net 4 App pool in IIS (Call it something like BizTalkIsolatedHost
),
And then move the wizard created app in IIS to this App Pool
You should now be able to navigate to your Orchestration 'endpoint', e.g.:
http://localhost/BizTalkWCF.Orchs/BizTalkWCF_AddSuffixService_RcvSuffixService.svc
Summing up - was it all worth it?
As you can see from the above, it is quite a lot of work to re-expose a web service in BizTalk, and we haven't really added any value in BizTalk, other than perhaps to have some BizTalk tracking and retry capability :). When orchestrating a composite service (one incoming request requires multiple back end service calls to fulfill, and if using canonical schemas as well), there will be many more schemas and maps to consider, plus additional complexity with the orchestration. And when working with web services, you get a large number of artifacts (schemas, maps, messages, ports etc etc) very quickly, so a strict naming convention is essential.
And we haven't considered things like exception handling, retries, etc.
So, just a sanity check before planning to publish 100's of services in this manner, I guess we need to consider other technology alternatives:
But if there are only a few, high value services like this, especially if such services require composition and mapping of multiple internal services, or use different consumed technologies (SAP RFC, SQL, SOAP, etc) then BizTalk is about right for the job.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With