EnvironmentCheckByFilter
Gruppe |
|
Funktion |
Diese Klasse zur Umgebungsprüfung ruft eine Funktion auf, deren Ergebnis als Datentyp Boolean interpretiert wird und für die Entscheidung verwendet wird, ob der Job gestartet oder suspendiert werden soll. |
Konfigurationsdatei |
Ja. Siehe unten. |
Beschreibung
Diese Klasse zur Umgebungsprüfung ruft eine Funktion auf, deren Ergebnis als Datentypen Boolean interpretiert wird und für die Entscheidung verwendet wird, ob der Job gestartet oder suspendiert werden soll.
Mit einer Properties-Konfigurationsdatei wird festgelegt, welche Funktion für die Entscheidung aufgerufen wird, ob der Job gestartet oder suspendiert wird, welche Parameter er beim Start erhält, sowie ob eine Exception im Funktionsaufruf unterdrückt werden soll.
Die Wartezeit in Sekunden bis zur erneuten Ausführung der Umgebungsprüfung kann entweder als Ganzzahl vorgegeben werden, oder durch den Aufruf eine weitere Funktion (Wait-Funktion) zur Laufzeit ermittelt werden. Wenn für die Wartezeit der Wert 2147483647 (Integer.MAX_VALUE) gesetzt wird, wird der Job nicht suspendiert, sondern gelöscht. In diesem Fall wird auch die Backupdatei gelöscht.
Wird für die Entscheidung ein Makro aufgerufen, dass die Funktion abort execution(a, b) verwendet (oder wenn die Funktion direkt aufgerufen wird) und die Funktion führt einen Abbruch durch, dann wird der Profil-Job nicht gestartet oder suspendiert, sondern abgebrochen (aber ohne Fehler).
Konfiguration
Property |
Bedeutung |
Default |
Bemerkung |
|
|
|
Die folgenden Properties sind für die Entscheidungs-Funktion. |
filter.class |
Name der Funktionsklasse. |
Kein Defaultwert. |
Vollständiger Klassenname oder einfacher Klassename. Wenn keine Klasse angegeben wird, wird die Funktions-ID verwendet. |
filter.id |
Registrierte Funktions-ID. |
226 |
Funktions-ID einer in ./etc/admin/datawizard/filter.properties oder custom_filter.properties registrierten Funktion. Das Property wird nur ausgewertet, wenn kein Klassenname angegeben ist. Wenn weder Klassenname noch Funktions-ID angegeben ist, wird die Funktion logical-condition(cnd a, val b [, c, ...]) verwendet, die die ID 226 hat. |
filter.param.a |
Parameter a. |
Kein Defaultwert. |
Wert, der als Parameter a an die Funktion übergeben wird. Es hängt von der konkreten Funktion ab, ob er diesen Parameter erwartet. Hinweis: Sie können für Werte der Funktions(Filter-)Parameter Variablen (Syntax @MSG_CALL_MYVAR@) und System-Konstanten (Syntax %MYCONST%) verwenden. |
filter.param.b |
Parameter b. |
Kein Defaultwert. |
Wert, der als Parameter b an die Funktion übergeben wird. Es hängt von der konkreten Funktion ab, ob er diesen Parameter erwartet. |
filter.param.N |
Parameter N. |
Kein Defaultwert. |
Wert, der als Parameter N an die Funktion übergeben wird, mit N = {c-z}. Es hängt von der konkreten Funktion ab, ob er diesen Parameter erwartet. |
|
|
|
Die folgenden Properties sind für die Warte-Funktion. |
wait.time |
Wartezeit in Sekunden bis zum Restart. |
30 |
Werte kleiner als 1 werden ignoriert. Dann gilt der Default=30. Dieser Wert kann durch die Wait-Funktion zur Laufzeit nur vergrößert werden. |
wait.filter.class |
Name der Wait-Funktionsklasse. |
Kein Defaultwert. |
Klassenname der Funktion, die zur Berechnung der Wartezeit verwendet wird. Hat Vorrang vor wait.filter.id. |
wait.filter.id |
ID der Wait-Funktionsklasse. |
Kein Defaultwert. |
Registrierte ID der Funktion, die zur Berechnung der Wartezeit verwendet wird. Wird ignoriert, wenn wait.filter.class existiert. Falls weder ID noch Klasse der Wait-Funktion angegeben werden, aber wait.filter.param.a existiert, wird die Funktion logical-condition(cnd a, val b [, c, ...]) verwendet, die die ID 226 hat. |
wait.filter.param.a |
Parameter a für Wait-Funktion. |
Kein Defaultwert. |
Wert, der als Parameter a an die Wait-Funktion übergeben wird. Es hängt von der konkreten Funktion ab, ob er diesen Parameter erwartet. |
wait.filter.param.b |
Parameter b für Wait-Funktion. |
Kein Defaultwert. |
Wert, der als Parameter b an die Wait-Funktion übergeben wird. Es hängt von der konkreten Funktion ab, ob er diesen Parameter erwartet. |
wait.filter.param.N |
Parameter N für Wait-Funktion |
Kein Defaultwert. |
Wert, der als Parameter N an die Wait-Funktion übergeben wird, mit N = {c-z}. Es hängt von der konkreten Funktion ab, ob er diesen Parameter erwartet. |
|
|
|
Die folgenden Properties sind für die Exception-Behandlung (gilt für beide Funktionen). |
filter.exception |
Exceptions unterdrücken. |
Kein Defaultwert. |
Wenn dieses Property den Wert ignore hat, werden Exceptions in beiden Funktionen unterdrückt und nicht an den Job weitergegeben. Exceptions in der Entscheidungs-Funktion werden als false interpretiert. Der Job wird dann suspendiert. Exceptions in der Wait-Funktion führen dazu, dass die mit wait.time definierte Wartezeit gilt. |
|
|
|
Die folgenden Properties sind für das Verhalten bei Neudurchlauf. |
restart.execute |
Auch bei Neudurchlauf. |
false |
Bei Wert true wird die Umgebungsprüfung auch gestartet, wenn der Job mit Neustart erneut ausgeführt wird. Default: Bei Neustart keine Umgebungsprüfung ausführen. |
Anwendungsbeschreibung
Job starten oder suspendieren?
Die Entscheidungsfunktion wird mit filter.class oder filter.id, sowie den Parameterwerten filter.param.N definiert. Für N können die Kleinbuchstaben a bis z verwendet werden. Es werden nur die Parameter übergeben, die die Funktion auch erwartet.
Vorzugsweise wird die Funktion logical-condition(cnd a, val b [, c, ...]) verwendet, wenn weder filter.class noch filter.id definiert sind. Diese Funktion kann auch ein Funktions-Makro aufrufen, wenn der Name des Makros in Parameter a übergeben wird. Durch vorangestelltes not vor dem Namen kann die Logik des Makros negiert werden. Durch die Verwendung eines Makros sind auch komplexere Funktionsketten möglich.
Der Rückgabewert der Funktion bzw. Makros entscheidet, ob der Job ausgeführt oder suspendiert wird. Wert true führt den Job aus, false suspendiert ihn. Wenn der Wert nicht den Datentypen Boolean hat, wird er durch implizite Typumwandlung gewandelt. Für die implizite Typumwandlung zu Boolean gelten folgende Regeln.
String |
Das Wort true in beliebiger Schreibweise mit Groß- und Kleinbuchstaben liefert den Boolean-Wert true. Alles andere ist false. |
Integer, BigInteger, Float, Double, BigDecimal |
Alle Werte größer 0 sind true. Negative Werte und 0 sind false. |
Date, Timestamp |
Jeder gültige Zeitpunkt nach 1970-01-01 liefert true. Leere Werte (no value) sind false. |
Wartezeit bis zur erneuten Umgebungsprüfung
Wenn der Job suspendiert wurde, wird nach einer Wartezeit eine erneute Umgebungsprüfung ausgeführt. Vor deren Ergebnis hängt es ab, ob der Job gestartet oder weiter suspendiert wird.
Konfigurierte Wartezeit
Die Wartezeit in Sekunden wird mit dem Property wait.time festgelegt. Wenn dieses Property fehlt, wird der Default 30 Sekunden angenommen. Werte unter einer Sekunde werden ignoriert. In diesem Fall gilt der Default 30.
Berechnung der Wartezeit zur Laufzeit
Zur Laufzeit kann die Wartezeit mit einer weiteren Funktion, der Wait-Funktion, neu berechnet werden. Die berechnete Wartezeit wird nur dann wirksam, wenn sie größer ist, als die konfigurierte Wartezeit.
Das Ziel der berechneten Wartezeit ist es, unnötige Läufe der Umgebungsprüfung zu vermeiden, wenn erkennbar ist, dass es auch dann wieder zur Suspendierung führen wird. Deshalb ist nur eine weitere Verlängerung der konfigurierten Wartezeit möglich, keine Verkürzung.
Die Wait-Funktion wird, analog zur Entscheidungsfunktion, mit wait.filter.class oder wait.filter.id, sowie den Parameterwerten wait.filter.param.N definiert. Für N können die Kleinbuchstaben a bis z verwendet werden. Es werden nur die Parameter übergeben, die die Wait-Funktion auch erwartet.
Wenn weder wait.filter.class, noch wait.filter.id existiert noch wait.filter.param.a, wird keine Berechnung der Wartezeit ausgeführt, also keine Wait-Funktion gestartet.
Wenn wait.filter.param.a existiert, aber weder Funktionsklasse noch ID definiert ist, wird auch hier die Funktion logical-condition(cnd a, val b [, c, ...]) verwendet. Üblicherweise wird auch hier ein Makro aufgerufen, dessen Ergebnis aber ein numerischer Wert ist, die Anzahl der Sekunden für die berechnete Wartezeit.
Verhalten bei Exceptions im Funktionsaufruf
Das Ziel der Umgebungsprüfung ist es u.a. die Verfügbarkeit eines externen Systems zu prüfen. Dabei ist es möglich, dass diese Prüfung mit einer Exception endet, eben weil das System nicht verfügbar ist. Wenn diese Exception nicht abgefangen und ignoriert wird, wird sie an das Profil weitergegeben und jedes Mal ein Eintrag in der Fehlerliste des Control Centers erzeugt.
Mit dem Property filter.exception=ignore kann man diese Exceptions abfangen. Das führt zu folgendem Verhalten bei einer Exception.
Für die Entscheidungsfunktion wird bei Exception das Ergebnis false angenommen, der Job wird daher suspendiert.
Bei Exception in der Wait-Funktion scheitert die Berechnung der Wartezeit. Es wird mit der konfigurierten Wartezeit gearbeitet.
Verhalten bei manuellem Neudurchlauf
Wenn ein bereits gelaufener Job mit dem Neudurchlauf-Dialog erneut gestartet wird, muss entschieden werden, ob dafür die Umgebungsprüfung mit der Klasse EnvironmentCheckByFilter ausgeführt werden soll. Default ist: Keine Umgebungsprüfung bei Neudurchlauf.
Mit dem Property restart.execute=true kann man erreichen, dass auch bei einem Neudurchlauf die Umgebungsprüfung ausgeführt wird.
Auflösung von Variablen und Systemkonstanten
Die Umgebungsprüfung wird vor der Phase 2 ausgeführt, also bevor die eigentliche Job-Umgebung existiert. Deshalb stehen nur die auch aus Phase 1 bekannten Systemvariablen und die Variablen MSG_CALL_ zur Verfügung, wenn sie im Profil definiert sind. Damit kann bei Aufruf des Profils per Message oder bei Triggerung durch HTTP oder durch ein Profil eine Parametrisierung der Umgebungsprüfung erfolgen.
Variablen, die im Profil definiert sind und bei Aufruf einen Wert 'von außen' erhalten, können in der Konfigurationsdatei als Wert eines Properties mit der Syntax @Variablenname@ verwendet werden. Systemkonstanten können mit der Syntax %Konstantenname% als Property-Wert in der Konfigurationsdatei verwendet werden.
Achtung: Da bei erneuter Ausführung der Umgebungsprüfung nach der Wartezeit mit dem originalen Variablensatz gearbeitet wird, ändern sich die Werte bei erneuter Umgebungsprüfung nach der Suspendierung üblicherweise nicht.
Da die System-Variable VAR_FILENAME nicht zur Verfügung steht, gibt es eine Pseudo-Variable @<file>@, die den Namen der Quelldatei enthält.
Einschränkungen
Zum Zeitpunkt der Umgebungsprüfung existiert die Job-Umgebung noch nicht. Deshalb wird eine rudimentäre Ersatz-Umgebung erzeugt.
In dieser Umgebeung stehen zwar Maps und Listen, sowie Value-Splitter zur Verfügung und können innerhalb der Umgebungsprüfung verwendet werden, aber eine Übergabe der erzeugten Listen-/Map-/Splitter-Objekte an die eigentliche Job-Umgebung erfolgt nicht.
In der rudimentären Umgebung können eventuell einzelne Funktionen nicht funktionieren. Eine vollständige Prüfung aller Funktionen in allen Kombinationen wurde nicht durchgeführt.
Anwendungsbeispiele
Szenario 1
Ein Profil empfängt Daten per Email und erzeugt eine Zieldatei mit fixem Dateinamen ./temp/output/Env2Check.txt, die von einem anderen System/Prozess abgeholt und dabei gelöscht wird. Es besteht die Gefahr eines Datenverlustes, wenn die Datei durch einen späteren Job überschrieben wird, bevor sie vom Zielsystem abgeholt wurde.
Als erste Maßnahme wird das Profil auf Single-Run (Darf nur in einer Instanz laufen) eingestellt. Trotzdem kommt es gelegentlich zum Überschreiben der Datei.
Ziel: Folgejobs des Profils sollen solange zurückgestellt werden, bis die Zieldatei abgeholt und gelöscht wurde.
Lösung: Die Umgebungsprüfung erfolgt mit com.ebd.hub.datawizard.extensions.EnvironmentCheckByFilter und folgender Konfiguration.
filter.param.a=not file
filter.param.b=./temp/output/Env2Check.txt
restart.execute=true
Erklärung: Da weder Klassenname noch ID für die Entscheidungsfunktion definiert sind, wird logical-condition verwendet. Diese Funktion ruft mit dem Schlüsselwort file die Funktion file-exists( filename a, [canread b],[canwrite c],[istype d],[modified e]) auf, der die Existenz der mit filter.param.b angegebenen Datei prüft.
Durch Voranstellen von not vor file wird die Logik invertiert. Dadurch wird der Folgejob suspendiert, solange die Datei noch nicht abgeholt und gelöscht wurde.
Da keine wait.time konfiguriert ist und keine Wait-Funktion, wird die Umgebungsprüfung alle 30 Sekunden wiederholt.
Mit restart.execute=true wird garantiert, dass auch bei manuellem Neudurchlauf diese Prüfung ausgeführt wird.
Szenario 2
Während der Arbeitszeit fallen Daten an, die erst mehrere Stunden nach Arbeitsschluss verarbeitet werden sollen. Alle Jobs des Profils zwischen 06:30 und 19:45 müssen suspendiert werden. Da es sich um einen langen Zeitraum handelt, sollen unnötige Läufe der Umgebungsprüfung durch Berechnung der Wartezeit vermieden werden.
Lösung: Es werden zwei Funktions-Makros entwickelt und getestet: Makros.zip
Makro AfterEight
Dieses Makro wird für die Entscheidung verwendet, ob der Job ausgeführt oder suspendiert wird. Es hat zwei Parameter:
a [Suspend start time (HHmm)] b [Suspend end time (HHmm)] |
1) now()
2) format date/timestamp to text(date a, template b, [Locale c], [Timezone d])
a result: 1
b constant: HHmm
c constant:
d constant: Europe/Berlin
3) convert-type( value a, type b, mask c)
a result: 2
b constant: Integer
4) final-on-condition(ret a, cnd b, par c [, d, ...])
a constant: true
b constant: <
c result: 3
d input: 1
5) a >= b
a result: 3
b input: 2
Makro SecondsUntilEight
Dieses Makro wird für die Berechnung der Wartezeit bis zum nächsten Lauf der Umgebungsprüfung verwendet. Es hat einen Parameter:
a [Target time (HHmm)] |
1) now()
2) format date/timestamp to text(date a, template b, [Locale c], [Timezone d])
a result: 1
b constant: HHmm
c constant:
d constant: Europe/Berlin
3) a - b
a input: 1
b result: 2
4) a * b
a result: 3
b constant: 60
5) convert-type( value a, type b, mask c)
a result: 4
b constant: Integer
Die beiden Makros werden in der Konfiguration der Umgebungsprüfung durch EnvironmentCheckByFilter verwendet.
filter.param.a=Macro AfterEight
filter.param.b=0630
filter.param.c=1945
wait.time=27
wait.filter.param.a=Macro SecondsUntilEight
wait.filter.param.b=1945