BizTalk: Maps mit Referenzen zu externen Assemblies debuggen

by wolfgang@gehirnwindung.de (Wolfgang) Mai 05, 2010 14:25

Um BizTalk-Maps zu debuggen, die eine exterene Assembly aufrufen, reichen die Standard-Möglichkeiten nicht mehr aus. Es erscheint die Fehlermeldung

Cannot find the script or external object that implements prefix 'http://schemas.microsoft.com/BizTalk/2003/ScriptNS0'

Um das zu umgehen, müssen die externen Assemblies dem Debugger bekannt gemacht werden. Um allgemein XSLT zu debuggen kann, neben der Möglichkeit dies über das Menü "XML" -> "Debug XSLT" zu erledigen, auch das Objekt XslCompiledTransform verwendet werden. Hierdurch ist man wesentlich flexibler und kann z.B. StartParameter angeben und/oder eben Extension Objects". Und da eine BizTalk-Map letztendlich auch nur ein XSLT-Dokument darstellt, gilt das auch dafür.

Als erstes sollte man ein C#-Projekt zur BizTalk-Solution hinzufügen. Darin wird lediglich unten stehende Methode eingefügt und die "Main"-Methode so angepasst, dass ein Aufruf der Methode "DebugXslt" mit den jeweiligen Parametern erfolgt.

/// <summary>
/// Helper Method to debug Maps with Extension Objects
/// </summary>
/// <param name="mapXslt">Path to xslt-file generated by the MapperCompiler (Validate Map)</param>
/// <param name="inputXml">Path to input-file (Test Map)</param>
/// <param name="extensionObjectsXml">Path to Extension Object XML (Validate Map)</param>
static void DebugXslt( string mapXslt, string inputXml, string extensionObjectsXml ) {
    if( !string.IsNullOrEmpty( mapXslt ) && !string.IsNullOrEmpty( inputXml ) && File.Exists( mapXslt ) && File.Exists( inputXml ) ) {
        XslCompiledTransform xslt = new XslCompiledTransform( true );

        // allow embedded scripts and document()-function
        XsltSettings xsltSettings = new XsltSettings( true, true );

        // Load the style sheet.
        xslt.Load( mapXslt, xsltSettings, null );

        // resolve extension objects
        XsltArgumentList xsltArgs = new XsltArgumentList( );
        if( !string.IsNullOrEmpty(extensionObjectsXml) && File.Exists( extensionObjectsXml ) ) {
            XmlReaderSettings rsettings = new XmlReaderSettings( );
            rsettings.IgnoreComments = true;
            rsettings.IgnoreProcessingInstructions = true;
            rsettings.IgnoreWhitespace = true;

            using( XmlReader reader = XmlReader.Create( extensionObjectsXml, rsettings ) ) {
                reader.ReadStartElement( "ExtensionObjects" );

                do {
                    string ns = "", an = "", cn = "";
                    while( reader.MoveToNextAttribute( ) ) {
                        switch( reader.LocalName ) {
                            case "Namespace":
                                reader.ReadAttributeValue( );
                                ns = reader.Value;
                                break;
                            case "AssemblyName":
                                reader.ReadAttributeValue( );
                                an = reader.Value;
                                break;
                            case "ClassName":
                                reader.ReadAttributeValue( );
                                cn = reader.Value;
                                break;
                        }
                    }

                    // load type and add instance to xslt-Arguments
                    if( !string.IsNullOrEmpty( ns ) && !string.IsNullOrEmpty( an ) && !string.IsNullOrEmpty( cn ) ) {
                        Type t = Type.GetType( Assembly.CreateQualifiedName( an, cn ) );
                        xsltArgs.AddExtensionObject( ns, System.Activator.CreateInstance( t, false ) );
                    }
                } while( reader.ReadToNextSibling( "ExtensionObject" ) );

                reader.Close( );
            }
        }

        // Execute the transformation.
        using( XmlWriter writer = XmlWriter.Create( TextWriter.Null ) ) {
            xslt.Transform( inputXml, xsltArgs, writer );
            writer.Close( );
        }

        xsltArgs.Clear( );
    }
}

Parameter Beschreibung
mapXslt Pfad zur XSLT-Datei
inputXml Pfad zur der Datei, die die Testdaten enthält
extensionObjectsXml

Pfad zur Datei, in der die Erweiterungsobjekte stehen (darf leer sein)

Nun müssen noch die einzelnen Pfade ermittelt werden. Mittels "Validate Map" (rot im Bild) werden die XSLT-Datei und die extensionObjects-Datei erstellt. Im Output-Window erscheinen die jeweiligen Pfade und müssen nur noch übernommen werden.
Hat man kein XML-Dokument, mit dem man Testen kann, sondern ein natives Format, so hilft "Test Map". Auch hier erscheint im Output-Window der Pfad mit dem Hinweis "Test Map used the following file".

 

Sind nun alle 3 Pfade ermittelt und eingetragen, kann es auch endlich losgehen. Damit der Debugger nicht einfach durchläuft, sollte die XSLT-Datei geöffnet und eine Haltepunkt eingefügt werden.

 

Nun muss das Projekt gestartet werden. Dazu mit der rechten Maustaste auf das Projekt zeigen und "Debug" -> "Start new instance" ausführen.
Alternativ das Projekt als StartUp-Project einrichten und F5 drücken...

Tags: , ,

Microsoft BizTalk Server

BizTalk: Zugriff auf UNB-Segment und AS2-Eigenschaften innerhalb Orchestration

by wolfgang@gehirnwindung.de (Wolfgang) Februar 15, 2010 21:30

In einer Orchestration bekommt man es normalerweise nur noch mit den eigentlichen Daten einer Nachricht zu tun. So sind bei EDIFACT-Nachrichten z.B. die UNA- und UNB-Segmente nicht Teil des Schemas. Weiterhin fehlen auch die AS2-Header und eben alles, was nicht unbedingt benötigt wird. Das hat seine Vorteile (ist aufgeräumt), manchmal wird aber auch der Zugriff auf diese Daten benötigt.

Läuft eine Nachricht mal auf einen Fehler, so kann man in den "Message Details" erkennen, dass verschiedene "Context-Properties" aus eben diesen sonst nicht sichtbaren Segmenten (oder aus dem Protokoll) zu den einzelnen Nachrichten zugewiesen sind.

Auf diese Kontexteigenschaften kann man mittels Message(ContextProperty) innerhalb einer BizTalk Server Expression Shape in Orchestration Expression Shape zugreifen. Im Falle von EDIFACT-Eigenschaften muss aber - damit man die Auswahl der Context Properties überhaupt zu sehen bekommt - noch eine Referenz auf die DLL Microsoft.BizTalk.Edi.BaseArtifacts (oft zu finden unter C:\Program Files\Microsoft BizTalk Server 2006\Microsoft.BizTalk.Edi.BaseArtifacts.dll) zum Projekt hinzugefügt werden.

Mit dieser Referenz sind dann Kontexteigenschaften in den Namespaces EDI (für EDIFACT und X12 - Eigenschaften) und EdiIntAs (für AS2 - Eigenschaften) vorhanden.

Tags: , , ,

Microsoft BizTalk Server

BizTalk: Checkliste für das Senden von AS2-Nachrichten

by wolfgang@gehirnwindung.de (Wolfgang) Januar 20, 2010 21:29

Nach der Checkliste für das Empfangen von Nachrichten über AS2, muss quasi ja auch eine Checkliste für das Senden bereitgestellt werden ;) Diese Liste ist wesentlich kürzer, wenn es auch mehr Möglichkeiten gibt, als hier dargestellt...

  1. Send Port
    - für asynchrone MDN: One-way
    - für synchrone MDN: Solicit-Response
    • Type: HTTP
      • Destionation URL: Die URL, die beim Partner eingerichtet wird (auf beiden Seiten sollte die URL exakt gleich angegeben werden - inkl. Groß-/Kleinschreibung)
      • Enabled chunked encoding deaktivieren
    • Send pipeline
      • AS2Send (für alle möglichen Daten),
      • AS2EDISend (für EDI-Daten) oder
      • eine eigene Send Pipeline, in der die AS2 Encoder-Component verwendet wird
  2. Sender Party
    • General
      • Send Ports (den oben erstellen Port auswählen, alternativ geht die Zuweisung auch über einen Role Link oder wie unten beschrieben über den Alias-Namen)
    • AS2 Properties -> Party as AS2 Message Receiver (nicht verwirren lassen)
      • Einstellungen ab "Outbound AS2 Message" entsprechend der Vereinbarung mit dem Partner einstellen
      • AS2-From und AS2-To erscheinen wie hier angegeben im Head-Bereich der Nachricht und damit beim Partner
  3. Asynchrone MDNs müssen - wie eine beliebig andere AS2-Nachricht - empfangen werden können. An welche Adresse die MDN geschickt wird, kann in den Party-Einstellungen angegeben (Receipt-Delivery-Option) werden. Um die Verarbeitung dieser Nachrichten kümmert sich allerdings der BizTalk-Server selbst.

Die Party Resolution für ausgehende Nachrichten (also das Finden der Party, die die Nachricht empfängt und bei der die entsprechenden Einstellungen vorgenommen wurden) kann auch anders erfolgen. Das zuweisen des Send-Ports zu einer Party wird aber (meiner Erfahrung nach) sehr häufig verwendet. Es sollte allerdings auch ausreichen, einer Party einen EDIINT-AS2-To - Alias und der ausgehenden Nachricht den AS2-To - Header zuzuweisen - getestet hab ich das noch nicht.

Für die Signierung und Verschlüsselung der Nachricht und der Signierung der MDN müssen zusätzlich Zertifikate installiert und an bestimmten Stellen ausgewählt werden, die in dieser kleinen Übersicht beschrieben werden.

Tags: ,

Microsoft BizTalk Server

BizTalk: Checkliste für Empfang von AS2-Nachrichten

by wolfgang@gehirnwindung.de (Wolfgang) Januar 15, 2010 00:06

Um über BizTalk-HTTP-Adapter AS2 Daten empfangen zu können, müssen gleich ein paar Einstellungen passen. Ein kleiner Überblick über die wichtigsten Einstellungen soll hiermit geschaffen werden:

  1. Virtuelles Verzeichnis für den Empfang der Nachrichten über HTTP
    • Local Path: Verzeichnis, in dem die Datei BTSHttpReceive.dll liegt, z.B. C:\Program Files\Microsoft BizTalk Server 2006\HttpReceive\ bzw. C:\Program Files\Microsoft BizTalk Server 20009\HttpReceive\
    • Execute permissions: Scripts and Executables
    • Identität des zugewiesenen Application Pools muss ein Benutzer sein, der Zugriff auf die BizTalk-Datenbank hat, in der Regel wird hier BTSIsolatedHostUser verwendet
    • In welcher Web Site das virtuelle Verzeichnis liegt (es kann natürlich auch die Web Site direkt verwendet werden) ist dabei egal. Allerdings sollte man bei mehreren Web Sites darauf achten, dass der virtuelle Pfad über alle Web Sites hinweg eindeutig ist, da man innerhalb der Receive Location die betroffene Web Site nicht mit angeben kann.
  2. Receive Port anlegen
    • Keine oder asynchrone MDN: One-Way
    • MDN synchron: Request-Response
  3. Receive Location anlegen
    • Type: HTTP-Adapter
      • Virtual directory plus ISAPI extension: z.B. /virtualDirectory/BTSHttpReceive.dll.
        Wie oben erwähnt, können die Web Sites des IIS hier nicht angegeben werden. Nur der virtuelle Pfad (ausgehend vom root-Verzeichnis)
      • Es kann ein beliebiger QueryString an die DLL angehängt werden. Damit können - mit nur einem virtuellen Verzeichnis - für verschiedene Kunden und/oder Dokument verschiedene Receie Locations definiert werden (an sich braucht man damit nur ein virtuelles Verzeichnis im IIS einrichten).
        Dieser Querystring muss exakt genauso auch im sendenden Programm angegeben werden (mit exakt ist Reihenfolge, Groß-Kleinschreibung und Umfang gemeint...).
      • Die Einstellung Suspend failed requests aktivieren
    • Receive Pipeline
      • AS2Receive: Wenn beliebige Daten per AS2 empfangen werden sollen
      • AS2EdiReceive: Wenn EDIFACT-Nachrichten per AS2 empfangen werden sollen
      • oder eine selbst-erstellte Pipeline, die die AS2 decoder-Component verwendet
  4. Sender-Party
    • Party Properties
      • Damit der Firmeneintrag beim Empfang der Datei gefunden werden kann, muss als EDIINT-AS2 From Value (AS2-From) der, zwischen den Partnern ausgemachte Name angegeben werden. Der Name sollte nur aus ASCII-Zeichen bestehen
    • AS2 Properties, Party as AS2 Message Sender
      • Hier kann man eigentlich alles auf Standard lassen (keine Checkbox aktiv). Damit gibt der Sender vor, wie die Datei zu behandeln ist.
      • Man kann den Sender auch zu bestimmten Einstellungen zwingen. Dazu die Checkbox Override inbound message properties aktivieren und die Einstellungen in der Gruppe Incoming AS2 message anpassen
      • Wenn die MDN signiert werden soll, dann kann das erreicht werden, indem die Checkbox Sign requested MDN if Disposition-Notification-Option header is not present or if Signed-Receipt-Protocol header is set to optional aktiviert werden. Der Sender darf das allerdings nicht ausschließen...
  5. Empfänger-Party (aktueller Rechner)
    Beim Empfänger in diesem Fall nicht viel Einstellbar. Hier geht es primär um die MDN, die versendet wird
    • Party Properties
      • Damit die Einstellungen der Firma verwendet werden können, muss als EDIINT-AS2 To Value (AS2-To)-Wert der zwischen den Partnern ausgemachte Name für den Empfänger angegeben werden
  6. Send Port oder Orchestration zum Verarbeiten der ankommenden Daten
    • Damit keine Fehlermeldung angezeigt wird, muss die Datei auch verabeitet werden - und das kann man nur erreichen, indem man entweder
      • den oben erstellen Receive Port einer Orchestration zuweist (Bindings -> Inbound Logical Port), oder
      • einen Send Port erstellt und den Filter so anpasst, dass die ankommenden Nachrichten über diesen Port verarbeitet werden (z.B. über die Eigenshaft BTS.ReceivePortName)

Zugegeben, wirklich kurz ist die Liste nicht ;) Dennoch sind nur die notwendigsten Einstellungen beschrieben.

Falls die Nachrichten und MDNs signiert und/oder verschlüsselt werden sollen, hab ich im Artikel BizTalk: Wohin mit den AS2-Zertifikaten entsprechende Einstellungen beschrieben.

Update: Punkt 6 hat zwar an sich nichts mehr mit dem Empfang der Daten zu tun, kam aber dennoch dazu, da der Punkt offenbar oft vergessen / übersehen wird (hat man mir berichtet).

Tags: ,

Microsoft BizTalk Server

BizTalk: Wohin mit den AS2-Zertifikaten (Signieren und Verschlüsseln)

by wolfgang@gehirnwindung.de (Wolfgang) Januar 14, 2010 00:27

Will man Nachrichten mittels AS2 verschlüsselt oder signiert versenden oder eine verschlüsselte oder signierte Nachricht empfangen, so muss man sich zwangsläufig mit Zertifikaten auseinandersetzen und diese an bestimmte Stellen (Zertifikatsspeicher) ablegen und an ebenso genau definierten Stellen in der BizTalk Administration Console auswählen.

Am Einfachsten macht man sich die Arbeit, wenn man das SDK-Tool "Certificate Wizard" (unter C:\Program Files\Microsoft BizTalk Server 2006\SDK\Utilities\Certificate Wizard\CertWizard.exe bzw. im Verzeichnis BizTalk Server 2009 zu finden) verwendet. Dieses Tool kopiert je nach Einstellung die Zertifikatsdateien in die entsprechenden Zertifikatsspeicher. Wer es manuell machen oder einfach nur überprüfen will, der kann sich an folgender Liste orientieren.

Das Auswählen des Zertifikats innerhalb der BizTalk Server Administration Console muss zudem auch noch an entsprechenden Stellen erfolgen. Auch hier hilft die Liste weiter.

Nachrichten

  Signierung Ver-/Entschlüsselung
Eingehend Speicher:
Typ:
BizTalk:
Other People (Local computer)
Public key (Partner)
Party (Partner) / Certificates
Speicher:
Typ:
BizTalk:
Personal store (Isolated host User)
Private key (Home)
Isolated Host / Certificates
Ausgehend Speicher:
Typ:
BizTalk:
Personal store (InProc user)
Private key (Home)
Group / Certificates
Speicher:
Typ:
BizTalk:
Other People (Local computer)
Public key (Partner)
Send Port / Certificates

MDN

  Signierung
Eingehend Speicher:
Typ:
BizTalk:
Other People (Local computer)
Public key (Partner)
Party (Partner) / Certificates
Ausgehend
synchron
Speicher:
Typ:
BizTalk:
Personal store (Isolated host user)
Private key (Home)
Group / Certificates
Ausgehend
asynchron
Speicher:
Typ:
BizTalk:
Personal store (InProc user)
Private key (Home)
Group / Certificates

Zertifikatsspeicher

Die Zertifikatsspeicher sind nicht ganz einfach zu finden. Man kann aber wie folgt vorgehen. Bestenfalls legt man sich eine eigene Administrationskonsole an.

  • mmc.exe starten
  • Menü "File" -> "Add/Remove Snap-In..."
  • Button "Add..."
  • "Certificates" auswählen und mit "Add" bestätigen
  • "Computer Account" auswählen
  • weiter bis Finish
  • "Certificates" auswählen und mit "Add" bestätigen
  • "My User Account" auswählen

Leider kann man keinen speziellen Benutzer auswählen. Die Datei kann aber als *.msc-Datei gespeichert werden und danach mit der rechten Maustaste mittels "Run as..." mit einem anderen Benutzer gestartet werden. Hier kann dann der BTSHostUser und der BTSIsolatedHostUser eingetragen werden. Nicht schön, aber hilfreich ;)

Tags: ,

Microsoft BizTalk Server

BizTalk: unexpected token ';'

by wolfgang@gehirnwindung.de (Wolfgang) November 30, 2009 22:03

Ein Kunde kam heute mit einer Orchestration zu mir, die folgende Fehlermeldung beim kompilieren erzeugte:

Error X2016: unexpected token ';'

Wie so oft führt auch hier eine eigentlich extrem kleine Ursache zu dieser Auswirkung. Die Fehlermeldung sagt leider nicht viel aus. Nach kurzer Suche im .odx-Quelltext findet man dann aber zum Glück schnell ein Konstrukt wie

variableName =  ;

Das sieht nicht nur seltsam aus, sondern ist natürlich auch falsch... Grund war in diesem Fall ein einzelnes Leerzeichen als "Initial Value" der System.String-Variable. Das ist fast schon "fies", da man den Fehler nicht einmal auf den ersten Blick auf die Eigenschaften der Variable erkennen kann (wie im Screenshot zu sehen).

BizTalk Server Orchestration-Fehlermeldung unexpected token

Für string-Variablen muss jeder Initialwert also stets in doppelten Anführungsstrichen stehen.

Tags: ,

Microsoft BizTalk Server

BizTalk Server Scripting-Functoid wider Erwarten...

by wolfgang@gehirnwindung.de (Wolfgang) September 23, 2009 20:00

Mit dem Scripting Functoid des BizTalk-Mappers kann man bekanntlich eigene Scripts in verschiedenen Sprachen (z.b. C#) während des Mappings ausführen lassen. Man definiert damit eine Funktion deren Parameter mit Hilfer der Eingangselemente gefüllt werden können. Der Rückgabewert der Funktion ist das, was das Functoid als Ausgangsparameter weitergibt. Bis hierhin ist alles noch selbsterklärend.

Falls nun mehrere Scripting Functoide existieren, die alle das Gleiche tun, so ist man gut beraten, auch immer den gleichen Methodennamen zu verwenden. Diese werden beim Kompilieren in XSLT zusammengeführt (aus dem *.btm-Dateien wird immer xslt generiert). Innerhalb dieser XSLT-Datei, wird dann auch immer nur eine Funktion aufgerufen.

Allerdings scheint den Entwicklern ein kleiner Fehler unterlaufen zu sein. Denn nicht der Methodenname und der dazugehörige Inhalt (MethodBody), sondern lediglich der Methodenname und die Anzahl der Parameter wird verwendet, um die "Gleichheit" zweier Funktionen festzustellen.

vollständigen Artikel anzeigen...

Tags: ,

Microsoft BizTalk Server

BizTalk Eloquent: You must specify at least one already-initialized correlation set...

by wolfgang@gehirnwindung.de (Wolfgang) August 08, 2009 10:24

Die Lösung ist unglaublich einfach - die Frage danach klingt aber alles andere als das *g*. Folgende Fehlermeldung kann beim kompilieren eines BizTalk-Projekts erscheinen.

Error 3: you must specify at least one already-initialized correlation set for a non-activation receive that is on a non-selfcorrelating port.

Die Macher dieser wortgewaltigen Fehlermeldung haben durchaus recht. Damit eine Nicht-aktivierende Receive-Shape (wie übersetzte man das *g*?) auf einem nicht-Selbst-Korrelierenden Port (Anschluss) funktioniert, muss mindestens ein initialisierter Korrelationssatz vorgegeben werden... Das klingt kompliziert - und das ist es auch.

Die andere Seite hätte man - meiner Meinung nach - aber auch dazuschreiben können. Will man keine Korrelationssätze definieren oder braucht man diese erst gar nicht, reicht es auch aus, von einem Nicht-aktivierenden auf einen aktivierenden Port umzustellen. D.h. dass man die Eigenschaft "Activate" des ersten Receive Ports auf "True" stellen muss. Dies dürfte in vielen Fällen auch das gewünschte Verhalten sein...

 Einstellung Activate einer Receive-Shape in Biztalk-Orchestation

Was das ist? Ein aktivierender Receive Port initialisiert die Orchestration, sobald eine Nachricht diesem Anschluss zugeordnet wird. D.h. die Orchestration wird nach dem Empfang auf diesem Port ausgeführt. Daher darf es nur einen solchen Receive Port geben (Ausnahmen gibt's mittels Listen- und Parallel-Shape auch hier) und dieser aktivierende Receive Port muss ganz am Anfang stehen (sonst würde man die Orchestration ja zu einem Zeitpunkt aktivieren wollen, zu dem sie bereits läuft).

Tags: ,

Microsoft BizTalk Server

Fehler 404 beim Aufruf von BTSHTTPReceive.dll

by wolfgang@gehirnwindung.de (Wolfgang) Mai 20, 2009 18:58

Heute stieß ich auf einen mir seltsam erscheinenden Fehler. Ich hatte AS2-Daten von einem Partner bekommen und habe diese eingerichtet. Beim ersten Test kam es dann gleich zum Fehler 404 "File not found" bzw. "Datei nicht gefunden". Das wollte ich prüfen und nachdem ich die URL in den Browser eingegeben hatte, erschien auch die selbe Fehlermeldung. Beim Aufruf des Verzeichnisses wurde die Datei allerdings noch - wie im Bild zu sehen - angezeigt.

Die Datei ist also vorhanden. Verwirrend.

Die Lösung ist ganz einfach, wenn man sie denn kennt ;) Innerhalb der Web Service Extensions im IIS Manager muss diese DLL eingetragen und die Ausführung erlaubt werden.

Tags: ,

Microsoft BizTalk Server

BizTalk 2009: Ein Feature das keines ist

by wolfgang@gehirnwindung.de (Wolfgang) April 29, 2009 18:31

Das neue Projektformat der BizTalk-Projekte lässt einiges erhoffen. Neben MSBuild-Deploys z.B. auch, dass unterschiedliche Elemente wie z.B. C#-Dateien mit eingefügt werden können. Und tatsächlich ist sogar schon eine *.cs-Datei in neuen BizTalk-Projekten enthalten: AssemblyInfo.cs.

Und diese ist nicht nur proforma vorhanden, sondern wird tatsächlich auch vom C#-Compiler kompiliert.

vollständigen Artikel anzeigen...

Tags:

Microsoft BizTalk Server

Powered by BlogEngine.NET 1.6.1.6
Theme by Mads Kristensen | Modified by Mooglegiant and me ;)