I am new to BizTalk development. I have an existing SOAP web service, which has around 50 different operations. I want to connect this service to another application, but use the BizTalk server as an intermediary in this communication. So service and application should not know each other directly, BizTalk should be able to log all messages going through etc etc.
What is the best approach to make this work in BizTalk Server 2013?
So far I tried to create a new BizTalk Application and import the SOAP web service there. Then however it seems that I need to create around 50 different orchestrations, each one just mapping the incoming message in BizTalk to the external service for each service operation. This seems very cumbersome. Also publishing all those orchestrations becomes painful, as BizTalk cannot merge those into a single endpoint again. Ideally I would like to publish a single endpoint for BizTalk server on IIS that is using the exact same WSDL as the target SOAP service, ideally without having to create any orchestrations at all. Is this possible?
Thanks!
So, yes, but...what you want is absolutely doable but there would be lots of answers for that. Once you learn how things in BizTalk are actually working, it's obvious how to do this.
For example, a single Receive Location (IIS endpoint) can receive any number of request types provided they are the same protocol/format, SOAP, REST/JSON for example. The only difference in the IIS site is any metadata, so just don't publish that. The Message differentiation is done in the Pipelines just like any other BizTalk Message.
You don't really need Orchestrations for Maps, you can apply those at the Port Level provided it's a 1-1 relationship between the SOAP call and Map.
Please try a few things. I'll become clear. You can always come back for any specific issues.
Related
I'm a bit confused on what the biztalk wcf publishing wizard produces?
So for example, I have a simple biztalk project that takes a Input xml file, maps it, and outputs to another folder.
Can i use the wcf publishing wizard to create a webservice to pass in and out an xml to the solution?
Yes you can. WCF Publishing wizard is for this purpose. You can either expose your schema as a service or your Orchestration. It has few options to choose e.g. whether you want to use BasicHttpBinding, WSHttpBinding or custom. You should have a local IIS configured for this. It will also create a receive location in BizTalk to receive the message from IIS service and return the response.
More details about it can be found on http://msdn.microsoft.com/en-us/library/bb226547.aspx
To answer your specific question, yes, you would 'publish' the schemas.
To note, there is no difference in the output of either option. Publishing an Orchestration merely reads some metadata from the compiled Assembly. If you set the same values when publishing 'Schema', the output metadata will be the same.
Also note, the IIS endpoint is completely schema agnostic, meaning it makes no attempt to validate the messages it receives or sends, regardless of what Schemas or Orchestration Port you 'publish'.
Is it possible to use Biztalk internal functions to perform the following task, instead of writing a custom program?
Regularly extract XML from another website to the Biztalk receive location and further process by Biztalk.
Thanks.
BizTalk Server out of the box does not provide a way to poll http endpoints.
For that, you would use the Scheduled Task Adapter (http://biztalkscheduledtask.codeplex.com/).
I'm working on a web service that uses ASP.NET security model (i.e. with AspNetCompatibilityRequirements set to allowed). Like many others, I got an error saying the Anonymous access is required because the mexHttpBinding requires it and the only way to get around it is to remove the mex endpoint from each service as described here:
WCF - Windows authentication - Security settings require Anonymous
I thought by removing mex endpoint I will no longer able to generate WSDL or add a reference to the service from Visual Studio but to my surprise everything still works. I quickly googled the "mex binding" but most web sites just say it's for "Metadata Exchange" without going into too much detail on what it actually does.
Can anyone tell me what's the side effect of removing the mex binding?
If your WCF service does not expose service metadata, you cannot add a service reference to it, neither from within Visual Studio (Add Service Reference), nor will another client be able to interrogate your service for its methods and the data it needs.
Removing Metadata Exchange (mex) basically renders the service "invisible", almost - a potential caller must find out some other way (e.g. by being supplied with a WSDL file, or by getting a class library assembly with a client he can use) about what the service can do, and how.
This might be okay for high risk environment, but most of the time, being able to interrogate the service and have it describe itself via metadata is something you want to have enabled. That's really one of the main advantages of a SOAP based service - by virtue of metadata, it can describe itself, its operations, all the data structures needed. That feature is used to make it really easy to call that service - you just point to the mex endpoint, and you can find out all you need to know about that service.
Without the metadata exchange, you won't be able to use svcutil.exe to automatically generate the proxy classes.
I have an ASP.NET MVC web app whose controllers use WCF to call into the domain model on a different server. The domain code needs to talk to a database and access to the database server isn't always possible from web servers (depends on the customer site) hence the use of WCF to get to a place where my code is allowed to connect to the database server.
This is configurable so if the controllers are able to access the database server directly then I use local instances of the domain objects rather than use WCF.
Lets say I have a page asking for person details like age, name etc. This is a complex type that is a parameter on my WCF operation like this :
[OperationContract]
string SayHello( Person oPerson);
When I generate the client code (eg; by adding a service reference in my client) I get a separate Person class that fulfills the wcf contract. The client, an MVC web app, can use this client Person class as the view model and all is well. I pass that straight into the WCF client methods and it all works brilliantly.
If my mvc client app is configured to NOT use WCF I have a problem. If I am calling my domain objects directly from the controller (assume I have a domain access factory/provider setup) then I need the original Person class and not the wcf generated Person class. This results in my problem which is that I will have to perform mapping from one object to another if I don't use WCF
The main problem with this is that there are many domain objects that will need to be mapped and errors may be introduced such as new properties forgotten about in future changes
I'm learning and experimenting with WCF and MVC can you help me know what my options are in this scenario? I'm sure there will be an easy way out of this given the extensibility of WCF and MVC
Thanks
It appears that you are not actually trying to use a service-oriented architecture. In this case, you can place the domain objects into a single assembly, and share it between the WCF service and the clients. When creating the clients, use "Add Service Reference", and on the "Advanced" tab, choose "Share Types". Either choose to share all types, or choose the list of assemblies whose types you want to share.
Sound service-oriented-architecture dictates that you use message based communication regardless of whether your service is on another machine, in another process, in another appdomain, or in your appdomain. You can use different endpoints with different bindings to take advantage of the speed of the link (http, tcp, named pipes) based on the location of your service, but the code using that service would remain the same.
This may not be the easiest or least time-consuming answer, but one thing you can do is avoid using the "add service reference" option, and then copy your contract interfaces to your MVC application and initiate the connection to WCF manually without automatically creating a service proxy. This will allow you to use one set of classes for your model objects and you can control explicitly when to use WCF or not.
There's a good series of webcasts on WCF by Michele Leroux Bustamante, and I think in episode 2, she explains how to do exactly this. Check it out here: http://www.dasblonde.net/WCFWebcastSeries.aspx
Hope this helps!
One sound option is that you always use WCF, even if client and server are in the same process, as Aviad points out.
Another option is to define the service contracts on interfaces, and to put these, together with the data contracts into an assembly that is shared between client and server. In the client, don't use svcutil or a service reference; instead, use ClientFactory<T>.
This way, your client code will use the same interfaces and classes as the server.
Using the BizTalk ESB Toolkit 2.0
We are working on a project where we need to call a proxy to a web service which is a DLL. We have no problems doing this via an orchestration since you can use a static port and configure it to use the SOAP adapter with the web service setting pointing at the assembly in the BizTalk Admin interface. In the itinerary though there doesn't seem to be an obvious way to do this since dynamic ports don't have the option to use the SOAP adapter.
There is a good reason why we want to do this, don't worry.
Following on from this, we implemented a custom adaptor provider but are having problems getting it to work.
We followed an (old) example shown here:
The custom adaptor provider inherits from BaseAdapterProvider and overrides the SetEndPoint(Dictionary, IBaseMessageContext) method.
The method extracts the assembly name, type name, and method name that are passed in via the resolver dictionary and then writes them to the pipeline context:
pipelineContext.Write("TypeName",
"http://schemas.microsoft.com/BizTalk/2003/soap-properties", typeName);
pipelineContext.Write("MethodName",
"http://schemas.microsoft.com/BizTalk/2003/soap-properties", action);
pipelineContext.Write("AssemblyName",
"http://schemas.microsoft.com/BizTalk/2003/soap-properties", assembly);
and sets the transport type to soap:
pipelineContext.Write("TransportType",
"http://schemas.microsoft.biztalk.practices.esb.com/itinerary", "SOAP");
In all other respects the adapter provider is nearly identical to the example shown in the link above, except for the obvious change from SMTP to SOAP.
The adapter provider assembly is signed, GACed, and added to the esb.config.
The adapter provider is called from an itinerary that only calls the service and then returns the response. We are testing the itinerary from the Itinerary Test Client that is shipped with the toolkit. Event logging within the custom adapter shows that the adapter code is being called. The problem is that the message is not being routed to the service proxy. The event viewer gives the following error:
The Messaging engine failed to process
a message submitted by adapter:SOAP
Source
URL:/ESB.ItineraryServices.Response/ProcessItinerary.asmx.
Details:The published message could
not be routed because no subscribers
were found. This error occurs if the
subscribing orchestration or send port
has not been enlisted, or if some of
the message properties necessary for
subscription evaluation have not been
promoted. Please use the Biztalk
Administration console to troubleshoot
this failure.
Investigating the suspended service instamces in Group Overview shows two things:
The values for assembly name, type name, and method name are being set correctly.
The message body is missing.
We have tried configuring the send and receive pipelines on the send port to be both XMLTransmit/XMLReceive and ItinerarySendPassthrough/PassthroughReceive and it makes no difference.
Is there something obvious we might have missed? Do you have to explicitly pass the message body through? If so how?
EDIT:
Following a request from the BizTalk ESB Toolkit forum I am posting screen shots of the itinerary, context and send port filters.
Itinerary,
Context,
Port filters.
Many thanks, Nigel.
first of all I'll say you are trying to over engineer the solution. Adapter development is not trivial and there are various things you need to take in to consideration. Developing and Deploying adapters are categorized as platform changes, which effects your whole environment, so if you are not familiar then your shouldn't do it. I would recommend you taking some other route. At this point I personally don't have enough insight into ESB internals, so won't be able to comment on it. At worst case you may be better off using the .NET proxy dll directly inside your orchestration (expression or message shape) rather than building an adapter. Even though its not recommended approach, still I feel its better than custom adapter approach.
Semantically, I don't see why a solution that involves a WCF-BasicHtpp adapter would not work in your scenario. In any case, I would definitely try to see what happens with a WCF-BasicHttp adapter, and once I got a working solution, I would switch to a custom SOAP adapter if that is really necessary.
Currently, your solution is weird - in the sense that you have an On-Ramp directly connected to an Off-Ramp. I've never seen that in any of my itineraries. You might need to create an intermediate messaging or orchestration Itinerary service in betweeen.
Otherwise, the message effectively gets published to the message box and obviously there is no subscribers for it, hence the error you encounter.