BizTalk– Extracting xs:Base64Binary

Hi,

Sometimes you will need to extract binary data from an XML file. It may be in a form of a string or Base64Binary, either way, you can extract it by using a helper class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.XLANGs.BaseTypes;
using System.IO;


namespace Romiko.Common.Helpers
{
    [Serializable]
    public  class CustomStreamFactory : IStreamFactory
    {

        byte[] _data;

        public CustomStreamFactory(byte[] b)
        {
            _data = b;
        }

        public Stream CreateStream()
        {
            return new MemoryStream(_data);
        }

    }
}

 

Then all we need is to create a helper method:

using System;
using Microsoft.XLANGs.BaseTypes;

namespace Romiko.Common.Helpers
{
    [Serializable]
    public  static class Utilities
    {

        public static void GetBinary(XLANGMessage message, string base64data)
        {
            byte[] b = System.Convert.FromBase64String(base64data);
            message[0].LoadFrom(new CustomStreamFactory(b));

        }

        public static void GetBinary(XLANGMessage message, byte[] base64data)
        {
            message[0].LoadFrom(new CustomStreamFactory(base64data));

        }
    }
}

 

I created two overloads here, in case you have it in a byte array in XML or as a string.

In an orchestration you can then create a new message in a message construct like so:

image

System.Diagnostics.Trace.WriteLine(">>> PersistCompletedApplication.odx - Sending Pdf");

GeneratedPdf = new System.Xml.XmlDocument();

//Helper to Extract Binary data into a new binary message.
Romiko.Common.Helpers.Utilities.GetBinary(GeneratedPdf, MyXmlDocument.GeneratedPdf);
GeneratedPdf(FILE.ReceivedFileName) = nFileName + ".pdf";

MyXmlDocument.GeneratedPdf is a distinguished field here, so it is easier to pass the data over, not the most memory efficient, but in my case the documents (PDF) are tiny, so no need to over engineer the solution.

Thanks to Richard Seroter’s tips Smile

Cheers

BizTalk Mapper–Inline XSLT Templates–Tracking Profile Editor Limits

Hi Guys,

I hit a limit with the Tracking Profile Editor where I needed to tracking aggregate results from repeating fields in the incoming message within an orchestration. So I decided to try edit the .btt file directly and see if I can fool the BTTDeploy command. However it did not work, it detected my XPath was too fancy and rejected it. Since you can edit .btt files and get away with some minor fancy xpathing.

So the solution was to create an intermediate message to serve as the profiling message source. Hence an orchestration that has an additional construct shape that BAM profiling can consume.

As usual, the BizTalk mapper makes a mess of things when you want to loop through records and frankly I was not in the mood to use the Table Extractor/Looping “functoid” for simple sums. So Inline XSLT here we come.

In fact 90% of my time I will opt for xslt than the biztalk mapper, purely due to the mapper is reserved for very simple mappings. XSLT’s are by far easier to read than the BizTalk Mapper when it comes to complex conditions.

So, below is a message constructed that BAM TPE can consume easily without hacking the .btt file.

image

It is a bit odd to create a message that does nothing in the orchestration at first look, but it serves as an invaluable source of information for BAM profiling.

I opted for a BizTalk Map to create the BAM message, to keep maintenance of schema’s visible and no dirty XmlDocument.Load statements in the orchestration Smile Yes you know who you are!

Here is the sample MAP that takes input message and creates a BAM message for TPE to consume:

image

The Scripting Functoids will then have the following for calculating Annual Sums.

Notice that Param1 is the Input element relative to the Script Functoid, this is usefull, so I can grab a subset of the xml data to pass into the scripting functoid, in this case Benefits.

<xsl:template name="AnnualTotalPremium">
<xsl:param name="param1" />
    <xsl:variable name="Premium" select="sum(//*[local-name()='Premium' and namespace-uri()='urn:Romiko.Submission']) * 12" />
 <xsl:element name="AnnualTotalPremium" >
          <xsl:value-of select="$Premium"/>
 </xsl:element>
  </xsl:template>

Below is a more interesting one that takes record counts as a second parameter for average benefits per policy premium.

<xsl:template name="AveragePolicyAnnualPremium">
<xsl:param name="param1" />
<xsl:param name="param2" />
    <xsl:variable name="Premium" select="(sum(//*[local-name()='Premium' and namespace-uri()='urn:Romiko.Submission']) * 12) div $param2 " />
 <xsl:element name="AveragePolicyAnnualPremium" >
          <xsl:value-of select="$Premium"/>
 </xsl:element>
  </xsl:template>

So, I hope this inspires anyone needed to collect data for BAM that is a bit too more for TPE to handle and you do not want to implement custom BAM Interceptors.

BizTalk–WCF Oracle Composite Transactions and a small think on ESB’s

When using the BizTalk Adapter Pack 2.0/WCF LOB on BizTalk 2009.

Remember with Oracle WCF Adapter to install these before the oracle client :

WCF LOB SDK SP2
BizTalk Adapter Pack 2.0

When configuring the operations in the WCF adapter ensure you fully qualify the operation name that matches the logical orchestration port in the WCF ADAPTER Bindings.

If it does not have this, then you will get errors where an InvalidOperationException will occur.

<Operation Name=”LogicalPortOperationName” Action=”http://Microsoft.LobServices.OracleDB/2007/03/CompositeOperation” />

image

clip_image002[7]

You can read more here.

http://msdn.microsoft.com/en-us/library/dd788415(v=bts.10).aspx

Since we use ambient Transactions and Nested transaction for the batch, also ensure the Oracle Microsoft Transaction Services is installed. I use the 64 bit version which runs fine with Biztalk in 32 bit mode. However I have BOTH oracle 32bit and 64 bit client (Oracle Dara Access Components 11.2.0.7.20 or higher, since the 32 bit is needed for Developer Design time work with the ConsumeAdapterService Wizards on the developer box. Use different install paths for 32 bit and 64 bit as well.

HINT: Generate all insert, update, select, delete operations in one go on the ConsumeAdapterService wizard, then you never have namespace clashes if you need the operations later!

Another point is to Update the machine.config if you use a later version of the oracle client on the Development box, else the LOB wizard will not work.

 <!-- Add in Machine.Config -->
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89b483f429c47342" culture="neutral" />
<bindingRedirect oldVersion="2.111.7.0" newVersion="2.112.1.2"/>
</dependentAssembly></assemblyBinding>

Here is some notes on it:

1. Ensure you have the Adapters downloaded. clip_image002

2. Install WCF LOB Adapter SDK SP2 x64.

Ensure you include the TOOLS on the development server.

clip_image004

If you do not install the tool, then Visual Studio dev environment will not have the consume adapter feature!

clip_image006

3. Install BizTalk adapter Pack 2.0 for 2009, both for x86 and x64. Get from MSDN Subscription

clip_image008.

Oracle Client Install

4. Install Oracle Data Access Components (ODAC) 11.1.0.7.20 bundled with Oracle Instant Client making sure no other client versions are present before installation. 32 First and then 64 Bit. 

clip_image012

clip_image014

5. Use the follow name for BASE: Oracle and software location fro 64 bit is \11, 32 bit is 11-32

clip_image016

clip_image018

6.

clip_image020

clip_image022

clip_image024

clip_image026

clip_image028

Keep the above install path as short as possible

7. The Visual Studio system used an older version of oracle at DESIGN TIME on a dev box, the following int he machine config will fix this error:

clip_image030

Fix:

Add to Machine.config in C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG

<!– Add in Machine.Config –>

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

<dependentAssembly>

<assemblyIdentity name="Oracle.DataAccess" publicKeyToken="89b483f429c47342" culture="neutral" />

<bindingRedirect oldVersion="2.111.7.0" newVersion="2.112.1.2"/>

</dependentAssembly>

</assemblyBinding>

8. Install the Transaction Oracle Service for Microsoft Transaction Services Support 64 bitclip_image032

Ensure you choose the correct Software location corresponding to the 64 bit folders. 64 bit is d:\Oracle\11

clip_image034

clip_image038

9. Restart the Machine.

Microsoft ESB Toolkit for BizTalk

I am in disagreement with how Microsoft has bundled and named this toolkit. For one BizTalk is not an ESB it is a message broker. So the toolkit should be renamed. An ESB is something that is 100% distributed with no centralised publisher. An ESB is similar to a PCI Bus, Ethernet or CPU Microprocessor Bus Architecture, where all endpoints participate. If you wanted a pure ESB with BizTalk then all endpoints would be BizTalk, which would never be feasible from a financial perspective. A good example of an ESB would be NServiceBus (http://nservicebus.net/).

I love working with BizTalk, but it should never be abused or sold as an ESB. Perhaps a blog about this in depth at some point when I get a chance will be nice.

It is very dangerous selling BizTalk as an ESB to clients, you putting them down a path that is not going to look pretty in 5 years time. .Net to .Net communication does not need a BizTalk Broker in-between it. BizTalk is ideal for integration services and that’s it.

BizTalk can act as a Integration layer as ONE OF the endpoints in an ESB. If Ethernet or PCI was used a central server to publish/subscribe messages, I can tell you that it would not be a very scalable and reliable system.

It is not only BizTalk that is a culprit for misunderstanding ESB’s all major vendors are in the same boat trying to sell ESB servers like IBM Websphere and Oracle SOA. And I can understand why, centralised = licensing made easy.

Remember a true ESB cannot be touched and pointed at, it is a DISTRIBUTED ARCHITECTURE with each endpoint managing it’s own persistence, any endpoint  can just go down when it wants and be turned on when it wants to.

Follow

Get every new post delivered to your Inbox.

Join 131 other followers