Azure BizTalk Rules Alternatives

 

All Preview API Apps including BizTalk Rules V1 API App was deprecated from Azure since Jan 18th, 2017. The migration path is to redeploy the V1 API App as App Service but this is not possible for built in BizTalk Rues API App.

Here are few alternatives of BizTalk Rules V1 API App:

Option 1: On-Premises BizTalk Rules Engine

we can use BizTalk BRE to define Rules in Rules Editor, deploy them on a BizTalk Server installation and write a Web API App to execute the policy through code, and we access the Web API App from Azure through a Hybrid Connection. The Logic Apps does not support Hybrid Connections yet, therefore we have to create a Relay Web App in Azure which take HTTP requests from the Logic App and pass it on to On-premises Rules Web API App.

 

Logic App –> App Service | Azure Hosted Relay Web API [Relay request and Cache Rules Result] –> Hybrid Connection –> On-Premises Web API –> BizTalk BRE Call

 

With this approach, we have access to full capabilities of BizTalk Rules Engine to create and execute complex Rules, and store and retrieve facts from on-premises SQL Server database. However, we need to have a BizTalk 2010+ installation on any on-premises server or on an Azure VM.

 

Option 2: CodeEffects Rules Engine

CodeEffects Rules Engine provide a web based Rules editing and testing platform, and we can choose this option if we don’t have a BizTalk Server installation, yet we want a UI based Rule editor and complex rules processing.

Logic App –> App Service | Azure Hosted Relay Web API [Relay request and Cache Rules Result] –> Hybrid Connection –> Code Effects Rule Engine

Option 3: Azure Functions as Rules Engine

 

Azure Functions is a solution for easily running small pieces of code in the cloud. The Code can be edited and deployed within Azure Portal. The idea is to use Azure Functions to defined and execute the Rules Logic and the Functions are invoked over an HTTP call from Logic Apps or Web Apps.

 

Logic App | Web App –> HTTP call to Azure Function –> Azure Function implementation

 

Option/Feature

Rules Authoring

Rules Complexity

Dependency

1: BizTalk Rules Engine

UI

Complex

BizTalk installation

2: CodeEffects

UI

Complex

CodeEffects Rules License/Free version

3: Azure Functions

Code

Custom Code

No

Posted in Azure, BizTalk, C#. Tags: . Leave a Comment »

Secure Azure Service Bus Relays with SAS Token

This article explains how to secure Service Bus Relays using Shared Access Signature (SAS) to prevent unauthorized/Anonymous access.

Shared Access Signature

Shared Access Signatures are based on SHA-256 secure hashes or URIs. In Azure all Service Bus services provide this authentication mechanism to control access to the resource that may be a service bus relay, a service bus messaging queue or a topic. The SAS is composed of two components:

1. A Shared Access Policy.

2. A Shared Access Signature which is also called a token.

To secure and access a Service Bus Relay endpoint first we need to create a Service Bus Relay Namespace in the Azure portal. After the namespace has been created, create a new policy under Service Bus Relay namespace. We created a new Service Bus Namespace and a new policy as RelayPolicy as shown in the picture below.

clip_image002

Note: we will use Policy name and the Primary key to generate a SAS token or Shared Access Signature in the console application which we are going to create shortly.

Create a console application in C# to generate SAS token

Now we will create a C# script to generate a SAS token.

Create a console application in Visual Studio and name it whatever you like.

Replace the code in the Program.cs class with the following code. Note that the Primary Key and the Policy name may vary and you need to put your own Policy name and Primary Key here.

static void Main(string[] args)

{

var strAuthorizaitionHeader = GenerateToken(“https:// Dev-Relays.servicebus.windows.net/”,

“RelayPolicy”, “*********************=”);

}

public static string GenerateToken(string resourceUri, string sasKeyName, string sasKey)

{

//set the token lifespan

TimeSpan sinceEpoch = DateTime.UtcNow – new DateTime(1970, 1, 1);

var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 3600); //1hour

string stringToSign = HttpUtility.UrlEncode(resourceUri) + “\n” + expiry;

HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(sasKey));

var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

//format the sas token

var sasToken = String.Format(CultureInfo.InvariantCulture, “SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}”,

HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, sasKeyName);

return sasToken;

}

 

We will use this token in the logic app to send HTTP request to the Relay Service endpoint.

Now Open the logic app and go to the HTTP Post action and paste the SAS token string as value for Authorization HTTP header

clip_image004

Configurations for BasicHttp Relay transport properties

In Biztalk BasicHttp Relay set the transport properties as following.

1. Set the Security mode to Transport.

2. Set Relay Client Authentication Type as Relay Access Token.

The following picture shows the configurations settings of BasicHttp Relay transport properties

clip_image006

 

 

Could not load file or assembly ‘Microsoft.BizTalk.Interop.SSOClient, Version=7.0.2300.0

SSO Error

Unexpected exception occurred while configuring [BizTalk EDI/AS2 Runtime].

——————————
ADDITIONAL INFORMATION:

Could not load file or assembly ‘Microsoft.BizTalk.Interop.SSOClient, Version=7.0.2300.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ or one of its dependencies. The system cannot find the file specified. (EDIAS2Config)

FIX

Install SSOClient from [BizTalkServer2013 installation media]\BT Server\Platform\SSO\Client

Posted in BizTalk. Tags: . 1 Comment »

BizTalk EDI: Creating batching configuration in code

For outbound EDI batching, we have to create Batch Configuration in Party Configuration and set Filter Criteria about what messages should constitute one batch. But what if Filter Criteria is dynamic or we have too many batches to configure

here is code snippet to create batch configuration through API

 var builder = new SqlConnectionStringBuilder("DATA SOURCE="BTSSQLServer;Initial Catalog=BizTalkMgmtDb;
Integrated Security=SSPI;");
            using (var tmpCtx = TpmContext.Create(builder))
            {
                var agreement = (from p in tmpCtx.Agreements where p.Name == AgreementName select p).FirstOrDefault();
                if (agreement == null)//create agreement if does not exist.
                {
                    string Sender = ConfigurationManager.AppSettings["Sender"] ?? "SenderPartyName";
                    string Receiver = ConfigurationManager.AppSettings["Receiver"] ?? "ReceiverPartyName";
                    var OneWayAgreement = agreement.GetOnewayAgreement(Sender, Receiver); 
                    var firstBatch = OneWayAgreement.GetBatches()[0]; // first batch config is used as template
                    var newBatch = OneWayAgreement.CreateBatch(BatchName);
                    FilterPredicate predicate = firstBatch.GetFilterPredicate();
                    predicate.Groups[0].Statements[0].Value = "FilterRHS";
                    newBatch.SetFilterPredicate(predicate);
                    newBatch.SetReleaseCriteria(firstBatch.GetReleaseCriteria());
                    tmpCtx.AddToBatchDescriptions(newBatch);
                    tmpCtx.SaveChanges();
// this SQL insert is required to Activate the batch config
                    using (var cmd = new SqlCommand(@" INSERT INTO [dbo].[PAM_Control]
                                                                       ([EdiMessageType]
                                                                       ,[ActionType]
                                                                       ,[ActionDateTime]
                                                                       ,[UsedOnce]
                                                                       ,[BatchId]
                                                                       ,[BatchName]
                                                                       ,[SenderPartyName], ReceiverPartyName, AgreementName)
                                                                    SELECT 0 as EDIMessageType
                                                                  ,'EdiBatchActivate' as 'ActionType'
                                                                  ,GetDate() as 'ActionDateTime'
                                                                  ,0 as 'UsedOnce' 
                                                                  ," + newBatch.Id + @" as [BatchId]
                                                                  ,'" + BatchName + @"' as [BatchName], '"+ Sender +@"', '"+
 Receiver +@"', '" + AgreementName + "'", new SqlConnection(builder.ConnectionString)))
                    {
                        cmd.ExecuteNonQuery();
                    }
                }
                tmpCtx.Dispose();
Posted in BizTalk, C#. Tags: , . Leave a Comment »

BizTalk EDI: AK2 missing from 997 ACK

 

We can correlate a 997 with corresponding EDI request message by looking at AK2 segment (AK2:02 = ST02 in request), but by default BizTalk generates AK2 only for failed transactions, thus makes it difficult to correlate 997 with corresponding request in Async setup. To bring AK2 in 997, enable from Parties configuration

SNAGHTML16ab7ff

Posted in BizTalk. 1 Comment »

BizTalk: ‘Unspecified error’ when starting Host Instance

 

I was stuck with this error when starting BizTalk host instances after database connectivity was lost and resumed,

SNAGHTML4aab330

event log:

A failure occurred when executing a Windows service request.
 
Service request: Start
 
BizTalk host name: BizTalkServerApplication
Windows service name: BTSSvc$BizTalkServerApplication
 
Additional error information:
Error code: 0x80131604
Error source: mscorlib
Error description: Exception has been thrown by the target of an invocation.

 

one of possible reasons (among other is a reported issue in BizTalk – and MS provides CU for it) is a new section in BizTalk config file that is not declared in machine.config. In my case, I added a new config section to define appSettings configuration keys  – but I forgot to update machine.config first

<system.configuration> 

</system.configuration>

BizTalk ESB: Exception Handling in Orchestration

here is how to use Exception Handling framework from Orchestration

This post is about couple of errors that consumed lots of time to figure out when testing an implementation that uses ESB Exception Handling framework.

in windows event log (BizTalk ESB Toolkit 2.1):

Object reference not set to an instance of an object.

Source: Microsoft.Practices.ESB.ExceptionHandling.PipelineComponents.ProcessFault

Method: Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext, Microsoft.BizTalk.Message.Interop.IBaseMessage)

Error Source: Microsoft.Practices.ESB.ExceptionHandling.PipelineComponents

Error TargetSite: Void WriteHeaderFailedMessageRouting(System.Xml.XmlTextWriter, Microsoft.BizTalk.Message.Interop.IBaseMessage, System.Object ByRef) 

Error StackTrace:    at Microsoft.Practices.ESB.ExceptionHandling.PipelineComponents.ProcessFault.WriteHeaderFailedMessageRouting(XmlTextWriter writer, IBaseMessage pInMsg, Object& portName)
   at Microsoft.Practices.ESB.ExceptionHandling.PipelineComponents.ProcessFault.WriteHeader(XmlTextWriter writer, XmlTextReader reader, FaultSource faultSource, IBaseMessage pInMsg, Object& portName)
   at Microsoft.Practices.ESB.ExceptionHandling.PipelineComponents.ProcessFault.Execute(IPipelineContext pContext, IBaseMessage pInMsg)

Reason:

// Add the message to the Fault Message
Microsoft.Practices.ESB.ExceptionHandling.ExceptionMgmt.AddMessage(MsgFaultMultipart, MsgInboundMessage);

this line is required in Orchestration code for ProcessFault pipeline component to work.

 

in windows event log:

xlang/s engine event log entry: Uncaught exception (see the ‘inner exception’ below) has suspended an instance of service (a42d0855-ec7c-3dc7-5e9f-442c84746e85)’.

The service instance will remain suspended until administratively resumed or terminated.

If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.

InstanceId: 003a57d2-42b3-4a20-8cfa-a03b810df217

Shape name: Send_1

ShapeId: ad8c422b-4b45-41c5-bd0b-5ce958491e1e

Exception thrown from: segment 5, progress 8

Inner exception: Exception occurred when persisting state to the database.

       
Exception type: PersistenceException

Source: Microsoft.XLANGs.BizTalk.Engine

Target Site: Void Commit()

The following is a stack trace that identifies the location where the exception occured

   at Microsoft.BizTalk.XLANGs.BTXEngine.BTXXlangStore.Commit()

   at Microsoft.XLANGs.Core.Service.Persist(Boolean dehydrate, Context ctx, Boolean idleRequired, Boolean finalPersist, Boolean bypassCommit, Boolean terminate)

   at Microsoft.XLANGs.Core.ServiceContext.PendingCommit(Boolean ignore, XMessage msg)

   at Microsoft.XLANGs.Core.ExceptionHandlingContext.PendingCommit(Boolean ignoreCommit, XMessage msg)

   at Microsoft.XLANGs.Core.ExceptionHandlingContext.PendingCommit(Boolean ignoreCommit, XMessage msg)

   at Microsoft.BizTalk.XLANGs.BTXEngine.BTXPortBase.SendMessage(Int32 iOperation, XLANGMessage msg, Correlation[] initCorrelations, Correlation[] followCorrelations, Context cxt, Segment seg, ActivityFlags flags)

   at XX.segment5(StopConditions stopOn)

   at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)

Additional error information:

        A batch item failed persistence Item-ID 5f10694f-5a1f-4b05-ab88-6c9edbd1140d OperationType MAIO_CommitBatch Status -1061151998 ErrorInfo The published message could not be routed because no subscribers were found. .

       
Exception type: PersistenceItemException

Additional error information:

        Failed to publish (send) a message in the batch. This is usually because there is no one expecting to receive this message.  The error was The published message could not be routed because no subscribers were found.  with status -1061151998.

       
Exception type: PublishMessageException

       

Reason:

1. Add Microsoft.Practices.ESB in your Application’s References

2. configure a SQL send port with ProcessFault pipeline component to insert exception in ExceptionDB.

(Alternatively, we can use All.Exceptions send port that was created with ESB Core installation)

17-Sep-12 12-24-36 PM