Heute möchte ich eine sehr häufig mit Nuxeo bewältigte Aufgabe besprechen: die regelmäßige serverseitige Ausführung von Geschäftslogik.

Es gibt zahlreiche Aktionen, die sich für diesen Vorgang eignen: beispielsweise die Erstellung von Wochen- oder Monatsberichten, die vierteljährliche “Bereinigung” veralteter Dokumente, die tägliche Verbindung mit einem externen Dienst und so weiter …

Wie das geht? Eigentlich ganz einfach:

  • Ein Scheduler sendet regelmäßig ein Ereignis.
  • Ein Handler wird diesem Ereignis zugewiesen und führt jedes Mal eine bestimmte Aufgabe aus, wenn das Ereignis ausgelöst wird.

Scheduler, Ereignis, Handler: All diese Elemente lassen sich ganz einfach mit Nuxeo Studio konfigurieren, dem besten Tool auf diesem Planeten, (ich habe wahrscheinlich schon in einigen meiner älteren Beiträge erwähnt, wie toll dieses Tool ist!).

Für diesen Beitrag möchte ich mich auf den folgenden Anwendungsfall konzentrieren: die Verarbeitung abgelaufener Assets.

Nehmen wir einmal an, dass mir Bild-, Video- und Audiodokumente vorliegen und für einige von ihnen ein Ablaufdatum (Feld “dc:expired”) eingerichtet wurde. Die Dateien stehen allen Benutzern zur Verfügung, nach dem Ablaufdatum muss jedoch die entsprechende Logik greifen. Für unser Beispiel möchte ich diese Logik ganz einfach gestalten: Nach dem Ablauf werden die Dokumente in einen anderen Lebenszyklusstatus (“veraltet”) überführt und die Zugriffsberechtigungen so verändert, dass nur noch Administratoren und Mitglieder der Validierungsgruppe auf die Assets zugreifen können. Für den Umgang mit abgelaufenen Assets gibt es zahlreiche Verfahren, die von den jeweiligen Geschäftsregeln und -prozessen abhängen (bei den obigen Angaben handelt es sich lediglich um ein Beispiel).

Tauchen wir also etwas tiefer in die Materie ein und unterhalten uns in der entsprechenden Reihenfolge über folgende Elemente:

  • zunächst den Scheduler (da er im Mittelpunkt aller Verfahren steht),
  • anschließend den Handler (in meinem Beispiel lediglich eine Automatisierungskette)
  • und schließlich das Ereignis

Der Scheduler

Die Architektur von Nuxeo basiert auf einem Komponentenmodell, bei dem alle Funktionen über Plug-Ins laufen und über Erweiterungspunkte konfigurierbar sind. Da Nuxeo die coolste Content-Services-Plattform überhaupt ist, ist sie (neben Hunderten weiterer Dienste) auch mit einem konfigurierbaren Scheduler-Service ausgestattet, der es Ihnen ermöglicht, so viele Scheduler hinzuzufügen, wie Sie möchten.

Ein Scheduler funktioniert ganz einfach - zunächst müssen mindestens vier Eigenschaften festgelegt werden:

  • Eine eindeutige Scheduler-ID. Interessanterweise lässt sich damit einer der Standard-Scheduler von Nuxeo überschreiben. Der nuxeo-imap-connector beispielsweise prüft alle fünf Minuten, ob neue E-Mails eingegangen sind. Wenn Sie diese Häufigkeit ändern möchten, kopieren Sie einfach die Definition und wandeln Sie die Angabe für “cronExpression” ab (siehe unten).
  • Die ID des zu sendenden Ereignisses.
  • Eine Ereigniskategorie (“default” (Standard) reicht vollkommen aus).
  • Der “cron”-Ausdruck, der festlegt, wie häufig das Ereignis ausgelöst wird.

Kurze Notiz am Rande: Nachdem “Entwickler” nicht gleichbedeutend mit “Barbar” ist und sich manche von uns auch für Etymologie interessieren, habe ich mich über den Ursprung des Worts “cron” auf Wikipedia informiert. Im englischen Artikel steht: “Das Wort stammt vom griechischen Wort für “Zeit”, χρόνος (chronos) ab.” Klingt logisch.

Der zu verwendende Ausdruck wird auf dieser Dokumentationsseite beschrieben (einschließlich Beispielen). In unserem Beispiel möchten wir täglich um 3 Uhr morgens nach abgelaufenen Assets suchen, also lautet der Ausdruck “cronExpression”…
3 ?”
Von rechts nach links gelesen bedeutet das: bei Sekunde 0; Minute 0; wenn Stunde gleich 3; beliebiger Tag des Monats; beliebiger Monat; beliebiger Wochentag.

Ich weiß ja nicht, wie es Ihnen geht, aber ich persönlich stehe nur ungern morgens um drei auf, um nachzusehen, ob mein Scheduler funktioniert, und ihn gegebenenfalls zu reparieren, und dann wieder bis um drei Uhr am folgenden Morgen zu warten, um ihn erneut zu prüfen … Schwierig ist das auch, wenn Sie in zwei Tagen eine Demo planen.

Für unser Testszenario führen wir den Scheduler also zunächst alle 30 Sekunden aus. Der folgende Befehl wird um exakt hh:mm:00s und hh:mm30s ausgeführt. Kopieren Sie diese XML-Erweiterung und fügen Sie sie unter CONFIGURATION (Konfiguration) > Advanced Settings (Erweiterte Einstellungen) > XML Extensions: (XML-Erweiterungen:) in Ihr Studio-Projekt ein.

<extension
           target="org.nuxeo.ecm.core.scheduler.SchedulerService"
           point="schedule">
  <schedule id="`HandleExpiredAssets`">
    <event>`HandleExpiredAssets`</event>
    <eventCategory>default</eventCategory>
    <!-- Every day at 3am: * * 3 * * ? →
    <!-- For our test, let's do it every 30s at hh:mm:00 and hh:mm:30-->
    <cronExpression>0/30 * * * * ?</cronExpression>
  </schedule>
</extension>

So wird ein neuer Scheduler mit der ID “HandleExpiredAssets” erstellt, der alle 30 Sekunden das Ereignis “HandleExpiredAssets” auslöst. Ich habe in diesem Beispiel sowohl für die Scheduler-ID als auch die Ereignis-ID den gleichen Wert verwendet, was jedoch nicht erforderlich ist.

Und schon ist der Scheduler bereit. Ich sagte doch, dass es ganz einfach ist! Nein, im Ernst: Jetzt, da Sie wissen wie, dauert die Erstellung eines Schedulers gerade einmal 15 Sekunden. So genial ist Nuxeo!

Der Handler

Nun schreiben wir die Automatisierungskette, die unsere abgelaufenen Assets verwaltet. Dazu müssen wir lediglich Folgendes tun:

  1. Nach Assets mit dem Feld “dc:expired” mit einem Datum früher als heute suchen, die noch nicht verarbeitet wurden
  2. Die Assets verarbeiten

In unserem Beispiel verarbeiten wir Assets durch:

  1. Änderung des Lebenszyklusstatus
  2. Änderung der Berechtigungseinstellungen, sodass nur noch Administratoren und Validierer Zugriff besitzen

Wir müssen auf irgendeine Weise nur neu abgelaufene Assets verarbeiten können, was in diesem Beispiel anhand des Lebenszyklusstatus erfolgt. Diese Lebenszyklusrichtlinie gilt für Bild-, Video- und Audio-Dokumente:

Handler-Lebenszyklus

Mit unserer Abfrage wird nur nach Assets gesucht, die aktuell den Status “genehmigt” aufweisen, die dann in den Status “veraltet” überführt werden. So sieht die NXQL-Abfrage aus, die für die Einrichtung dieser Automatisierung verwendet wird (wie gewohnt versuchen wir nicht, Versionen und Proxys zu modifizieren):

SELECT * FROM Document WHERE
ecm:primaryType IN ('Picture','Video', 'Audio')
AND ecm:currentLifeCycleState = 'approved'
AND dc:expired < DATE '@{CurrentDate.format("yyyy-MM-dd")}'
AND ecm:isVersion = 0 AND ecm:isProxy = 0

Der Lebenszyklusstatus lässt sich ganz einfach anpassen. Dazu benötigen Sie nur den Befehl “Document.FollowLifecycleTransition”.

Nun möchten wir die Berechtigungen ändern. Dazu gehört Folgendes:

  • Entfernen der Berechtigung “lokal” (falls vorhanden)
  • Blockieren der Vererbung (hierdurch werden die Administratoren automatisch zur einzigen Gruppe, die auf die Dokumente zugreifen kann)
  • Erstellen neuer Berechtigungen für Validierer

Diese Art der Automatisierung ist extrem leistungsstark! Wenn Sie die Verarbeitung ganzer Dokumentenlisten automatisieren, indem einfach ein Befehl alles erledigt, sparen Sie jede Menge Zeit und Ressourcen.

Hier gilt es jedoch zwei wichtige Punkte im Kopf zu behalten, die damit zusammenhängen, dass die Kette mit dem Scheduler beginnt. Wenn dieser also gestartet wird, gibt es keinen Kontext oder “CoreSession”. Das bedeutet, dass Sie zunächst den Befehl “Fetch > ContextDocument” entfernen müssen, der von Studio automatisch hinzugefügt wird. Anschließend müssen Sie “LoginAs” aufrufen, bevor eine Abfrage gestartet wird, da “LoginAs” eine “CoreSession” erstellt. Unten finden Sie zu Referenzzwecken die gesamte Kette. Ich habe zudem einen Protokollvorgang hinzugefügt, damit wir die Geschehnisse überwachen und prüfen können, wie der Scheduler funktioniert, wie er das Ereignis auslöst und wie unsere Kette ausgeführt wird:

Handler-Kette

Sieht gut aus, oder nicht? Bisher haben wir uns über Scheduler und Handler unterhalten, also müssen wir nun das Ereignis erstellen, das die beiden miteinander verbindet.

Das Ereignis

Wie bei den beiden anderen Vorgängen ist auch das Einrichten eines Ereignisses ganz einfach. Wir müssen lediglich ein paar Ereignishandler erstellen, die:

  1. auf unser Ereignis “HandleExpiredAssets” reagieren
  2. die Kette “HandleExpiredAssets” ausführen, wenn das Ereignis festgestellt wird

Und ja, ich neige dazu, überall die gleichen Namenskonventionen zu verwenden. Wenn Sie das verwirren sollte, können Sie gerne eigene Namenskonventionen festlegen.

Die Erstellung eines Ereignishandlers in Studio ist ganz einfach, doch bei unserem Anwendungsfall müssen wir zunächst ein kleines Problem lösen.

“HandleExpiredAssets” ist ein benutzerdefiniertes Ereignis, das Nuxeo nicht kennt, da es nicht Teil der Standardkonfiguration ist. Hier kommen also die Studio-Verzeichnisse ins Spiel. Legen Sie nun also die Elemente fest, die Studio nicht kennt, damit die Anwendung sie im Bedarfsfall entsprechend bereitstellen kann. Navigieren wir zu SETTING (Einstellungen) > Registries (Verzeichnisse) > Core Events (Hauptereignisse) und fügen unser Ereignis hinzu. Beispiel:

Verzeichnis

Nun können wir einen neuen Ereignishandler erstellen, der über dieses Ereignis in Studio aufgelistet wird. Wir erstellen also das Ereignis, wählen unser Ereignis und unsere Automatisierungskette aus und schon sind wir fertig!

Ereignis-Listener

Bereitstellen und nutzen

Oben habe ich ein Beispiel für eine Konfiguration vorgestellt, die innerhalb weniger Augenblicke vorgenommen werden kann - wahrscheinlich in weniger Zeit, als Sie für das Lesen dieses Beitrags benötigt haben!

Mein Rat? Speichern Sie alles, stellen Sie die Elemente auf dem Testserver bereit und behalten Sie das Protokoll genau im Auge. Denken Sie daran, dass wir zwei sehr spezifische Elemente verwenden: Eine benutzerdefinierte Lebenszyklusrichtlinie und eine benutzerdefinierte Gruppe (Validierer). Fangen Sie beispielsweise mit dem Öffnen eines Bilddokuments an, ändern Sie “dc:expired” in das Datum des gestrigen Tages und prüfen Sie, ob das Dokument im ersten Protokoll als erfasst und 30 Sekunden später als nicht mehr erfasst geführt wird.

Hierbei handelt es sich jedoch nur um ein einfaches Beispiel, Ihre Geschäftsregeln sind höchstwahrscheinlich sehr viel komplexer. Mit Nuxeo Studio haben Sie jedoch alle Tools zur Hand, die Sie für beliebige Automatisierungsvorgänge benötigen. Vielleicht möchten Sie ja eine Woche vor dem Ablauf E-Mail-Benachrichtigungen abschalten, sodass ein Benutzer das Asset verwalten, prüfen und das Ablaufdatum ändern kann usw.

Ich hoffe, mein Chef findet nicht heraus, dass ich mein Verfallsdatum schon lange überschritten habe …