官术网_书友最值得收藏!

Consuming WCF services without orchestration

There are plenty of scenarios where orchestration is an unnecessary addition to service bus processing. Recall that an orchestration's prime benefit is the injection of a stateful, sequential series of steps to message processing. If the "processing" of a message can consist solely of the core BizTalk messaging components (receive ports, send ports, pipelines, maps, and subscriptions), then a messaging-only solution is the way to go. A general rule among BizTalk architects is that you avoid orchestration and concentrate on pure messaging when at all possible. This isn't because orchestration is intrinsically bad but rather because many situations actually don't require the overhead and complexity of a workflow.

That said, how nicely does the BizTalk bus play with WCF services when no orchestration is involved? Quite well, thank you. Let's look at how we may route inbound data to a WCF subscriber using only the message bus.

In our new scenario, we have a target service in our enterprise resource planning (ERP) system that accepts new order notices and uses WCF's WsHttpBinding. We'd like to call this service whenever a new product order enters the MessageBox. This subscriber does not need any direct knowledge of the upstream publisher or how the message arrived to the bus.

  1. We start this example by referencing the target service from within Visual Studio. This is done by once again right-clicking the BizTalk project and choosing Add and then Add Generated Items.
  2. The Consume WCF Service is selected, and when the BizTalk WCF Service Consuming wizard launches, the Metadata Exchange Endpoint is picked as the source of the service metadata.
  3. Now we plug in the valid HTTP endpoint URI of our WCF service:

When the wizard completes, we have a set of metadata files (schemas, bindings, and orchestrations) that help describe the service and how to consume it. This example doesn't use orchestration, but we do still require one hand-built BizTalk artifact—a map. The WCF service expects the order data to be in a particular format, so we should design a map that gets applied by the outbound send port. The BizTalk map takes the repeating set of order items and puts them into their appropriate fields in the target schema.

Now we build and deploy our updated project. Once that deployment has succeeded, we import the binding generated by the BizTalk WCF Service Consuming wizard. For this scenario:

  1. Let's import the custom binding (OrderService_Custom.BindingInfo.xml) so that we can see the different properties this adapter exposes.
  2. A send port is created for the WCF-Custom adapter, but note that the binding specified by the adapter matches that of our service endpoint, wsHttpBinding.

On the General tab of the adapter configuration, observe that there is a section called SOAP action header. This contains the SOAP action that will be attached to the outbound messages for this send port.

The BtsActionMapping wrapper in this textbox is used to support multiple SOAPAction values. However, this also means that something needs to set the BTS.Operation value, which the WCF adapter uses to choose the appropriate SOAP action from this collection. Typically, this is set by the orchestration's logical send port operation name, but in the absence of an orchestration, we would have to set the BTS.Operation value in a custom pipeline component. Before throwing up your hands and swearing loudly at this unnecessary complexity, breathe deeply and relax. Luckily, this textbox also supports an alternate format that is more supportive of simple content-based routing scenarios. A single SOAP action URI in this textbox is used when you want to apply the same SOAPAction header to all messages transmitted by the send port. For our scenario, let's switch this to the single SOAPAction header that corresponds to our target service operation.

Next, we must apply our XSLT map to this send port. The map is a required component because our service is expecting a very specific data format that does not match the original structure of the data.

Our final step is to introduce a valid subscription for this send port. Without one, this port will never receive any messages published to the bus. Because we'd like to pull every order from the MessageBox, our subscription should be type-based, not context-based. A context-based subscription would say that we are subscribing to properties of the message (for example, which port it arrived at) instead of anything relating to the message itself. We want to subscribe to all messages of a particular type. The subscription applied can be seen in the following screenshot:

Now, technically we are finished. If we send a message into BizTalk, it should route to a listening send port and produce the expected tracing statements. However, see the following Pitfall to resolve an error with our current configuration.

Note

Pitfall

The solution, as it stands now, will raise an exception. Why? The WCF service that BizTalk calls does not return a response message. However, the auto-generated BizTalk binding file was for a two-way send port. So, when the WCF service is called, the request is successful but we end up with a subscription not found exception on the (empty) response message. We can fix this by creating a new one-way send port with configuration settings (adapter type, URI, binding, SOAPAction, and subscription) identical to those of the auto-generated port.

主站蜘蛛池模板: 吉隆县| 盐边县| 新泰市| 宝山区| 永德县| 当雄县| 龙井市| 嘉兴市| 温宿县| 五家渠市| 安阳县| 昌黎县| 合江县| 涞水县| 伊川县| 房产| 胶州市| 华坪县| 西乡县| 金坛市| 株洲市| 交城县| 荣成市| 汉寿县| 镇赉县| 杭锦后旗| 丰城市| 长宁县| 平利县| 襄垣县| 柳河县| 信阳市| 固镇县| 敦化市| 广西| 简阳市| 宝清县| 额尔古纳市| 武夷山市| 公安县| 寿宁县|