Arpalesa Blogs

Categorieën

Op datum

Uitgelicht

Custom pipeline

Custom pipeline

Het overkomt mij eigenlijk best vaak dat ik iets wil in BizTalk wat weer niet kan. Gelukkig is het mogelijk om dan "Custom pipelines" te maken. Dat is eigenlijk heel makkelijk. Er is een "Pipeline component wizard" plugin voor Visual Studio (https://btsplcw.codeplex.com/) die eigenlijk best goed werkt, maar niet heel vele meer doet dan onderstaande classe genereren. Ik heb hem voor mijzelf wat aangepast. Voeg de classe toe aan een gewone Visual Studio class library en doorloop alles waar CHANGE: staat. Pas dat aan zoals bij de omschrijving staat en build je project.

Lukt de build? Gefeliciteerd, je hebt een custom pipeline component gemaakt. Alleen, je moet hem dan nog wel even toevoegen aan een echte pipeline. Om dat te toen plaats je de gebuilde assembly (dll) eerst in de "Pipeline Components" subdirectory van de folder waar je BizTalk in hebt geinstalleerd (vaak c:\program files (x86)\Microsoft BizTalk).

Vervolgens voeg je een nieuw project toe, maar nu dan een BizTalk project. Voeg daar dan een send of receive pipeline aan toe, klik "choose items" op je toolbar en selecteer de custom pipeline die je net hebt gemaakt. Sleep die naar de juiste fase van de send of receive pipeline, pas eventueel de default properties aan, build de pipeline en voeg die toe als resource van de BizTalk applicatie waar je deze wil gebruiken.

Na het restarten van de host instances kan je de pipeline gebruiken. Zoals je ziet is deze blog best wel kort en beperkt, dat komt meer omdat hij eigenlijk alleen voor mijzelf is gebruikt en ik wel weet hoe het moet :-). Is dit te onduidelijk en heb je meer info nodig, laat het mij dan even weten en dan help ik je er wel doorheen.

Hieronder de template classe voor een nieuwe pipeline:

// CHANGE: Voeg aan het project een referentie toe naar Microsoft.BizTalk.Messaging.dll (in BizTalk installatie folder onder program files).
// CHANGE: Voeg aan het project een referentie toe naar Microsoft.BizTalk.Pipeline.dll (in BizTalk installatie folder onder program files).
// CHANGE: Voeg aan het project een referentie toe naar System.Drawing (alleen als we een icoontje willen meegeven in de taakbalk).
// CHANGE: Wijzig hier de namespace
namespace NameSpaceNaam
{
using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Resources;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Component;
using Microsoft.BizTalk.Messaging;
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
// CHANGE: Geef hier een unieke GUID. Gebruik dezelfde GUID in GetClassID.
[System.Runtime.InteropServices.Guid("12345678-1234-abcd-abcd-12344321abcd")]
// CHANGE: Hier kan je de plaats beperken waar het pipelinecomponent toegevoegd kan worden.
// Door dit op CATID_Any te laten staan kan het op elk stadium in een pipeline control.
[ComponentCategory(CategoryTypes.CATID_Any)]
// CHANGE: Pas hier de classe naam van de pipeline component aan.
public class PipelineNaam : Microsoft.BizTalk.Component.Interop.IComponent, IBaseComponent, IPersistPropertyBag, IComponentUI
{
#region IBaseComponent members
///


/// Naam van het pipeline component
///

[Browsable(false)]
public string Name
{
get
{
// CHANGE: Geef hier de naam retour die het component krijgt in de toolbox.
return "Pipeline naam";
}
}
///
/// Versie van het pipeline component
///

[Browsable(false)]
public string Version
{
get
{
// CHANGE: Geef hier de major.minor versie aan van het component.
return "1.0";
}
}
///
/// Korte omschrijving van het component
///

[Browsable(false)]
public string Description
{
get
{
// CHANGE: Geef hier een korte omschrijving van het component.
return "Omschrijving van het component.";
}
}
#endregion
#region Pipeline properties
// CHANGE: Voeg hier alle properties toe die je beschikbaar wil stellen aan
// het pipeline component. LET OP: Denk hier goed over na. Het is heel irritant om
// later nog weer properties toe te voegen, te verwijderen of namen / types te
// veranderen.
private string _VoorbeeldProperty = string.Empty;
public string VoorbeeldProperty
{
get
{
return _VoorbeeldProperty;
}
set
{
_VoorbeeldProperty = value;
}
}
#endregion
#region IPersistPropertyBag members
///
/// Gets class ID of component for usage from unmanaged code.
///

///
/// Class ID of the component
///
public void GetClassID(out System.Guid classid)
{
// CHANGE: Geef hier dezelfde GUID retour die boven de class declaratie is gebruikt.
classid = new System.Guid("12345678-1234-abcd-abcd-12344321abcd");
}
///
/// not implemented
///

public void InitNew()
{
}
///
/// Loads configuration properties for the component
///

/// Configuration property bag
/// Error status
public virtual void Load(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, int errlog)
{
object val = null;
// CHANGE: Herhaal dit voor alle properties die je hebt toegevoegd.
// Uit de propertybag zet / schrijf je altijd objects. Cast die objects
// dus naar het juiste type.
val = this.ReadPropertyBag(pb, "VoorbeeldProperty");
if ((val != null))
{
this._VoorbeeldProperty = ((string)(val));
}
}
///
/// Saves the current component configuration into the property bag
///

/// Configuration property bag
/// not used
/// not used
public virtual void Save(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, bool fClearDirty, bool fSaveAllProperties)
{
// CHANGE: Herhaal dit voor alle properties die je hebt toegevoegd.
this.WritePropertyBag(pb, "VoorbeeldProperty", this.VoorbeeldProperty);
}
#region utility functionality
///
/// Reads property value from property bag
///

/// Property bag
/// Name of property
/// Value of the property
private object ReadPropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName)
{
object val = null;
try
{
pb.Read(propName, out val, 0);
}
catch (System.ArgumentException)
{
return val;
}
catch (System.Exception e)
{
throw new System.ApplicationException(e.Message);
}
return val;
}
///
/// Writes property values into a property bag.
///

/// Property bag.
/// Name of property.
/// Value of property.
private void WritePropertyBag(Microsoft.BizTalk.Component.Interop.IPropertyBag pb, string propName, object val)
{
try
{
pb.Write(propName, ref val);
}
catch (System.Exception e)
{
throw new System.ApplicationException(e.Message);
}
}
#endregion
#endregion
#region IComponentUI members
///
/// Component icon to use in BizTalk Editor
///

[Browsable(false)]
public IntPtr Icon
{
get
{
// CHANGE: Dit is het icoontje in de toolbar. Het moet een 32x32 bitmap
// zijn. Momenteel maken we een afbeelding met in rood de tekst PC.
// Pas dat aan naar een andere toolbar icon indien gewenst.
Bitmap b = new Bitmap(32, 32);
Graphics g = Graphics.FromImage(b);
g.DrawString("PC", new Font("Verdana", 8, FontStyle.Bold), Brushes.Red, 0, 0);
g.Save();
return b.GetHicon();
}
}
///
/// The Validate method is called by the BizTalk Editor during the build
/// of a BizTalk project.
///

/// An Object containing the configuration properties.
/// The IEnumerator enables the caller to enumerate through a collection of strings containing error messages. These error messages appear as compiler error messages. To report successful property validation, the method should return an empty enumerator.
public System.Collections.IEnumerator Validate(object obj)
{
// example implementation:
// ArrayList errorList = new ArrayList();
// errorList.Add("This is a compiler error");
// return errorList.GetEnumerator();
return null;
}
#endregion
#region IComponent members
///
/// Implements IComponent.Execute method.
///

/// Pipeline context
/// Input message
/// Original input message
///
/// IComponent.Execute method is used to initiate
/// the processing of the message in this pipeline component.
///

public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
// CHANGE: Hier gebeurd het echte werk. De execute methode krijgt het bericht door.
// Je kan er mee doen wat je wil.
// Voorbeeld: Dit vraagt de bestandsnaam op:
string received = inmsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties").ToString();
// Zie hier https://blogs.msdn.microsoft.com/mattlind/2006/08/10/accessing-and-listing-message-context-properties-in-pipeline-components/
// voor alle andere bericht eigenschappen die je uit kan vragen / in kan stellen.
// Voorbeeld: Hiermee pas je de ReceivedFileName aan. Als een verder poort het bestand
// wegschrijft met %SourceFileName% dan zal die vanaf dat moment de aangepaste naam hanteren.
inmsg.Context.Write("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", "AangepasteNaam.txt");
// Voorbeeld: inmsg.BodyPart.Data is de daadwerkelijke inhoud van het bestand.
// Hier lezen we de hele data uit naar een string (fulldata).
string fullData = string.Empty;
if (inmsg.BodyPart != null)
{
using (StreamReader sr = new StreamReader(inmsg.BodyPart.Data))
{
fullData = sr.ReadToEnd();
}
}
// Voorbeeld: Hier passen we de berichtinhoud aan naar iets anders.
// We schrijven de aanpassingen via een streamwriter naar een memorystream.
// Spoelen die terug en zetten de bericht data op die memorystream.
// De memorystream voegen we toe aan de resourcetracker zodat die ook netjes
// opgeschoond raakt op het moment dat dit niet meer nodig is.
fullData = "Nieuwe of aangepaste bericht inhoud";
MemoryStream ms = new MemoryStream();
// Let op, zet deze niet in een using, dan is het straks een closed stream.
StreamWriter sw = new StreamWriter(ms);
sw.Write(fullData);
sw.Flush();
ms.Position = 0;
inmsg.BodyPart.Data = ms;
pc.ResourceTracker.AddResource(ms);
// Voorbeeld: aan het einde geef je dus weer de inmsg terug. Retourneer je
// NULL dan is dat net alsof dat er nooit een bericht is doorgekomen. Er
// wordt dan dus ook geen bericht naar de messagebox gezet en zal ook geen
// "no subscribers" bericht volgen. Als je alles wat er moet gebeuren in deze
// pipeline afwerkt is het aan te raden een property op te nemen "ReturnMessage"
// die bij false NULL terug geeft (zo kan men het altijd true zetten als ze
// via een send poort een backup willen maken etc).
// Installatie:
// Een custom pipeline component build je, dan voeg je hem toe aan de
// Pipeline Components folder onder de BizTalk applicatie folder.
// Sluit visual studio en start hem opnieuw. Op dat moment kan je
// in een BizTalk project een pipeline toevoegen en dit component vanuit
// de toolbar toevoegen en slepen naar de pipeline. Die pipeline build je
// ook, die voeg je in BizTalk toe als resource en dan moet het werken.
// Een custom pipeline zoals dit is dus nog niks, het moet altijd in een
// pipeline component van een BizTAlk project worden gezet.
return inmsg;
}
#endregion
}
}

 

Categories: BizTalk

Attachments

  1. example.txt 14-4-2017 22:56:42
You need to login in order to comment