January 2008 - Posts

ESB Guidance...part 5
25 January 08 12:03 AM | wmmihaa | 2 comment(s)
Extending ESB Guidance

·         Blogical.Adapter.SQL - Download

·         Blogical.Adapter.SMTP - Download

·         Blogical.Resolver.LDAP - Download

·         Blogical.Resolver.SQL - Download

Adapter Provider Framework
After a resolver executes, the dynamic resolution service checks whether the result is an endpoint (not a transformation). If it is an endpoint, the service instantiates the adapter manager, which validates and fixes the transport type and the outbound transport location.
The adapter manager uses the suffix stated in the transport location (eg FTP://) to determine the appropriate adapter provider. An adapter provider is a custom assembly that must implement the IAdapterProvider interface. The adapter provider uses the properties of the Resolution structure within the Dictionary instance generated by the resolver to set all the protocol-specific properties of the message that enable the BizTalk run-time engine to perform dynamic resolution.

The Resolver Framework

The itinerary describes a composition of services to be executed, such as transformation, routing and dynamic end-point resolution. Each of which works with a set of resolvers, that will provide the necessary input for that service or endpoint. Which resolver to be used is described by a moniker Eg UDDI://.
A resolver takes the resolver connection string, validates it, and uses the result to query and populate a Dictionary object that Adapter Providers and Services can use.


SQL Adapter provider

The integrated SQL adapter, which ships with BizTalk Server, is designed for sharing data between BizTalk Server and Microsoft SQL Server databases. The Blogical.Adapter.SQL adapter provider reads the Resolver.EndpointConfig property from the chosen resolver and sets the necessary context properties for SQL adapter.

Resolver configuration sample:

<Resolvers serviceId="DynamicTest0">
&lt;![CDATA[STATIC:\\TransportLocation=SQL://;EndpointConfig=
IntegratedSecurity=SSPI&amp;
PersistSecurityInfo=False&amp;
InitialCatalog=EsbAdmin&amp;
DataSource=localhost&amp;
DocumentTargetNameSpace=http://SQLSendProject1=&amp;
ResponseDocumentRootElementName=PersonResponse;]]&gt;</Resolvers>

 

Machine.Config settings:

<add key="SQL"
         value="Blogical.Adapter.SQL,
         Version=1.0.0.0, Culture=neutral,
         PublicKeyToken=c2c8b2b87f54180a" />

 

Supported Resolvers: STATIC, BRE

 

SMTP Adapter provider
BizTalk Server can send messages to other applications by creating an e-mail message and delivering it to a specified e-mail address. One often mentioned problem, when using the SMTP adapter, is that the To address property makes up the actual send port uri and is there for not be dynamically set if you’d like to send (route) different messages to different users. This issue can be solved by using a dynamic send port and set the SMTP properties at runtime.  The Blogical.Adapter.SMTP adapter takes on the very same approach and reads the Resolver.TransportLocation and the Resolver.EndPointConfig from the chosen resolver and sets the necessary context properties.

 

Resolver configuration sample:

<Resolvers serviceId="DynamicTest0">
&lt;![CDATA[STATIC:\\TransportLocation=SMTP://someone@bts2006.com;
EndpointConfig=SMTPHOST=MySmtpHost&amp;
FROM=noreplyn@bts2006.com&amp;
SUBJECT=A Subject]]&gt;
</Resolvers>

 

Machine.Config settings:

<add key="SMTP"
         value="Blogical.Adapter.SMTP,
         Version=1.0.0.0, Culture=neutral,
         PublicKeyToken=c2c8b2b87f54180a" />

Supported Resolvers: STATIC, BRE, Blogical.Resolver.LDAP 

LDAP Resolver

The Blogical.Resolver.LDAP resolver makes an Active Directory lookup and populates the Resolution object with Mail address, SMTP server name, From address and Subject.

This Resolver only works with the SMTP Adapter Provider

Itinerary usage:

SQL Resolver

If you’d like to use a SQL database as a repository for your services and endpoints, the Blogical.Resolver.SQL might be what you’re looking for. In this sample I’ve created a table that maches the resolution object. The resolver expects a query where returning a single row, for example:

SELECT * FROM tblResolution WHERE id='CAAE0F7E-417C-4F18-9958-8EECB6F93CAE'

The Resolver will populate the Resolution dictionary with every column/value pair.

Itinerary usage:

<Resolvers serviceId="DynamicTest0">
&lt;![CDATA[SQL:\\DataSource=localhost;
InitialCatalog=EsbExceptionDb;
IntegratedSecurity=SSPI;
Query=select * FROM tblResolution where id='CAAE0F7E-417C-4F18-9958-8EECB6F93CAE']]&gt;
</Resolvers>

 

ESB Guidance...part 6

Filed under: , ,
ESB Guidance...part 4
06 January 08 11:34 PM | wmmihaa | 38 comment(s)
Extending the ESB Guidance

If what you get from ESB Guidance is not enough, there are three areas you should look in to:

·         Adapter Providers

·         Resolvers

·         Services

Building your own Adapter Provider

When the message has been processed, it is going to be sent to its destination through a dynamic send port, (a.k.a off-ramp). Usually, when using a dynamic port, we’d set the port properties such as transport type and location programmatically in an expression shape (orchestration) or in a custom pipeline component.

In the case of ESB Guidance this is all done using an Adapter Provider. In other words, the Adapter Provider serves to write and promote context properties for specific adapters.

ESB Guidance comes with support for the most common adapters such as WCF-BasicHttp, WCF-WSHttp, MQSeries, FILE and FTP. But for the purpose of this article, we’ll create a SMTP provider.

 

1.       Start of by creating a new Class Library project. And rename the default class to AdapterProvider.

2.       Let the AdapterProvider inherit from the Microsoft.Practices.ESB.Adapter .IAdapterProvider interface and implement the two SetEndpoint methods. (I’m aware the code sample does not fit the size of the frame, but it works if you want to copy the text)

        public void SetEndpoint(Dictionary<string, string> ResolverDictionary, IBaseMessageContext pipelineContext)
        {
            if (null == ResolverDictionary)
                throw new ArgumentNullException("ResolverDictionary");
            if (null == pipelineContext)
                throw new ArgumentNullException("pipelineContext");

            try
            {
                string transportLocation = ResolverDictionary["Resolver.TransportLocation"];
                string endpointConfig = ResolverDictionary["Resolver.EndpointConfig"];

                string to = transportLocation.Replace("SMTP://", "");
                string from = string.Empty;
                string subject = string.Empty;
                string host = string.Empty;
                
                string[] endpointConfigs = endpointConfig.Split(':');

                foreach (string config in endpointConfigs)
                {
                    string[] configs = config.Split('=');
                    switch (configs[0].ToUpper())
                    {
                        case "SMTPHOST":
                            host = configs[1];
                            break;
                        case "FROM":
                            from = configs[1];
                            break;
                        case "SUBJECT":
                            subject = configs[1];
                            break;
                        default:
                            throw new ArgumentNullException("Invalid SMTP Adapter Provider Configuration");
                    } 
                }
                
                //First, set the outboundtransportlocation, transporttype and SMTP specific attributes
                pipelineContext.Write(BtsProperties.OutboundTransportLocation.Name, BtsProperties.OutboundTransportLocation.Namespace, transportLocation);
                pipelineContext.Write(BtsProperties.OutboundTransportType.Name, BtsProperties.OutboundTransportType.Namespace, "SMTP");
                pipelineContext.Write("From", "http://schemas.microsoft.com/BizTalk/2003/smtp-properties", from);
                pipelineContext.Write("OutboundTransportLocation", "http://schemas.microsoft.com/BizTalk/2003/system-properties", "mailto:" + to);
                pipelineContext.Write("Subject", "http://schemas.microsoft.com/BizTalk/2003/smtp-properties", subject);
                pipelineContext.Write("SMTPHost", "http://schemas.microsoft.com/BizTalk/2003/smtp-properties", host);

                // Second, loop through the endpointconfig, this should be ; seperated and set properties
                // by namespace of specific adapter
                if (!string.IsNullOrEmpty(endpointConfig))
                    AdapterMgr.SetContextProperties(pipelineContext, ResolverDictionary);

            }
            catch (System.Exception ex)
            {
                EventLogger.Write(MethodInfo.GetCurrentMethod(), ex);
                throw;
            }
        }
3.       Build and GAC the project. 

4.       Add the new AdapterProvider to the <AdapterProvider> section of your machine.config.

Eg:

<add key="SMTP"
         value="Blogical.Adapter.SMTP,
                Version=1.0.0.0, Culture=neutral,
                PublicKeyToken=c2c8b2b87f54180a" />

5.       Restart IIS and BizTalk.

6.       Create an Itinerary and attach a STATIC resolver to your service (“DynamicTest” in this sample)

E.g:

<Resolvers serviceId="DynamicTest0">&lt;![CDATA[
STATIC:\\TransportLocation=SMTP://mikael.hakansson@bts2006.com;
EndpointConfig=SMTPHOST=labs:FROM=noreplyn@bts2006.com:SUBJECT=This is a test mail;]]&gt;</Resolvers>
 ESB Guidance...part 5
Filed under: ,

This Blog

News

    MVP - Microsoft Most Valuable Professional BizTalk User Group Sweden BizTalk blogdoc

    Follow me on Twitter Meet me at TechEd

    Visitors

    Locations of visitors to this page

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

Syndication