Serverseitige Skripte

enaio® 10.0 »

Skripte, die auf dem Server laufen, müssen unter Umständen auf Kernel-Objekte des Servers zugreifen können. Zu diesem Zweck wird vom Server im Skript das Objekt 'Running Context' (RC) zur Verfügung gestellt. Soweit es von den JobDrivenEvents nicht anders definiert ist, lautet die Variablen-Instanz 'RC'. Darüber hinaus können von den verschiedenen Jobs in JobDrivenEvents auch proprietäre Objekte zur Verfügung gestellt werden. Diese werden dann in der Dokumentation der entsprechenden Jobs gesondert vermerkt. Auch die Art der Bereitstellung dieser Objekte ist jobspezifisch.

Entwicklung von Skripten

Alle Kernel-Objekte sind dem Running Context zugeordnet und sind niemals direkt im globalen Namensraum des Skripts sichtbar, im Gegensatz zu Objekten, die der Job selbst hinzufügt. Diese können auch im globalen Namensraum sichtbar sein. Auf jeden Fall sind sie zusätzlich auch dem Running Context zugeordnet. Somit unterscheiden sich die Kernel-Objekte von jobspezifischen Objekten, da die Kernel-Objekte nur über den Running Context sichtbar sind und niemals direkt, wobei die jobspezifischen Objekte immer über Running Context und möglicherweise auch direkt als Variablen sichtbar sein können. Auch auf diese jobspezifischen Objekte kann über den Running Context zugegriffen werden.

Es gibt zwei Möglichkeiten, auf die Objekte über Running Context zuzugreifen, entweder über Eigenschaft 'Item', z. B. 'RC.Item("SessionData")', oder mit dem Punkt vom RC getrennt, z. B. 'RC.SessionData'.

Die erste Möglichkeit funktioniert sowohl mit Namen, als auch mit Nummern. Die Nummer des Objektes kann als Parameter der Eigenschaft 'Item' übergeben werden: RC.Item(2).

Die gesamte Anzahl der Objekte im RC kann mit dem Eigenschaft 'RC.Count' ermittelt werden. Die Kernel-Objekte stehen in der Liste immer hinter allen jobspezifischen Objekten, d. h. die Nummerierung ist nicht bei jedem Aufruf die gleiche.

RC

Der Running Context hat außer allen Objekten noch die Eigenschaft 'GUIAvailable', mit der man aus dem Skript heraus ermitteln kann, ob die GUI-Aufrufe im Skript erlaubt sind, und die Methode 'NewJobsParams', mit der man eine neue Instanz der Parameterliste erstellen kann, die dann für die Jobsaufrufe verwendet wird.

Die dritte Methode des RC ist 'IncludeFile(BSTR FileName)' und kann dafür benutzt werden, ein großes Skript auf mehrere aufzuteilen.

Eine weitere Eigenschaft des RC ist 'UseNewDB'. Sie wird verwendet, um zu steuern, ob Jobs in einer Transaktion aufgerufen werden oder einen eigenen Transaktionskontext bekommen.

Objekte

Es gibt folgende Kernel-Objekte des ersten Levels:

  • SessionData,

  • ServerData,

  • General,

  • Logger,

  • Jobs,

  • Actions,

  • Registry.

Im Folgenden ist die Beschreibung der einzelnen Objekte aufgeführt.

SessionData

Dieses Objekt liefert Daten über das Konto des Benutzers, in dessen Kontext das Skript ausgeführt wird. Momentan stehen folgende Eigenschaften zur Verfügung:

Name

Beschreibung

SessGUID

GUID der Client-Sitzung

UserName

Name des Benutzers

StatName

Name des Rechners, an dem enaio® client läuft

InstName

Name des Programms, aus dem das Login erfolgte

UserGUID

GUID des Benutzers

StatGUID

GUID der Station von enaio® client

Das ist keine MAC-Adresse, sondern die GUID des Datensatzes aus der DB.

UserID

ID des Benutzers

Supervisor

Das Supervisor-Flag aus der Benutzer-Tabelle für den Benutzer

LangID

Sprache-ID aus der Benutzer-Tabelle für den Benutzer

ServerData

Dieses Objekt liefert unterschiedliche Konfigurationsdaten aus der Laufzeitumgebung des Servers. Momentan stehen folgende Eigenschaften zur Verfügung:

Name

Beschreibung

DataDir

Pfad zum Datenbereich der Servergruppe

RootDir

Pfad, über den der Server gestartet wurde

TempDir

Pfad zum ostemp-Verzeichnis des Servers

ConfDir

Pfad zum etc-Verzeichnis der Servergruppe

UserDir

Pfad zum user-Verzeichnis der Servergruppe

Service

Name des Dienstes

LogDir

Pfad zum log-Verzeichnis, in das der Server protokolliert

Connect

Computername und TCP-Port, durch '#' getrennt

ServerID

ID des Servers

GroupID

ID der Servergruppe

General

Dieses Objekt liefert einige allgemeine Daten des Jobs. Momentan stehen folgende Eigenschaften zur Verfügung:

Name

Beschreibung

JobNumber

Nummer des Jobs, fortlaufend seit dem Serverstart gezählt

ThreadID

ID des Threads, in dem der Jobs gerade ausgeführt wird

Logger

Dieses Objekt gibt die Möglichkeit im Kernel-Kontext zu protokollieren. Das Skript kann auch ein eigenes Protokoll führen, indem er die oxrpt.dll per COM direkt anspricht. Dabei wird eine eigene Konfiguration genommen. Alternativ kann das Skript über das Objekt Logger protokollieren. Das Logger-Objekt stellt folgende Methoden zur Verfügung:

Name

Beschreibung

Flow

Flow-Protokoll auf Level 5

FlowEx

Level und die Stelle im Skript können festgelegt werden

Info

Flow-Protokoll mit Facility 'informational' auf Level 3

InfoEx

Wie Info, die Stelle im Skript kann festgelegt werden

Warning

Flow-Protokoll mit Facility 'warning' auf Level 3

WarningEx

Wie Warning, die Stelle im Skript kann festgelegt werden

Error

Error-Protokoll mit Facility 'error' auf Level 0

errorEx

Wie Error, die Stelle im Skript kann festgelegt werden

Der Aufruf eines Protokolleintrags wird im Protokoll mit dem Text 'SCRIPT: […]' erscheinen, wobei in der Klammer der übergebene Text protokolliert wird. Je nach Methodenaufruf erscheint der Eintrag als 'Flow', 'Info', 'Warning' oder 'Error'.

Alle Methoden haben einen Parameter 'Text', der den eigentlichen Protokolleintrag darstellt, und je nach Methode weitere Parameter:

Flow(BSTR Text);

Warning(BSTR Text);

Info(BSTR Text);

Error(BSTR Text);

FlowEx(BSTR Text, UINT Level, BSTR Function, UINT Line);

WarningEx(BSTR Text, BSTR Function, UINT Line);

InfoEx(BSTR Text, BSTR Function, UINT Line);

ErrorEx(BSTR Text, BSTR Function, UINT Line);

Die Protokollierung über Methode 'Flow' wird auf dem Level 5 durchgeführt, die Methoden 'Info' und 'Warning' benutzen Level 3, und die Methode 'Error' benutzt Level 0.

Jobs

Dieses Objekt gibt die Möglichkeit unterschiedliche Server-Jobs ausführen zu lassen. Die Jobs werden synchron ausgeführt, d. h. die Aufrufmethode kehrt genau dann zurück, wenn der Job beendet ist, erfolgreich oder nicht. Der Aufruf eines Jobs sieht beispielsweise folgendermaßen aus:

1    Dim PrmIn

2    Dim PrmOut

 

3    Set PrmIn = RC.NewJobsParams

4    Set PrmOut = RC.NewJobsParams

 

5    PrmIn.Clear()

6    PrmIn.Value("Flags") = 0

7    res = RC.Jobs.krn.GetNextIndex(PrmIn,PrmOut)

8    if res = 0 then

9    MsgBox("krn.GetNextIndex succeeded: " & NextIndex)

    ‘Zur Ermittlung des Parameters siehe nächstes Kapitel.

10    else

11    MsgBox("krn.GetNextIndex failed: " & res)

12    end if

13    PrmOut.Clear()

In Zeilen 1 bis 4 erstellt man zwei Objekte, die als Eingabe- und Ausgabeparametern für den Job verwendet werden. Diese Objekte kann man nicht nur für einen Job, sondern für mehrere Jobs verwenden. Man kann zwar die Elemente hinzufügen und abfragen, aber nicht einzeln löschen. Deswegen wird die Methode 'Clear' eingeführt, mit der die Liste leer gemacht wird (Zeilen 5 und 13). Dann kann die Liste von Eingabeparametern gefüllt werden. Die Eigenschaft, die den jeweiligen Parameter darstellt, heißt 'Value' und hat den Namen des Parameters als Argument. Der Typ eines Parameters wird analysiert und dabei wird ein XMLRPC-Parameter erstellt, der den entsprechenden Typ hat. 'BSTR' wird nach 'XMLRPC-String' konvertiert. Verschiedene 'Integer-Werte' werden 'XMLRPC-Integer', und 'BOOL' wird 'XMLRPC-Boolean'. Andere 'XMLRPC-Typen' werden in der vorliegenden Version nicht unterstützt.

Danach erfolgt der Aufruf selbst, und zwar in Form:

RC.Jobs.namespace.jobname(in-list,out-list)

Hier ist 'namespace' die Bezeichnung eines Exekutors bzw. Namespaces (wie immer drei Buchstaben) und darauf folgt der Job-Name. Der Jobaufruf liefert einen Integer-Wert zurück, der normalerweise auf '0' gesetzt wird, falls der Job erfolgreich war. Dieser Wert stellt 'dwResult' da, was die eigentliche Job-Funktion zurückgibt. Sollten Probleme auftreten, die dazu führen, dass der Job überhaupt nicht aufrufbar ist (z. B. eine Exception oder der Job bzw. Namespace sind nicht bekannt), wird kein Rückgabewert zurückgegeben, sondern eine COM-Exception generiert. Wenn also der Aufruf 'Job.krn.MyJob' zurückkehrt, ohne eine COM-Exception auszulösen, kann davon ausgegangen werden, dass MyJob aufgerufen wurde und wenn der Aufruf Job.krn.MyJob z. B. den Wert '-1' zurückgibt, so kommt dieser Wert aus der Jobfunktion, und nicht aus dem Kernel heraus.

Um dem Job Dateien zu übergeben, fügt man einen weiteren Parameter hinzu. Dieser Parameter heißt $Job$Files$ und ist eine Zeichenkette. Sie besteht aus Dateinamen, die durch Semikolon getrennt angegeben werden.

Nach der Rückkehr kann man die Ausgabeparameter auswerten, sie befinden sich in unserem Beispiel in der Output-Parameter Liste 'PrmOut'. Selbstverständlich muss man die Namen der Parameter wissen. Die Ausgabedateien werden erhalten, indem der Job ausgewertet und gesplittet wird.

Dabei ist zu beachten, dass jedem Dateinamen ein Fragezeichen vorangestellt sein kann. Dies ist der Fall, wenn vom Job temporäre Dateien im ostemp-Verzeichnis angelegt werden, z. B. eine verschlüsselte Datei aus dem WORK-Verzeichnis wird in das ostemp Verzeichnis entschlüsselt.

Ist dem Dateinamen kein Fragezeichen vorangestellt, handelt es sich um keine temporäre Datei, und wurde somit z. B. direkt im CACHE oder WORK-Verzeichnis abgelegt.

Wird beispielsweise eine nicht vorhandene Variable angefragt, liefert der Performer den Parameter auch zurück, nur ist die Variable dabei nicht initialisiert, sie hat also den Typ 'VT_EMPTY'. Im Skript kann es mit der Funktion 'IsEmpty' geprüft werden. Die Namen der Jobs bzw. Namen und Typen der Jobparameter sind in Dokumentation der Server-API aufgeführt.

Sollen dem Job BASE64 Parameter übergeben werden, bzw. von dem Job BASE64 Parameter ausgelesen werden, so sind die Details dem folgenden Abschnitt 'Parameters' zu entnehmen. Ist beispielsweise die Variable Dom ein MSXML.DOMDocument-Objekt, in das ein XML geladen wurde, so kann man mit dem Befehl

PrmIn.Value("Buffer") = Dom

einen Input Parameter vom Typ BASE64 dem Job zuweisen. Umgekehrt kann man einen Ausgabeparameter folgendermaßen auslesen:

B64Result = PrmOut.Value("Result")

Dom.load(B64Result)

 

Wenn Sie einen Job im Skript am Server aufrufen und diesem den $$$Server-ID$$$-Parameter übergeben, dann wird dieser Job an den übergebenen Server weitergeleitet und dort ausgeführt. Aus Sicherheitsgründen gilt dieses Verfahren nur, wenn der Job per RC in einem Skript am Server aufgerufen wird.

Actions

Mit diesem Objekt sind einige Funktionsaufrufe möglich, die der Kernel selbst implementiert. Momentan stehen folgende Methoden zur Verfügung:

Name

Beschreibung

SendMail

Sendet eine E-Mail mit Eingabe von Ziel und Quelladressen, Thema, Text und die Liste von Dateien.

SendAdminMail

Sendet eine E-Mail an den Administrator, falls seine Adresse in der Registrierung konfiguriert ist.

StreamReset

Leert einen Istream.

Die Liste mit Dateinamen ist eine Zeichenkette, in der die Dateinamen mit Semikolon getrennt sind. Die Methoden haben folgende Parameter:

SendMail(BSTR To, BSTR From, BSTR Subject, BSTR Text, BSTR Files);

SendAdminMail(BSTR From, BSTR Subject, BSTR Text, BSTR Files);

StreamReset (VARIANT stream); // VARIANT ist vom Typ IStream oder BYREF | VARIANT und dann IStream

Registry

Dieses Objekt bietet die Möglichkeit die Elemente in der Server-Registrierung zu lesen und zu schreiben. Es stehen folgende Eigenschaften zur Verfügung:

Name

Beschreibung

Element

Diese Eigenschaft kann gelesen und geschrieben werden, und hat einen Parameter von Typ 'BSTR', der den vollständigen Pfad zum Element darstellt. Der Wert des Elementes hat ebenfalls den Typ 'BSTR'.

Der Pfad zum Element fängt mit dem aktuellen Schema an. Beispielsweise wird auf das Element 'ComString', das unter dem aktuellen Schema liegt, so zugegriffen: RC.Registry.Element("ComString").

Auf das Element 'Schema' das unter dem Schlüssel 'DataBase' liegt, wird mit 'RC.Registry.Element("DataBase\Schema")' zugegriffen. Achten Sie dabei auf die Groß-/Kleinschreibung.

Parameters

Dem Skript können verschiedene Parameter übergeben werden. Genauso können diese nach der Ausführung des Skripts zurückgegeben werden.

Dim InputNames

InputNames = RC.InputParams.Names

MsgBox("Input params: " & InputNames)

 

Dim NameArray

NameArray = Split(InputNames,";",-1,1)

MsgBox("VarType((NameArray) = " & VarType(NameArray))

Dim sMsg, i, sName

Dim Param

for i = LBound(NameArray) to UBound(NameArray)

    sName = NameArray(i)

    if (len(sName) > 0) then

        Param = RC.InputParams.Value(sName)

         if (IsEmpty(Param)) then

         sMsg = sMsg & "Parameter " & sName & " not found"

       else

          sMsg = sMsg & sName

          sMsg = sMsg & ": "

           sMsg = sMsg & Param

        end if

          sMsg = sMsg & vbCrLf

        end if

  next

  MsgBox(sMsg)

 

  RC.OutputParams.Value("hallo") = "Welt"

Zwei Objekte 'RC.InputParams' und 'RC.OutputParams' ermöglichen die Arbeit mit Parametern. Die Eigenschaft 'Names' gibt die Namen von allen Parametern aus der Liste zurück, durch Semikolon getrennt. Die Eigenschaft 'Value' ermöglicht, den Parameter zu lesen oder zu schreiben.

Ein besonderer Fall ist die Ausführung von Skripten bei KernelDrivenEvents. Die KDEs werden vor und nach dem Job aufgerufen. Sie brauchen deshalb Zugriff auf die Job-Parameter. Das wird durch die Variablen 'InputParams' und 'OutputParams' gewährleistet. Im Before Skript eines KDEs werden alle Parameter dem Skript als Input Parameter zur Verfügung gestellt. Nach der Ausführung des Skripts wird diese Liste von Input Parametern vollständig die originale Parameterliste des ursprünglichen Jobs ersetzen, denn es können auch einzelne Parameter aus der Liste entfernt werden. Im After Skript eines KDEs werden alle Input Parameter des Jobs (bzw. des Before Skripts) zur Verfügung gestellt, sowie alle Ausgabeparameter des Jobs. Die Ausgabeparameter können nun manipuliert werden. Im Gegensatz zum Before Skript werden die Output-Parameter nicht komplett ersetzt, sondern lediglich die Werte der vorhandenen Parameter geändert.

Bei Parametern, die nicht vom Type 'BASE64' sind, können die Werte wie oben beschrieben abgefragt bzw. geändert werden. Bei BASE64-Parametern wird anders vorgegangen: Solche Parameter werden als 'IStreams' dargestellt. Das Skript kann nun solche IStreams an diejenigen Schnittstellen weiterleiten, die diese auch verstehen, so z. B. an ein XMLDOMDocument, denn die Implementierung des 'msxml' erlaubt das Laden von XML aus IStreams. Anschließend kann ein mögliches DOM erneut in einen IStream gespeichern werden. Allerdings wird dabei der Inhalt von 'DOMDocument' anschließend dem IStream hinzugefügt, deswegen muss der IStream vorher geleert werden. Das kann mit 'RC.Actions.StreamReset(param)' erreicht werden.

Files

RunningContext hat Methoden, die es erlauben, Dateilisten dem Skript zu übergeben bzw. zurückzubekommen.

Mit 'RC.InputFiles' kann man im Skript die Dateiliste auslesen, die das Skript als Eingabeliste bekommt.

Mit 'RC.OutputFiles' kann man im Skript die Ausgabeliste von Dateien festlegen.

Beispiel: RC.OutputFiles = "c:\temp\1.txt;c:\temp\2.txt"

Die einzelnen Dateinamen müssen dabei mit Semikolon getrennt werden.

RunScript

Die beschriebene Funktionalität kann mit dem Job 'krn.RunScript' getestet werden. Dieser Job kann außerdem für administrative Zwecke benutzt werden, um beispielsweise periodisch bestimmte Skripte ausführen zu lassen.

Der Job 'RunScript' benötigt folgende Parameter:

Name

Typ

Beschreibung

Flags

Integer (2)

Wenn der Wert '1' ist, werden die dem Job übergeben Dateien nicht gelöscht.

Script

String (1)

Der Text des Skripts. Wenn dieser Parameter eine leere Zeichenkette ist, wird geprüft, ob mit dem Job mindestens eine Datei ankommt. Wenn nicht, so wird ein Fehler zurückgegeben. Wenn ja, so wird der Dateiinhalt als Skripttext verwendet. Nach dem Job werden alle angekommenen Dateien gelöscht, falls Flags den Wert '0' hat.

GUI

Boolean (3)

Wird weiter dem Performer als 'bGUIAvailable' übergeben. Mit dem Wert '0' wird die Möglichkeit abgeschaltet, eine Nachrichtenfenster anzuzeigen. Der Wert '1' kann diese Möglichkeit einschalten, es sei denn sie ist per Registrierung generell abgeschaltet worden.

CtxName

String (1)

Name des RunningContext, unter dem er im Skript sichtbar gemacht wird. Wenn dieser Parameter leer ist, wird 'RC' benutzt.

Main

String (1)

Name der Funktion, die im Skript aufgerufen werden soll, kann aber auch leer sein. Wenn der Parameter fehlt, wird 'Main' als Funktion angenommen.

Eval

Boolean (3)

Gibt an ob der Skripttext eine Expression darstellt.

Der Rückgabewert der serverseitig ausgeführten Skript-Funktion (mit leerem Job-Parameter 'Main' heißt die Funktion 'Main') wird nach Jobausführung als Rückgabeparameter '$ScriptResult$' (vom Datentyp String) zurückgeliefert.

Beispiel:

Set oServer = CreateObject( "OxSvrSpt.Server" )

set oSession = oServer.Login("<User>" , "<PWD>" , "<Server>", "<Port>" )

 

sScript= _

"Function Main" & vbcrlf & _

"Main=now" & vbCrLf & _

"End Function"

MsgBox _

"Lokale Zeit: " & vbTab & now & vbCrLf & _

"~Zeit am Server: " & vbTab & _

RunScript(oSession, sScript), vbInformation, _

"Zeitdifferenz lokal/server"

 

Function RunScript(oSession, sScript)

     set oJob = oSession.NewJob("krn.RunScript")

     oJob.InputParameters.AddNewStringParameter "Script", sScript

     oJob.InputParameters.AddNewStringParameter "CtxName", ""

     oJob.InputParameters.AddNewIntegerParameter "Flags", 0

     oJob.InputParameters.AddNewBooleanParameter "GUI", 0

     oJob.InputParameters.AddNewBooleanParameter "Eval", 0

     oJob.Execute

     RunScript = oJob.OutputParameters("$ScriptResult$.Value

End Function

Als Ergebnis wird folgendes Nachrichtenfenster zurückgeliefert:

Um dem Skript eine Parameterliste übergeben zu können, kann man dem Job weitere optionale Parameter übergeben. Diese Parameter müssen sich von normalen Jobparametern unterscheiden und müssen daher Namen besitzen, die bei diesem Job nicht vorhanden sind. Außerdem müssen beim Aufruf die Namen und die Werte wie folgt getrennt werden:

Name

Typ

Beschreibung

$SP_1_name$

String (1)

Der Name des ersten Skript-Parameters

$SP_1_value$

Beliebig

Der Wert des ersten Skript-Parameters

...

 

 

$SP_xx_name$

String (1)

Der Name des letzten Skript-Parameters

$SP_xx_value$

Beliebig

Der Wert des letzten Skript-Parameters

Diese Parameter müssen fortlaufend durchnummeriert werden.