Datenbanken und mehr

3. Juli 2007

Unzulänglicher FTP-Task im SSIS

Filed under: SSIS — Urs Gehrig @ 07:06

In einem meiner letzten Consulting Einsätze bin ich auf eine ganz besonders harte Nuss gestossen; dank den vielfältigen Tasks des SSIS habe ich dennoch einen valablen Workaround gefunden. Mit dem folgenden kleinen Beispiel möchte ich dir aufzeigen, wie vielfältig SSIS ist und dir gleichzeitig Mut machen nicht zu rasch den Pickel hinzuwerfen. Also los geht’s…

Die Aufgabe bestand im herunterladen eines Files von einem FTP-Server und der nachfolgenden Bearbeitung dieses Files – sofern überhaupt eines vorhanden ist. Leider ist der Filename unbekannt, da ein Verarbeitungsdatum die Extension des Filenamen bildet. Ein fehlen eines Files bedeutet keinen Fehler, ja ist sogar der Normalfall. Das ganze SSIS Package wird von einer Applikation via SMO angestossen. Die naheliegenste Lösung für das Packages beinhaltet wohl die Verwendung eines FTP Tasks. Im Kurzen würde dies in etwa wie folgt aussehen:

Das Propertie RemotePath des FTP-Tasks Download Ticket erhält den Wert myFile.* und das Propertie Operations den Wert Receive files. Der Foreach Loop Container ist ein Foreach File Enumerator. Auf den ersten Blick funktioniert dieser Ansatz gang ordentlich: das File wir heruntergeladen und vom Foreach File Enumerator im temporären Directory gefunden und verarbeitet. Das Problem kommt aber, wenn durch den FTP-Task kein File herunter geladen wird, weil keines vorhanden ist. In diesem Fall schlägt nämlich der FTP-Task fehl und das ganze Package wird mit einem Fehler abgebrochen – was ja in unserem Falle nicht passieren darf.

Erster Workaround: Das Propertie ForceExecutionResult des FTP-Tasks wird fix auf Success gesetzt. Damit wird der Control Flow des Packages auch weiter geführt, wenn kein File vom FTP Server kopiert wurde; also genau das was wir wollen. Pech gehabt: Der Foreach File Enumerator kommt zwar wie geplant zum Zuge und funktioniert auch einwandfrei (eine leere Collection bildet hier absolut kein Problem), das ganze Package hat nach der Verarbeitung aber dennoch einen DTSExecResult Wert von Failure.

Zweiter Workaround: In der Applikation, welche das Package startet, wird genau dieser eine Fehlerfall (kein File vom Server heruntergeladen) separat ausgewertet. Das kann in etwa wie folgt aussehen:

// start package
WSResult result = new WSResult(0, „“);

result.ResultCode = (Int32)myPackage.Execute();

// evaluate package result
// ignore FTP Task error in case any files are available!
if ((result.ResultCode == 0) || (myPackage.Errors.Count == 1 && myPackage.Errors[0].Source == „Download Ticket“ && myPackage.Errors[0].ErrorCode == -1073573501))
{
    // everything is OK!

    result.ResultCode == 0;
   

}
else
{
    // package failed
   

}

Fein, das funktioniert ganz gut; wenigstens in der Testumgebung wo der FTP-Server ein Microsoft Server ist (Bestandteil des IIS). Leider sah dies ganz anders aus, als ich diese Lösung in der realen Welt testete. Der Kunde hatte einen UNIX FTP Server und mit diesem kommt der FTP-Task nun ganz und gar nicht zu recht. Das File wird zwar runtergeladen (so sagt es jedenfalls der Task), aber das File ist nirgends zu finden. Ganz ähnlich verhält es sich beim Löschen des Files auf dem FTP Server; das File wird gelöscht (wiederum keine Fehlermeldung), aber das File ist weiterhin auf dem Server. Das kann doch nicht sein? Nochmals: Absolut keine Fehlermeldung vom FTP-Task, weder File nicht gefunden noch Keine Zugriffsberechtigung noch sonst was und trotzdem macht der Task nicht was er soll! Na ja, die Foren im Internet sind voll davon: So ziemlich jeder scheint dasselbe Problem mit dem FTP-Task und einem UNIX FTP Server zu haben L

Dritter Workaround: Wir wechseln den FTP Task durch einen Script Task aus und programmieren das runterladen halt selber in VB.net; schliesslich bietet uns das .NET Framework ja ein Webclient Objekt, welches als FTP Client genutzt werden kann. Soweit so gut; leider kann der Webclient nicht mit Wildcards in Fielnamen umgehen. War wohl wieder nichts.

Vierter Workaround: Wir wechseln den FTP Task durch einen Execute Process Task aus und rufen die Windows Konsolenapplikation FTP auf. Ja das war’s. Diese Lösung funktioniert. Egal ob ein File auf dem Server zum Download bereit liegt oder nicht. Egal ob der FTP Server ein UNIX oder Windows Server ist. Die Lösung funktioniert!

Du siehst also: Probleme gibt es immer und überall. SSIS bietet aber eine so grosse Vielfalt an Tasks, dass du immer einen Workaround für dein Problem finden kannst. Nur nie aufgeben!

Advertisements

2 Kommentare »

  1. Hallo,
    ich habe dieselbe Probleme mit dem ftp an Unix und zurück. Wie kann ich den Execute Task brauchen(ein Beispiel?). Konsolenapplikation FTP – soll da ein Batch geschrieben werden?
    Danke

    Kommentar von erwin — 19. Februar 2008 @ 18:03

  2. Hallo erwin,

    Nein, du brauchst kein Batchprogramm zu schreiben; stattdessen schreibst du einfach alle ftp Kommandos in ein Textfile (z.B. SCRIPT.TXT). Der Task sieht dann etwa wie folgt aus:
    ftp -s:SCRIPT.TXT

    Eine Liste aller unterstützten ftp Kommandos bekommst du via
    ftp help

    Einen guten Überblick über die Kommandos, den Aufbau des Textfiles und weitere ftp Tipps findest du auch unter http://www.ericphelps.com/batch/samples/ftp.script.txt.

    Hoffe das hilft, Gruss Urs

    Kommentar von Urs Gehrig — 19. Februar 2008 @ 21:32


RSS feed for comments on this post. TrackBack URI

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

Erstelle eine kostenlose Website oder Blog – auf WordPress.com.

%d Bloggern gefällt das: