Sample Activity – Call BizTalk Rules

I have been looking at scenarios involving Workflow and BizTalk and figured a good place to start was with Rules integration. If you have rules already defined in the BizTalk BRE, then you should be able to take advantage of them from a Workflow instead of trying to translate all of those rules into the WF rules engine.
The BRE activity allows you to reuse your investment in the BizTalk BRE be configuring and executing policies from your workflow. It contains a custom activity designer that queries information about the policy/facts and builds a dynamic set of properties so that you can configure the facts right on the activity and use databinding.
This is definitely a sample but works with my simple tests. I have not added support for data connection or data row/table facts, but it should be easy enough for someone to add those into the designer.
Hopefully this will be useful for some of you. Any feedback is welcome.
Grab the code here.

HIS 2006 and BizTalk 2006 HOST Adapters EVAL!

Alrighty then….. go get em!

Andrew McLaren from our team in Sydney just highlighted to me that you can now go and download the eval version’s of:

 

Microsoft Host Integration Server 2006 Evaluation Edition (120-day)

http://www.microsoft.com/downloads/details.aspx?FamilyId=E4A40127-D73C-4D41-B8B4-FBBE68EEC47E&displaylang=en

 

Microsoft BizTalk Host Adapters for Host Systems (requires BizTalk Server 2006)

http://www.microsoft.com/downloads/details.aspx?FamilyId=C0D4B943-1786-4B74-A9A4-FDAA582F5FA2&displaylang=en

Awesome! Now I need to just go and fire up my AS400 in the garage to test this..… ( I’m just kidding ;-)) Enjoy and let me know your feedback!

Getting at BizTalk ACKS and NACKS

As you may have experienced usually from a Send Port within an Orchestration,
the Orchestrations says “Yep all sent” (via the message box to the subscribed Send
Port……..

….then the unspeakable happens…..the Send Port Fails! but the Orchestration has
long gone and said all is good.

By setting the Notification Property to Transmitted to
the Send Port within the Orchestration, causes the Orchestration to wait till a Success
or Failure has come back from the Send Port.

To view the Acks or NACKS (for e.g. you may ask – how many times
does this fail??)

Simply add a Filter property to a Send Port of BTS.AckType=NACK or ACK

You’re done – you can now see an internal message within BizTalk

Interface Directly with BizTalk Messaging Engine

I came across a great simple sample of how to do this and thought I show how easy
it is to do this.

A whole bunch of BizTalk Samples from the Developer Team is here:
BizTalk Samples

One of the samples on the page is the ConsoleAdapter – very simple, non Adapter framework
receive adapter. This is an isolated adapter.

Here’s the crux of the sample – In particular look at the ProcessMessage function.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.BizTalk.Interop;
using Microsoft.BizTalk.Messaging.Interop;
using Microsoft.BizTalk.TransportProxy.Interop;
using Microsoft.BizTalk.Adapter.Framework;
using System.Globalization;
using System.Resources;
using Microsoft.BizTalk.Message.Interop;
using System.IO;

namespace Microsoft.Samples.BizTalk.Adapters.ConsoleAdapterLibrary
{
public class ConsoleAdapter : IBTTransport, IBTTransportConfig, IBTBatchCallBack
{
~ConsoleAdapter()
{
// Class destructor called by default right before ConsoleAdapter class is being
// destroyed. This method makes required call to TermiateIsolatedReceiver to

// match previous calls to RegisterIsolatedReceiver in the Register method.
_tp.TerminateIsolatedReceiver();
}

static ConsoleAdapter()
{
// Default class constructor called by default as ConsoleAdapter class is being
// instantiated. This method accepts a string as input from the command line and

// calls the SendMesage helper method to submit it to BizTalk Server.
// Multiple messages can be submitted by entering numerous strings and hitting <ENTER>.
// To end the progam hit <CTRL-C> and it will exit.
Console.WriteLine(“Type in message text and hit <ENTER> for each BizTalk Server
message. Hit <CTRL-C> to exit.”);
string data = Console.ReadLine();

do
{
// Submit the msssage to BizTalk Server
SendMessage(data);
data = “”
data = Console.ReadLine();
}
while(true);
}
static void SendMessage(string data)
{
// Helper method called by the default class constructor immediately following the
// ConsoleAdapter class being instantiated. This method accepts a string as input.
// That string is used as part (the body) of the message which is submitted in a

// (single) message batch to the BizTalk Server Messaging Engine. This method is
// called once for each message to be submitted.

// If the adapter instance is registered with BizTalk then proceed.
Otherwise this

// is the first message being submitted so register the adapter instance as an

// isolated recevier with BizTalk Server.
if (!Registered)
Register();

// Create a message part containing the string and adds it to
the message
IBaseMessagePart part = _fact.CreateMessagePart();
IBaseMessage msg = _fact.CreateMessage();
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
sw.Write(data);
sw.Flush();
ms.Seek(0, SeekOrigin.Begin);
part.Data = ms;
msg.AddPart(MESSAGE_BODY, part, true);

// Create a new context for a message.
SystemMessageContext context = new SystemMessageContext(msg.Context);

// _url is consoleadaptertestharness.exe
context.InboundTransportLocation = _url;
context.InboundTransportType = “Console”

// Obtain a batch from the Messaging Engine proxy and submit
the message via the batch.
IBTTransportBatch batch = _tp.GetBatch(_cb, _cb);
batch.SubmitMessage(msg);
batch.Done(null);

}
void ProcessMessage(Stream s)
{
//This gets us the interface to the Messaging Engine
IBTTransportProxy tp = GetProxy();
//get the message factory

IBaseMessageFactory msgfact;
msgfact = tp.GetMessageFactory();
IBaseMessage msg;
//create the message object
msg = msgfact.CreateMessage();
IBaseMessagePart part;
//create the part – in this case

//the only part
part = msgfact.CreateMessagePart();
//give the part the stream
part.Data = s;
//add the part
msg.AddPart(“body”, part, true);
IBTTransportBatch batch;
//get the bacth – the object
//used to send messages
batch = tp.GetBatch(this, null);
//submit the message – in this case
//this is a one-way MEP
batch.SubmitMessage(msg);
//tell the batch we’re done
batch.Done(null);

}
IBTTransportProxy GetProxy()
{
// Helper function to return a pointer to the proxy.
return _tp;
}
static void Register()
{
// Get the transport proxy and use it to register the adapter and it’s receive location

// with BizTalk Server.
_tp = new BTTransportProxy() as IBTTransportProxy;
_tp.RegisterIsolatedReceiver(_url, _instance);
_fact = _tp.GetMessageFactory();
Registered = true;

}
private static CB _cb = new CB();
private static string MESSAGE_BODY = “body”
//Need to have a receive location by this same name “ConsoleAdapterTestHarness.exe”
static string _url = “ConsoleAdapterTestHarness.exe”//System.Diagnostics.Process.GetCurrentProcess().ProcessName;
static IBaseMessageFactory _fact = null;
static ConsoleAdapter _instance = new ConsoleAdapter();
static IBTTransportProxy _tp = null;
static bool Registered = false;
public Guid ClassID { get { return new Guid(“{82A2D6BC-F1CA-4ad5-80AA-ED7B7A52B493}”);
} }
public string Description { get { return “Description” } }
public string Name { get { return “Console Adapter” } }
public string TransportType { get { return “Console” } }
public string Version { get { return “1.0.0.0” } }

void IBTTransportConfig.AddReceiveEndpoint(string url, Microsoft.BizTalk.Component.Interop.IPropertyBag
adapterConfig, Microsoft.BizTalk.Component.Interop.IPropertyBag bizTalkConfig)
{

}

void IBTTransportConfig.RemoveReceiveEndpoint(string url)
{

}

void IBTTransportConfig.UpdateEndpointConfig(string url, Microsoft.BizTalk.Component.Interop.IPropertyBag
adapterConfig, Microsoft.BizTalk.Component.Interop.IPropertyBag bizTalkConfig)
{

}
public void BatchComplete(int status, short opCount, BTBatchOperationStatus[] operationStatus,
object callbackCookie)
{

}
}
public class CB : IBTBatchCallBack
{
#region IBTBatchCallBack Members

public void BatchComplete(int status, short opCount, BTBatchOperationStatus[]
operationStatus, object callbackCookie)
{

}

#endregion
}
public class ConsoleAdapterConfig : IAdapterConfig
{
#region IAdapterConfig Members

public string GetConfigSchema(Microsoft.BizTalk.Adapter.Framework.ConfigType
configType)
{
switch (configType)
{
case ConfigType.ReceiveHandler:
return GetResource(“ReceiveHandler”);

case ConfigType.ReceiveLocation:
return GetResource(“ReceiveLocation”);

default:
return null;
}
}
string GetResource(string name)
{
ResourceManager rm = ConsoleAdapterLibrary.ConsoleAdapterRes.ResourceManager;
return rm.GetString(name);

}
public Microsoft.BizTalk.Adapter.Framework.Result GetSchema(string uri, string namespaceName,
out string fileLocation)
{
// TODO: Add RemotingAdapterConfig.GetSchema implementation
fileLocation = String.Empty;
return Result.Continue;
}

#endregion
}

}

BizTalk 2006 – purging the tracking database fast!

Something to share with you – ever wanted to clear out the tracking database? two
ways to do this:

1. considerate way – only purges completed items
MSDN
BTS06 Proper Purge

2. inconsiderate way – FAST! purges ALL data in the DTA.
Stored Proc – dtasp_CleanHMData (useful in test environments etc)
This will truncate the tables within the DTA DB – just like new!

Cheers,

Mick.

HIPAA Accelerator in a Clearing House situation

The question that I have raised a few times in my own head is how can you use the HIPAA accelerator in a clearing house enviornment. My definition of a clearing house is a company that represent different companies, so essentially the sender id that you define in the send handler is not always the same.

There is currently no way to create multiple send handlers, so Microsoft has created a pipeline component that you specify the sending ids that will reset it to. Because most clients need an acknowledment, I would always recommend using the adapter and not the pipeline componet as I documented here.

So my suggestion is as follows for inbound transactions:

  1. Create a recieve port called DMZ (port where clients are going to be able to drop their files off) and in there create seperate recieve locations for each of the clients inbound folders and use the passthru pipeline.
  2. Create a send port using the passthru pipeline filtering on the RecievePortName==”DMZ” and have the location defined as the %documentshome%\PickupEDI (remember you actually have to put the full path in the send port).
  3. Then you have recieve locations using the HIPAA_EDI adapter for each of the partners.

So my concurrent suggestion is as follows for outbound transactions:

  1. Using logic derived from thisentry, create seperate send ports using the HIPAA_EDI adapter and point the folder location to a staging area.
  2. Obtain the pipeline fix from Microsoft Support and create seperate pipelines for each of the partners that you represent.
  3. Create a seperate receve location that picks up the file using the passthru pipeline picking up the file that was created in step 1.
  4. Create a seperate send port that filters off the recieve location defined in step 3 and use the newly created pipeline that will replace the sending parties information that is defined in the send handler to the correct sending ids.

Wikipedia article on Rete

While I’m on the subject of rules engines (which seem to be my main blogging topic currently), I should report that during the last two or three weeks, I took the plunge and expanded (rather a lot) the Wikipedia article of the Rete algorithm.   See http://en.wikipedia.org/wiki/Rete_algorithm.     Originally, I used the text of an explanation I wrote a year or so ago.   I got some kickback on that, with claims of inaccuracy and other claims that the text was too convoluted (what, me write convoluted content – impossible!).   The original text wasn’t inaccurate, but it was less comprehensive than it should have been, and lacking clarity in places.  I spent some time last week extensively re-writing and expanding it, and have published the new version.    I’m not sure it’s any easier to read, but it is more complete.  Rete is a specialist subject, but if you are interested in how rules engines like MS BRE work internally, and specifically how they approach the problem of doing efficient combinatorial pattern-based matching of facts to rule conditions, then take a look.   I’ve added in links to other Wikipedia articles, and I plan at some point to add a few more diagrams.   Being Wikipedia, of course, anyone is free to alter, extend, re-write or even delete the content, so if you’re also a Rete-head, please feel free.


Previously posted at http://blog.solidsoft.com/blogs/charles_young_mvp_biztalk/default.aspx

BizTalk 2006: Cool content…

So, there I am, sitting next to my boss, Andy, at work.  He's just downloaded the electronic version of a BizTalk book he's bought.   It's called "Pro BizTalk 2006" from Apress, and its written by George Dunphy and Ahmed Metwally.   Andy draws my attention to the chapter on the Microsoft Rules Engine.   I've got an interest in this piece of kit, so I start flicking through the pages to see what the chapter is like.   Not too bad at all.  Oh look, they've even got a section starting on page 290 that discusses how to use XPaths effectively to handle XML facts.   Good stuff.   I've blogged on this once or twice myself, and I've had to explain the issues so many times to others.   It's a good, clear explanation.   The kind of thing I might have written myself and…oh, it really is very much the kind of thing I might have written myself.   I recognise the phrases, the terminology, the sentence structure.   Why, goodness me.  I did write it!    I even remember where I wrote it.   It's in a reply to a post on the MSN BizTalk group from way back.   I type half a sentence straight into Google.   Yes, there it is.  http://www.msnusers.com/biztalkserverstuff/general.msnw?action=get_message&mview=1&ID_Message=2064.   I knew I'd written it.    I do a detailed comparison.   Not quite the same.   The content has been re-worked, tidied up, etc.   But yes, its definitly a version of what I wrote.

Hey guys, I'm flattered.   Glad I could help you out.   Like it says on the cover,  "The Expert's (sic) Voice".   Incidently, I had a quick look through the book, and the other content looks almost as good as pages 290-291 [;)]

PS.  I'm not offended – just amused.   In any case, I had quick look at the T&Cs on MSN, and discovered that the authors are entirely in their rights to use the material in this way.

Previously posted at http://blog.solidsoft.com/blogs/charles_young_mvp_biztalk/default.aspx

Registry Access Permission

If you are getting an error logging to the EventLog, make sure you have the following registry setting:



  1. Navigate to \\MyComputer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\

  2. Right Click on EventLog and click permissions.

  3. Add the service account (application pool ID or BizTalk host instance service account) to the list of users and give it a special permissions of (Query Value, Set Value, Create Subkey, Enumerate Subkeys, Notify, Read Control).