Saturday, September 3, 2011

Global Context Field which is independent of a Message

I was thinking of writing about a Context field which is independent of message. Imagine a Scenario where you would like to promote a field only for routing no matter what the incoming file content is, you know one thing for sure that there is a field in the content of the file(FF,XML,EDI) which has the data for routing to destination system. In this case it never makes sense to create a Schema and promote the field as Distinguished or Property field and only for routing you don’t even need to create an Orchestration.Message In….. MessageOut ….simple J
So I thought to show you how simple is it to do with BizTalk.
  1. Create a new BizTalk project and add a new Property Schema which will have our Global PropertySchema field.
  2. Let’s add a field called Property1 to this Property Schema. Set the PropertySchemaBase as MessageContextPropertybase. So by this we say that the field Property1 will not be dependent upon the message content or it won’t be linked to any field in the message. 
  3. This namespace below is important. This is the namespace in which this property field (Property1) will be promoted globally.
  4. Deploy the solution to BizTalk so our global property Schema is in BizTalk.
  5. You can promote this field from any pipeline or Orchestration as shown below. pInMsg.Context.Promote(“Property1”,"https://BizTalk_Server_Project3.PropertySchema1", "Test");
  6. If you want to access it from Orchestration then it’s important to know the .Net Namespace the property belongs to as shown below in the properties.
The Property field (Property1) can easily be accessed from the Orchestration with the .Net namespace. strProp=Msg_XmlDocumentIn(BizTalk_Server_Project3.Property1);
Simple enough…promotions are important as they can save lot of your design time to plan complex Integration's. Promotions can help you route any message from a ReceivePort to SendPort but I limit the use of such uncontrolled scenarios and use Orchestration as it gives me full control over the message for complex scenarios… ;) .

Wednesday, May 11, 2011

SQL Receive Adapter: Multiple tables in different Database

Last week I had a simple scenario where BizTalk Server will use a SQL Receive Adapter and poll a SQL Stored Procedure(SP) which will return the rows from multiple tables spread across 2 different database.
Initially I thought the only catch out here will be to grant rights across all tables for the same User Account with which Biztalk polls the SP. Following were the last 2 lines of my proc.
SET @ReturnXML=SELECT  * FROM ABC INNER JOIN DB2.dbo.XYZ as XYZ ON ABC.FIELD1=XYZ.FILED2 WHERE ABC.UpdateID=@UpdateID FOR XML AUTO,ELEMENTS
Select @ReturnXML
The SP worked perfect from SQL Query window but I started getting the following error when called by BizTalk SQL Receive Adapter.
Event ID: 5740
Description:The adapter "SQL" raised an error message. Details "HRESULT="0x      7a" Description="Description not provided"

I thought I am missing some access rights on the 'XYZ' table, I granted all possible rights for the user on the table but still the same issue. After struggling for 2 days I thought to concentrate only on what the SP returned in the last 2 lines shown above.I felt that BizTalk is having an issue with the data returned from SP as it wont care what you do in the SP.BizTalk is only interested in the results(rows) returned,So I removed the variable(@ReturnXML) and it worked. So SP now returns the SQL Query directly.
SELECT  * FROM ABC INNER JOIN DB2.dbo.XYZ as XYZ ON ABC.FIELD1=XYZ.FILED2 WHERE ABC.UpdateID=@UpdateID FOR XML AUTO,ELEMENTS

Hope it helps you.

Tuesday, May 3, 2011

BAM Portal Activity Search: "This action cannot be performed because one or more database(s) appears corrupted"

Hi,
I noticed this error when I tried to search on an Activity in the BAM Portal.








I googled and noticed a good description about this issue by Gilles but it did not help me resolve the problem.

So I thought of fixing it in the BAM (BAMPrimaryImport)database as it clearly said about duplicate entry. I searched on the ActivityID and found only 1 record in "bam_ActivityName_active" table and I also found 1 record in the "bam_ActivityName_completed" Activity table.
SELECT * FROM [BAMPrimaryImport].dbo.bam_ActivityName_active where ActivityID='{42B99A00-4A43-40D4-8F6F-183851984197}'
So I thought that its not a duplicate issue as the Error says as I saw only 1 entry in each tables.
But I was wrong.

The issue is that there should not be any pending records in the Active tables if  the Activity is completed ie. if there exist a record in _Completed table for the same ActivityID.
In my case I intiated an Activity(BeginActivity) and Biztalk failed while updating the Actvity(UpdateActivity)and after that I completed the Activity(EndActivity). So there was an Orphan record in the _active table.
So I deleted all the records from _active table and it worked fine.
DELETE FROM [BAMPrimaryImport].dbo.bam_ActivityName_active

So this is what BizTalk means by Duplicate records.
"There should not be a record in the _active table if the activity has a record in the _completed table for the same ActivityID.If it exist then its a duplicate Error."

Error in Eventlog was as follows:
Event Type: Error
Event Source: BAM Portal
Description:
(BAMPortal.PortalApplication) Void LogAllErrors(System.Exception[]): System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: There are instances with duplicate ID '{42B99A00-4A43-40D4-8F6F-183851984197}' in activity 'xxx'. The duplicates must be removed from the database to fix this problem.
   at Microsoft.BizTalk.Bam.WebServices.Query.BamQueryService.GetInstanceData(String viewName, String activityName, InstanceQuery query, Int32 timeout)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at Microsoft.BizTalk.Bam.WebServices.QueryService.BamQueryService.GetInstanceData(String viewName, String activityName, InstanceQuery query, Int32 timeout)
   at Microsoft.BizTalk.Bam.Portal.DataAccess.QueryResultsObjectDataSource.ExecuteQuery(SQLQuery query)
   at Microsoft.BizTalk.Bam.Portal.DataAccess.QueryResultsObjectDataSource.EnsureData(SQLQuery query)
   at Microsoft.BizTalk.Bam.Portal.DataAccess.QueryResultsObjectDataSource.QueryResults(SQLQuery query)
   at BAMPortal.Search_aspx.ExecuteQuery()
   at BAMPortal.Search_aspx.executeQueryButton_Click(Object sender, CommandEventArgs e)
   at System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   --- End of inner exception stack trace ---
   at System.Web.UI.Page.HandleError(Exception e)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.pages_search_aspx.ProcessRequest(HttpContext context)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)



Happy Talking Biz. ;)

Thursday, April 21, 2011

MIME.FileName= "Blank" ??

Hi,
While working on an Integration to receive a file via email as attachment we normally use POP3 Adapter and MIME Decoder enabled So that the MIME Context fields are filled in properly. I googled on how does the POP3 Adapter populates it. This link helped me understand it better.
BizTalk uses the following logic to get the file name:
1. Take it from the Content-Description header. Some vendors don't populate the Content-Description header in the message sent to Exchange.
2. If not found, then the part name is based on the Content-ID header.
3. If still not found, then generate a GUID for the part name.

In our Scenario MIME.FileName was blank and the reason was the Mail Header was missing "content-disposition" field for Attachments.
Actual Header:
content-type: application/octet-stream; name=SampleAttachment.zip
content-transfer-encoding: base64
Expected Header:
content-type: application/octet-stream; name=SampleAttachment.zip
content-transfer-encoding: base64
content-disposition: attachment; filename=SampleAttachment.zip

Scott did shed some light on this issue out here
We had a discussion with the Vendor to populate content-disposition field for attachments in header but they were clear that their Mail Server guys will not accept this Change Request as the FileName is already available in ContentType field in the Mail header.Well actually the BizTalk MIME Decoder does populates it in "PartContentTypeSecondaryHeaderValue" .

So we handled it this way
if(MIME.FileName="")
filename = MIME.PartContentTypeSecondaryHeaderValue
I could not find much about this field.
Hope it helps you while working with FileNames in Mail Attachments.

Happy Integrating,
Nishil

Wednesday, May 19, 2010

Microsoft BizTalk Server 2009 Adapters for Host Systems 2.0 on BizTalk 2009 64 bit


Hi All,
BizTalk Server 2009 Adapters for Host Systems 2.0 are used to communicate with Host Systems like DB2 Databases.
  • Do we need HIS to be installed to work with these adapters?
          No,Host System Adapters can work with BizTalk just like normal adapters without HIS Server.
  • Are there any 32 bit or 64 bit Adapters for Host System?
          The Host System Adapters installation files are by default 32 bit installers.
          So you wont find any 64 bit installation files.
  • Does BizTalk 2009 64 bit support these Adapters?
          No,Biztalk only supports these adapters in 32 bit  mode.
          http://msdn.microsoft.com/en-us/library/aa560166(BTS.10).aspx
32-bit support64-bit support
HTTP-based adapters (IIS)
Yes
Partial
BizTalk Host instances
Yes
Yes
Enterprise SSO
Yes
Yes
BAM portal (IIS)
Yes
No
 SQL Server
Yes
Yes
  • So how we work with these adapters if we install BizTalk 2009 in 64 bit mode?
          You can install 64 bit BizTalk on a 64 Bit Operating System like Windows 2008 R2 but you will have to configure BizTalk to run in 32 Bit mode only.

If you install the Adapters for Host System on a 64 bit BizTalk installed over a 64 bit Operating system,it will install successfully but you will not find those adapters(DB2...etc) in the Adapter list or on any ports.
So best option is to Install BizTalk in 64 bit mode but configure it to run in 32 bit mode using "BizTalk Configuration Wizard" and then install the Adapters for Host System.

Hope it helps you as it took few hours before I could figure this out and I did not get any Error while installing the Adapters and nor could I see them in the Adapter List.

Thursday, October 22, 2009

Using the Lob WCF-Custom SQL Adapter to Submit a message to SSB queue from BizTalk


Hi All,
Recently on a project I had an integration where the destination wanted BizTalk to drop the message in a SQL Service Broker Queue.
The first thing I thought when I heard it was "SQL Queue?".Heard of MSMQ but SQL Queue,when did Microsoft come up with this concept.I really never heard of it and why we use it.
So I started googling on SQL Service Broker and found this good MSDN section
http://msdn.microsoft.com/en-us/library/bb522893.aspx
Here you will also find some tutorials to start working on
http://msdn.microsoft.com/en-us/library/bb839489.aspx

So after gaining some SQL Borker knowledge I googled as how this  works with BizTalk.
For a scenario where
BizTalk needs to read a message from the SSB Queue this article from WCF Lob Adapter pack Team was a perfect sample.
http://blogs.msdn.com/adapters/archive/2008/06/30/using-the-wcf-sql-adapter-to-read-messages-from-ssb-queues-and-submit-them-to-biztalk.aspx
So now I know how BizTalk how BizTalk can read a Message from a SSB Queue.
But what about Sending a message to the SSB Queue?
So lets start with a simple scenario for this.

1.I will have to Enable SQL Service Broker on any database.Lets use the Master database for our scenario.
2.Note we dont need to create any table to work with SSB Queues and BizTalk.So you can Create a new Database and enable SSB on it.
2.Then we need to create a new Queue.
3.Run this Script in the SQL Query window and you should be ready with the basic setup.

USE master;
GO
ALTER DATABASE master SET NEW_BROKER with rollback immediate;
ALTER DATABASE master SET ENABLE_BROKER with rollback immediate;

GO
USE <your db name here>;
GO

CREATE MESSAGE TYPE
    [Message1]
    VALIDATION = None;

CREATE CONTRACT [Contract1]
    ([Message1]
    SENT BY ANY
    );

CREATE QUEUE Queue1;

CREATE SERVICE
    Service1
    ON QUEUE Queue1(Contract1);



So I created only 1 Queue named "Queue1" and with a contract and message type.
Dont worry this is not Biztalk MessageType.
Now we will create a SQL Stored Procedure which will insert a xml in this queue.
USE [master]
GO
/****** Object:  StoredProcedure [dbo].[InsertMsgInQueue]    Script Date: 10/01/2009 11:47:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:  <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
Create PROCEDURE [dbo].[InsertMsgInQueue]
 -- Add the parameters for the stored procedure here
 @XMLIn XML
AS
BEGIN
 DECLARE @RequestMsg XML;
SELECT @RequestMsg = @XMLIn;
  DECLARE @DlgHandle UNIQUEIDENTIFIER; BEGIN DIALOG @DlgHandle
  FROM SERVICE [Service1] TO SERVICE N'Service1'
  ON CONTRACT [Contract1] WITH ENCRYPTION = OFF
  SEND ON CONVERSATION @DlgHandle MESSAGE TYPE [Message1] (@RequestMsg);
END


Now I will have to call this generic SP from BizTalk Send port and insert any XML in the SSB Queue(Queue1).
So now its time for BizTalk part of this Scenario.
Scenario :When we drop a file in a Folder  the Receive port picks up the file and sends the file to the Send Port via a Filter(ReceivePortName).
I hope every BizTalk Developer knows how this works....ping me if you dont.
No Orchestration is involved.
Next we need to configure the Send port so we can send the message to the Queue.
Just configure the Send port as Shown below in Screen1 and Screen2.

Screen1

Screen2
The Template code inside Screen2 is
<InsertMsgInQueue xmlns="http://schemas.microsoft.com/Sql/2008/05/Procedures/dbo">
<XMLIn>
<bts-msg-body xmlns="
http://www.microsoft.com/schemas/bts2007" encoding="string"/>
</XMLIn>
</InsertMsgInQueue>

Thats it.
Now start the ports drop any xml file in the "In" Folder and it should be insert inside the Queue.
No Orchestration,Only pure Message Based Routing simple solution.
Hope it helps somebody as I found it tough when I googled for a sample on this scenario.
So this was it all about Sql Service Broker and BizTalk.
Happy BizTalking.

Monday, June 15, 2009

Biztalk BAM Portal Issues


Hi,
I tried to configure BAM for the first time and failed with error Access Denied 401.2.
Event code: 4007
Event message: URL authorization failed for the request.
Event time: 15.06.2009 10:21:22
Event time (UTC): 15.06.2009 08:21:22
Event ID: db49acbf6d1c42d9b3228e5e8abdf0ce
Event sequence: 2
Event occurrence: 1
Event detail code: 0

Application information:
    Application domain: /LM/W3SVC/1/ROOT/BAM-1-128895276813021664
    Trust level: BAMPortal_Minimal
    Application Virtual Path: /BAM
    Application Path: C:\Program Files\Microsoft BizTalk Server 2009\BAMPortal\

Process information:
    Process ID: 5172
    Process name: w3wp.exe
    Account name: NISHIL\Administrator

Request information:
    Request URL: 
http://localhost/BAM/Default.aspx
    Request path: /BAM/Default.aspx
    User host address: ::1
    User: NISHIL\Administrator
    Is authenticated: True

I configured BAM using Administrator account as User everywhere ,even on the BAM App pool ,So for sure I knew this error is not about authentication.
What I found is in Biztalk Configuration Tool under BAM portal I had selected windows group "Role Name" ,"Bam Portal Users" as "Administrators" so that the Administrator User can easily access the portal.
But this is not correct.
I reconfigured BAM portal using "Role Name" as "Biztalk Server Administrators" and it worked fine.
Might be the group needs to be one of the Biztalk groups.Hope this post helps somebody.
------------------------------------------------------------------------
Other Solutions found on google which did not work for me were
1).Adding IIS 6 Management tools for backaward compatilibity since I use Windows 2008 and IIS 7 and Biztalk 2009.
2).Changing AuthenticationProviders cscript adsutil.vbs set w3svc/NTAuthenticationProviders "NTLM"