Wednesday, August 29, 2007

Enterprise Single Sign-on Service (SSO) as a configuration store (III)

In this article I will explain how to do a .NET class to get config properties from an SSO Affiliate Application.

First of all, we have to add a reference in our project to this DLL:
Common Files\Enterprise Single Sign-On\SDK\Bin\Microsoft.BizTalk.Interop.SSOClient.dll

Then we have to implement a class that implements IPropertyBag, something like this:

using Microsoft.BizTalk.SSOClient.Interop;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace SSOConfig{
   public class PropertyBag : IPropertyBag
   {
      private Hashtable _hashTable;
      public PropertyBag()
      {
         _hashTable= new Hashtable();
      }
      public void Read(string propName, out object ptrVar, int errorLog)
      {
         ptrVar = _hashTable[propName];
      }
      public void Write(string propName, ref object ptrVar)
      {
         if (_hashTable.ContainsKey(propName))
            _hashTable[propName] = ptrVar;
         else
            _hashTable.Add(propName, ptrVar);
      }
   }
}

Now, we can implement our class that gets properties from our affiliate application:

using Microsoft.BizTalk.SSOClient.Interop;
using System;
using System.Collections.Generic;
using System.Text;

namespace SSOConfig{
   public class SSOSettingsGetter    {

      private const string SSO_APPLICATION_NAME = "My Application";
      private const string SSO_IDENTIFIER_NAME = "ConfigProperties";

      public object GetProperty(string propertyName)
      {
         ISSOConfigStore appStore = new ISSOConfigStore();
         PropertyBag pb = new PropertyBag ();
         appStore.GetConfigInfo(SSO_APPLICATION_NAME, SSO_IDENTIFIER_NAME, SSOFlag.SSO_FLAG_RUNTIME, pb);
         object propertyValue = null;
         pb.Read(propertyName, out propertyValue, 0);
         return propertyValue;
      }
   }
}

Enterprise Single Sign-on Service (SSO) as a configuration store (II)

In previous article, I explained how to create an affiliate application in SSO. The most important thing was this lines:

...
<appAdminAccount>BizTalk Server Administrators</appAdminAccount>
<appUserAccount>BizTalk Application Users</appUserAccount>
...
<flags configStoreApp="yes" allowLocalAccounts="yes" enableApp="yes" />

First lines are important because our user should be under one of previous groups. Last line is important because determine that our application is for configuration.

Now I will explain how to set/get the properties' values from command line. We have to use BTSScnSSOApplicationConfig.exe tool.
The sintaxis for this tool to set a value is:
BTSScnSSOApplicationConfig.exe -set <appName> <id> <propertyName> <propertyValue>
The sintaxis for this tool to get a value is:
BTSScnSSOApplicationConfig.exe -get <appName> <id> <propertyName>

For example, to modify my "db.passwd" value:
BTSScnSSOApplicationConfig.exe -set "My Application" ConfigProperties db.passwd mynewpasswd

To obtain this value:
BTSScnSSOApplicationConfig.exe -get "My Application" ConfigProperties db.passwd

Monday, August 27, 2007

Differences/Similarities between WCF behaviors and BizTalk pipelines

Great Jesus Rodriguez's about wich WCF features are similar to BizTalk pipelines and wich are different, how this features can complement existing BizTalk pipelines features and which overlaps existing pipeline features:
http://weblogs.asp.net/gsusx/archive/2007/08/23/wcf-behavior-vs-pipelines-on-biztalk-server-r2.aspx

Here another article by Tomas Restrepo from a different point of view:
http://www.winterdom.com/weblog/2007/08/25/WCFAndBizTalkMessaging.aspx

Saturday, August 18, 2007

Enterprise Single Sign-on Service (SSO) as a configuration store (I)

If we want store our BizTalk application configuration in SSO, first we have to create our affilitiate application with an XML similar to this:

<sso>
<application name="My Application">
<description>My application description</description>
<contact>felixmondelo@gmail.com</contact>
<appAdminAccount>BizTalk Server Administrators</appAdminAccount>
<appUserAccount>BizTalk Application Users</appUserAccount>
<field ordinal="0" label="reserved" masked="no"/>
<field ordinal="1" label="db.passwd" masked="yes" value="passwd" />
<field ordinal="2" label="db.conn.string" masked="yes" value="Data Source=localhost;Initial Catalog=MyDb;Integrated Security=True" />
<flags configStoreApp="yes" allowLocalAccounts="yes" enableApp="yes" />
</application>
</sso>

For more information about each field in this xml go to http://msdn2.microsoft.com/en-us/library/ms961685.aspx.

Then we have to insert this application into SSO with this executable "%root%\Program Files\Common Files\Enterprise Single Sign-On\ssomanage.exe". Sintaxis to create an application is:
ssomanage.exe -createapps <previous xml document path>, for example:
ssomanage.exe -createapps myssoappconfiguration.xml.

Tuesday, August 14, 2007

Stored Procedure to return a Policy to its editable state

When we publish or deploy a Policy during development, if we want to modificate the Policy we need to create a new version. With this stored procedure, we can unpublish/undeploy our Policy and modificate it:

CREATE PROCEDURE [dbo].[re_setpolicyeditable] (@policyName nvarchar(256),@nMajor bigint, @nMinor bigint)

AS

DECLARE @nRuleSetID AS BIGINT

SET @nRuleSetID = (SELECT nRuleSetID FROM dbo.re_ruleset WHERE strName = @policyName AND nMajor = @nMajor AND nMinor = @nMinor)

IF @nRuleSetID IS NULL BEGIN PRINT 'The Policy [' + @policyName + ' ' + CAST(@nMajor AS nvarchar(10)) + '.' + CAST(@nMinor AS nvarchar(10)) + '] not exists.' RETURN

END

UPDATE dbo.re_ruleset SET nStatus = 0 WHERE nRuleSetID = @nRuleSetID

DELETE FROM dbo.re_deployment_config WHERE nRuleSetID = @nRuleSetID

DELETE FROM dbo.re_tracking_id WHERE nRuleSetID = @nRuleSetID

INSERT INTO dbo.re_deployment_history VALUES (@policyName , 1, 0, 0, getdate())

GO

Friday, August 10, 2007

Microsoft.BizTalk.Component.Utilities.dll (or how to add reference to a dll wich is only in the GAC)

There are some DLLs wich are located only in the GAC, there is no physical file in our computer. Visual Studio does not allow you to add references to components in the GAC.

We have two alternatives:

1) Copy the file from the GAC to a physical file:
copy C:\WINDOWS\assembly\GAC_MSIL\
Microsoft.BizTalk.Component.Utilities\
3.0.1.0__31bf3856ad364e3\
Microsoft.BizTalk.Component.Utilities.dll

2) Unload the project, edit it and add manually the reference:

<itemgroup>
<reference include="Microsoft.BizTalk.Component.Utilities, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<reference include="Microsoft.BizTalk.Pipeline, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<specificversion>False></specificversion>
<hintpath>..\..\lib\Microsoft.BizTalk.Pipeline.dll></hintpath>
</reference>

Wednesday, August 08, 2007

InterchangeId vs MessageId

Here is an excerpt from "Professional Biztalk Server 2006" book explaining wich is the most appropiate identifier for a message in BizTalk:
"The most appropriate identifier to use is the BTS.InterchangeID message context property. The interchange ID is a GUID that is created by the engine. It is flowed automatically by the Messaging Engine as the message passes through the pipeline. You should note that the Message ID is typically not appropriate, since the message may be cloned multiple times during its processing, as described in Chapter 4, and each clone will have a unique Message ID. The Orchestration Engine will also flow the BTS.InterchangeID message context property where it can, although you must flow the property yourself in scenarios in which you create new messages"

NAnt - Error Handling

When an error occurs in a NAnt process, we can execute an error handling task. We only need to set "nant.onfailure" property to point to valid target element in the build file.

Example:

<property name="nant.onfailure" value="myproject.error" />

<target name="myproject.error">
  <call failonerror="false" target="myproject.error.deletetempfiles" />
  <call failonerror="false" target="myproject.error.deletetestcertificates" />
  <call failonerror="false" target="myproject.error.deletesettings" />
</target>