4

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.
  • Finally 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?

Dijkgraaf
  • 11,049
  • 17
  • 42
  • 54
Ferit
  • 8,692
  • 8
  • 34
  • 59
  • Yes it is possible, but to give you an answer, much more detail is needed. What version of biztalk are you using? What exactly have you tried? What are the errors you see? – David Hall Aug 01 '13 at 13:41
  • Thanks for your answer. I use BizTalk Server 2013. Creating two seperate solutions with web services, then use these services references in BizTalk solution. Errors like: usage of unconstructed message, please specify a correlation set etc. I tried hundreds of times, tried in every way. – Ferit Aug 01 '13 at 13:58
  • In addition, i use .net 3.5 – Ferit Aug 01 '13 at 14:05

1 Answers1

7

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)

  • Used the default VS2010 WCF project, and called the project WCFService
  • Used basicHttpBinding for simplicity, but obviously other bindings can be used (but will require additional concerns such as security etc)
  • Note that the 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

  • Right click the WCFPorts project and select "Add" then "Generated Items"
  • Select Consume WCF Service
  • Check the Metadata Exchange (Mex) Endpoint
  • Provide the URL to your WCF Service (e.g. http://localhost:57582/Service.svc)
  • Leave the namespace (BizTalkWCF.WcfPorts)
  • Complete the wizard - the WCF artifacts should now be present
  • If you need to import more than one Web Service, I would suggest you create separate Visual Studio solution folders for each

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

  • Add reference to the Maps, Schemas and Ports projects
  • Add a new Orchestration (I've called AddServiceOrchestration).
  • You'll need to add an Receive port (added on the left) and Send Port (on the right).
  • Send Port uses the existing imported WCF Port (that we made public earlier). I'll be sending a request and receiving response.
  • Port binding select Direct Binding, and routed by filter expression.
  • For the receive port, you'll need to create a new port type - request response. Receive a request, send a response, and again, Direct binding, with routing via filter expressions.
  • Again, you need to make the Port public
  • You'll need to set the message types on the receive port for both the request and response (click on request and response and then find the message types in the Schemas assembly)
  • The shapes in the orchestration should be self explanatory and straightforward - basically just tie in the ports to receive and send shapes, and then use the maps in transform shapes.
  • The initial receive shape is the activation.

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:

  • BizTalk ESB toolkit (especially if there is a degree of commonality in your enterprise, and / or you have control over the services consumer)
  • Other ESBs (Mass Transit, NServiceBus, ServiceMix etc, or DIY buses built on Camel, Mule, Drools, Rabbit, Windows Service Bus etc), possibly with a custom facade for exposing web services 'end points'
  • For bulk 'service facades', Microsoft started prototyping a promising technology called Managed Service Engine but unfortunately this seems to be on ice.

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.

StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • Thanks for your valuable answer, I'm going to try and share the results. – Ferit Aug 05 '13 at 06:54
  • Yup, that's pretty much it :) There are a couple of 'flavours' - 1) if the services are mostly internal, and homogeneous, then lightweight ESB is usually a better option. 2) MSE tried to solve the issue of versioning, security credential management, and providing SLA's around availability and usage (i.e. legacy SOA management type issues). And 3) providing a composite for data from several back end services can be referred to as "orchestration", which is probably where something like BizTalk makes more sense :) – StuartLC Aug 05 '13 at 11:56
  • 2
    @StuartLC simply... wow... this is one of the largest investments of effort I've seen for a SO answer. Amazingly well done! – David Hall Aug 05 '13 at 15:27
  • Once you've deployed (and exposed the BizTalk service), you can add a consumer (which could be another service, like your `Service1`) - use the `Add WCF Service Reference` wizard once you've deployed the solution and used the publishing wizard to add receive port + IIS facade - you can dig the URL out of published receive location, or by finding it in IIS. – StuartLC Aug 06 '13 at 07:16
  • 2
    @StuartLC just wow for effort! Its guys like you that make SO work :-) – TJ Amas Aug 13 '13 at 23:49
  • Links : [Setting SOAP Action](http://geekswithblogs.net/LeonidGaneline/archive/2011/12/21/biztalk-and-wcf-adapters-operation-and-soap-action.aspx) and [with picture](http://msdn.microsoft.com/en-us/library/bb743856.aspx). Note that there are 2 permissable formats for specifying Soap actions, depending on whether you want to call multiple services on one port or not. – StuartLC Aug 16 '13 at 12:07
  • @StuartLC Don't know if it's important but i get a warning when compiling: BizTalkWCFSample-master\BizTalkWCFSample-master\BizTalkWCF.Maps\ServiceResponse.btm: warning btm1001: The destination node "ResponseMessage" is required but the source node "StringValue" is optional. – Ferit Aug 20 '13 at 07:32
  • @StuartLC I also noticed smth. When i try to run BizTalk app. first time, it says that its not fully configured and makes me to select hosts. In given dropdown menu, there is only BizTalk's BizTalkIsolatedServer. I have to select it, unless that, app. isn't running. So I'm actually hosting the app with BizTalk host, not IIS. – Ferit Aug 20 '13 at 08:21
  • There should be at least one other (non Isolated) Host otherwise BTS won't be able to run. If not you'll need to create one (Host and HostInstance). We usually use separate Send, Receive, Processing and Tracking [hosts as here](http://msdn.microsoft.com/en-us/library/aa577430.aspx) – StuartLC Aug 20 '13 at 08:28
  • @StuartLC I really appreciate your help, spending your time for me. Thanks. I'm going to dig it deep to make it run. If i can't make it run, i may ask for help again :) – Ferit Aug 20 '13 at 10:26
  • @StuartLC It WORKED when i change app pool framework version from 2 to 4. I wonder if i can use this without any client programs, with a web browser only? – Ferit Aug 20 '13 at 11:42
  • @StuartLC If we use web service publishing tool instead of WCF publishing tool, can we use the service with and only with a web browser? – Ferit Aug 20 '13 at 11:56