Debatching SWIFT messages

by ion.robu 24. February 2009 11:24

 

SWIFT is a standard which describe acollection of messages formats. There are a lot of financial applications whichworks with financial transactions, and, often, these applications must communicatebetween them. Because each of them worked with certain formats, there washarder and harder to maintain a good transmission of information, and requireda lot of time and effort.

Because of that, SWIFT standard wasreleased to describe how the messages should be structured and how to exposethe information, in order to be properly interpreted, to be easier tomanipulate and, thanks God, make developer life easier. []

There are few hundreds of SWIFT messages,called generically MTXXX, where XXX is a 3-digit number. A SWIFT message is composed,as general structure, from 3 parts, header, body and trailer, and each of themare composed by fields, well delimited by field identifiers (labels). Forexample, a transaction of MT103 type:

 

{1:F01BANKINFOAXXX1234567890}{2:O1037549081128ABCDOP2LCYYY40369224800811281431N}{3:{108:08B2807310101800}{119:STP}}{4:

:20:123456786

:23B:ABCD

:32A:081128EUR11111,11

:33B:EUR11111,11

:50K:/000011111

TEST COMPANY

TEST STREET

TEST CITY

TEST COUNTRY

:52A:ABCDGB2LXXX

:53A:ABCDNL2AXXX

:59:/ZZ96ABCD0002001126690718

810252 TEST TEST TEST CITY

TEST COUNTRY

ZZ

:71A:AAA

:77B:3

172929

-}{5:{CHK:70788693BBA7}{MAC:00000000}}{S:{SAC:}{COP:P}}

 

(note: the dates within transaction arenot real, as we are not interested about data, but about structure).

Thus, all information is well representedand has a well-known position inside of message – sender address, senderaccount, amount, date, receiver address etc., giving possibility to createsoftware mechanisms to extract useful data from message.

But, although we know now the structureof messages, is still hard to work with them. We still have complicatedstructures of messages, and, if an application works with many types ofmessages, the development is still a nightmare for us.

In this respect, Microsoft has elaborateda package, which comes to help BizTalk developers on financial applications.This package comes with description of every SWIFT message, providing a schemafile and a policy file for each SWIFT message type, to be used in applications.This is great, because the schema is, most of the time, the hardest part todevelop when we create an import or export channel. All we have to do further,to create a channel, is to develop a map, a pipeline, a destination schema (forimport) or source schema (for export) and to configure some ports.

After create all of these elements, wecan still have a problem: when import file contains more than one message, wecannot import them all using a simple pipeline, having just schemaspecifications. We can even specify the number of message elements in schema tobe * (unbounded), no effect. Biztalk does not know to “break” the file intomessages, and only the first message will be imported.

For that, we can use a technique named“debatching”. Practically, we must manually break the message before to send itto the message schema in order to be validated and, after that, mapped todestination schema.

More exactly, we will develop a pipelinecomponent, which will be added to Disassemble step on the pipeline:

 

Here is the code of pipeline component:

 

using System;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.ComponentModel;

usingMicrosoft.BizTalk.Component;

usingMicrosoft.BizTalk.Component.Interop;

usingMicrosoft.BizTalk.PipelineOM;

usingMicrosoft.BizTalk.Message.Interop;

using System.IO;

usingMicrosoft.Solutions.FinancialServices;

usingMicrosoft.Solutions.FinancialServices.SWIFT;

usingMicrosoft.Solutions.FinancialServices.SWIFT.Pipelines;

 

namespace SWIFT.Pipeline.Components

{

    [ComponentCategory(CategoryTypes.CATID_PipelineComponent)]

   [ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]

    [System.Runtime.InteropServices.Guid("116A2C53-4E95-4506-8110-AD2F924DEDDD")]

    public class SwiftFlatFileDisassembler: SWIFTDasm, IBaseComponent, IDisassemblerComponent, IPersistPropertyBag

    {

        /// <summary>

        /// Class constructor.

        /// </summary>

        publicSwiftFlatFileDisassembler(){}

 

        #region IDisassemblerComponentMembers

        /// <summary>

        /// Method is called by BizTalk when a new message is receivedon receive port.

        /// </summary>

        voidIDisassemblerComponent.Disassemble(IPipelineContext pContext,Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)

        {

            try

            {

               //here we can process the original streambefore disassembling

                     IBaseMessage_originalIBaseMessage = pInMsg;

              // callDisassemble method of base class to break the stream in individual messages

                base.Disassemble(pContext,pInMsg);

            }

            catch(Exception ex)

            {

                //threatpossible error

                throw;

            }

        }

 

        /// <summary>

        /// Total number of transactions.

        /// </summary>

        privateint _totalTransactions = 0;

       

        /// <summary>

        /// Method parse received file and identifies the transactions

        /// </summary>

       

       Microsoft.BizTalk.Message.Interop.IBaseMessageIDisassemblerComponent.GetNext(IPipelineContext pContext)

        {

            IBaseMessage iBaseMessage = null;

            try

            {

                //getiBaseMessage message from base class

                iBaseMessage = base.GetNext(pContext);

                // ifGetNext from base class don't return null we promote BatchId on messagecontext.

                if(iBaseMessage != null)

                {

                                  //check if message was successfully parsed, according toschema

                    boolmessageIsNotParsed = bool.Parse(iBaseMessage.Context.Read("A4SWIFT_Failed", "http://schemas.microsoft.com/A4SWIFT/Property").ToString());

                    if(messageIsNotParsed)

                    {

                        //threat error

                        throw new Exception(errorMessage);

                    }

                    _totalTransactions ++;

                   

                }

                else

                {

                     //finishof the message queue - process the _totalTransactions

                }

  

            }

            catch(Exception ex)

            {

                //threaterror

                throw;

            }

            returniBaseMessage;

        }

 

      

        #endregion

 

        #region IBaseComponent Members

        [Browsable(false)]

        stringIBaseComponent.Description

        {

            get{ return "SWIFTFlat File disassembler"; }

        }

        [Browsable(false)]

        stringIBaseComponent.Name

        {

            get{ return "SWIFTFlat File Disassembler"; }

        }

        [Browsable(false)]

        stringIBaseComponent.Version

        {

            get{ return "1.0.0.0";}

        }

 

                #endregion

 

        #region IPersistPropertyBag Members

 

        voidIPersistPropertyBag.GetClassID(out Guid classID)

        {

            classID = newGuid("116A2C53-4E95-4506-8110-AD2F924DEDDD");

        }

 

        voidIPersistPropertyBag.InitNew()

        {

            base.InitNew();

        }

 

        voidIPersistPropertyBag.Load(IPropertyBag propertyBag, interrorLog)

        {

            base.Load(propertyBag,errorLog);

        }

 

        voidIPersistPropertyBag.Save(IPropertyBag propertyBag, boolclearDirty, bool saveAllProperties)

        {

            base.Save(propertyBag,clearDirty, saveAllProperties);

        }

 

        #endregion

 

    }

 

}

 

      To create this component, add as referenceto the project the assemblies: Microsoft.Solutions.FinancialServices.SWIFT.PipelineComponents.SWIFTDasm,which comes with SWIFT 2007 Message Pack installation.

      

Thereare 2 methods, implemented by IDisassemblerComponent interface:

-         Disassemble – which breaks the originalstream (given as parameter) into individual messages and creates a queue, withthem

-         GetNext, which is calledfor each message in the queue, and get as parameter the message resulted afterapplying message schema to original message; thus, we receive XML messagecorresponding to individualmessage.

In this way, every MT message is processed as an individual message and processed further(mapper or whatever), allowing us to work with flat files with multiple messages. 

SwiftFlatFileDisassembler.rar (13.15 kb)

Tags:

Programming

Comments

4/5/2009 8:40:53 PM #

Viral

Hi,

Can I have code for CreateSwiftParsingErrorMessage(iBaseMessage);
function or some idea about how to get error information?

Thanks in advance

Viral

Viral India |

5/4/2009 12:19:50 AM #

Dejan

This feature exist under A4SWIFT MT pipeline already.
You don't need to create this add-on.

Dejan Serbia |

5/4/2009 12:27:30 AM #

Dejan

This feature exist under A4SWIFT MT pipeline already.
You don't need to create this add-on.

Dejan Serbia |

Comments are closed

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

RecentComments

Comment RSS

Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar