UX-Bridge - Entwicklerhandbuch

e-Spirit AG

FirstSpirit Version 5.x

17.01.2017
Inhaltsverzeichnis

1. Einleitung

Das Modul UX-Bridge kommt dem Trend von dynamischen Websites nach. Immer dort, wo eine Vorgenerierung von Inhalten nicht möglich ist, muss dynamisch auf die CMS-Inhalte zugegriffen werden. Dynamisch bedeutet in diesem Fall, dass sich der Inhalt für jeden Website-User und zu jedem Zeitpunkt ändern kann. Die UX-Bridge bietet eine Infrastruktur für die Anforderung einer dynamischen Content-Delivery-Plattform. Somit ergänzt das Modul den hybriden Architekturansatz um eine Standardkomponente für dynamische Content-Auslieferung.
Weitere Informationen finden Sie im UX-Bridge Whitepaper.

Diese Dokumentation soll die Entwicklung mit der UX-Bridge-Infrastruktur unterstützen und einen Einblick in die Konzeption geben.

Es beschreibt im zweiten Kapitel allgemein die Schritte, die beim Einsatz der UX-Bridge zu berücksichtigen sind. Das Kapitel deckt dabei die Themen Installation, Überlegungen zum Datenaustauschformat, Einrichtung in FirstSpirit, Routing sowie Adapter- und Webapplikationseinbindung ab.

Anhand von zwei Tutorials wird die Verwendung der UX-Bridge erläutert. Hier wird an konkreten Beispielen die Implementierung in FirstSpirit, die Erstellung eines Adapters sowie der Webanwendung Schritt für Schritt exemplarisch durchgeführt.

2. Konzeption

Bestehen in einem Projekt Anforderungen, die mit Hilfe der UX-Bridge umgesetzt werden sollen, so stellen sich vor der Implementierung einige Fragen, die im Rahmen der Konzeption bedacht und ggf. beantwortet werden sollten.

Bei der Konzeption können zwei Fälle unterschieden werden:
Wird ein FirstSpirit-Projekt vollständig neu entwickelt, so liegt der Fokus der Entwicklung auf der optimalen Umsetzung der fachlichen Anforderungen. Gleichzeitig soll das Konzept hinreichend flexibel sein, um auch zukünftige Anforderungen leicht umsetzen und integrieren zu können.
Soll die UX-Bridge andererseits in ein bereits bestehendes Projekt integriert werden, so stellt sich primär die Frage, wie sie am besten in die bestehenden Konzepte und Mechanismen eingebunden werden kann.

Im Folgenden werden einige Punkte betrachtet, die in vielen Projekten relevant sein werden.

2.1. Generierungs- und Deploymentkonzept

In vielen Projekten erfolgt die Aktualisierung der Webseite durch zyklische Generierungs- und Deploymentaufträge. Diese Aufträge führen einen Komplett- bzw. einen Teilabgleich durch. Unter Umständen können diese Aufträge auch manuell ausgeführt werden. Soll in diesem Szenario die UX-Bridge verwendet werden, so reicht es oft aus, die bestehenden Aufträge um die UX-Bridge-spezifischen Aufgaben zu erweitern. Details dazu finden Sie im Kapitel Auftrag anlegen und konfigurieren.

Innerhalb der Generierung wird für jede Seitenreferenz, die innerhalb der UX-Bridge-Generierungsaufgabe erzeugt wird, eine Nachricht an den UX-Bus gesendet. Innerhalb des Projekts sollte also darauf geachtet werden, dass innerhalb dieser Aufgabe nur die notwendigen Seitenreferenzen erzeugt werden. Sollen in einem Projekt z.B. nur die News (gepflegt über eine Datenquelle) über die UX-Bridge ausgeliefert werden, so sollten in der UX-Bridge-Generierungsaufgabe auch nur die notwendigen Contentprojektionsseiten generiert werden. Um diese Einschränkung vorzunehmen, kann zum Beispiel eine Teilgenerierung verwendet werden. Alternativ dazu kann auch eine Vollgenerierung genutzt werden. Allerdings sollte dann uxbSkipMessage eingesetzt werden, um die Generierung von Seitenreferenzen im UX-Bridge Ausgabekanal abzubrechen, die keine Nachrichten erzeugen sollen (siehe Online Dokumentation für FirstSpiritVorlagenentwicklungVorlagensyntaxSystemobjekte#globalvorschaubezogenAbbruch einer Vorschau/Generierung).

In anderen Projekten wird ein Großteil der Änderungen über Arbeitsabläufe freigegeben, die anschließend eine Generierung und ein Deployment der beteiligten Objekte vornehmen. Hierbei werden zumeist die geänderten Objekte per Skript ermittelt, die dann als Startknoten einer Teilgenerierung definiert werden. Das Löschen von Objekten erfolgt durch den Einsatz von Löscharbeitsabläufen. Die UX-Bridge lässt sich in solche Szenarien ebenfalls problemlos integrieren (siehe Kapitel Workflow-Kopplung).

Spielt die Zeit, in der Objekte auf der Webseite verfügbar sein müssen, eine große Rolle, so ist die Verwendung des arbeitsablauforientierten Ansatzes oft die bessere Wahl. Je weniger Objekte im Zuge einer Generierung erzeugt werden müssen, desto schneller sind die Objekte auf der Webseite verfügbar. Mit FirstSpirit 5 steht mit der DeltaGenerierung (siehe Developer-APIDelta Generation bzw. Access-APIGenerate Task) ein vereinfachter Mechanismus für solche Szenarien zur Verfügung. Unter FirstSpirit 4 kann dies bereits durch die Nutzung der Revisions-API erreicht werden.

Insgesamt gliedert sich die UX-Bridge somit in das bestehende oder in ein neu aufzusetzendes Generierungs- und Deployment-Konzept ein und bringt dafür keine eigenständige (getrennte) Lösung mit.

2.2. Datenmodell und Adapter

Soll die UX-Bridge in ein bestehendes FirstSpirit-Projekt integriert werden, so ist das Datenmodell oft bereits vorgegeben. Bei stark strukturierten Inhalten durch das Datenbankschema, bei schwach strukturierten Inhalten durch Formulare der Seiten- und Absatzvorlagen. Hier sollte geprüft werden, ob die zu erstellende Webapplikation, die später auf die Daten der UX-Bridge zugreifen soll, mit diesem Datenmodell arbeiten kann oder ob ein anderes Datenmodell sinnvoller ist. Dies könnte der Fall sein, wenn die Webapplikation ein deutlich einfacheres bzw. deutlich komplexeres Datenmodell benötigt.

Im letzteren Fall sind die FirstSpirit-Daten also nur ein Teil des Datenmodells der Webapplikation. Im erstgenannten Fall ist für viele Webapplikationen auch eine Teilmenge des in FirstSpirit hinterlegten Datenmodells ausreichend. Zusätzlich ist zu überlegen, ob aus Performancegründen das Datenmodell der Webapplikation denormalisiert wird.

Wurde die Entscheidung getroffen, abweichende Datenmodelle zu verwenden, so ist die Frage zu klären, in welchem Schritt die Transformation von einem Datenmodell in das andere Datenmodell vorgenommen werden soll. Die Antwort ist projektspezifisch, so dass hier nur die möglichen Varianten beschrieben werden.

Eine Bewertung muss im Projektkontext erfolgen:

  1. Die Transformation erfolgt über die CMS-Syntax in den Vorlagen, die das für die UX-Bridge notwendige XML erzeugen (siehe Kapitel Datenaustauschformat – FS Templating vs. WebApp Entwicklung). Die Adapter selbst nehmen keine größeren Transformationen vor, sondern schreiben die Objekte so in das Content-Repository, wie es das Datenaustauschformat definiert hat.
  2. Das Datenaustauschformat entspricht 1:1 dem Datenmodell in FirstSpirit. Die Transformation in das Datenmodell für das Content-Repository wird innerhalb des Adapters vorgenommen.
  3. Ein hybrider Ansatz, der in beiden Komponenten Transformationen vornimmt. Je nachdem wo es sich einfacher zu realisieren lässt.

Folgende Überlegungen können bei der Bewertung helfen:

  1. Sollen die Daten in mehrere Content-Repositories geschrieben werden, so ist es oft sinnvoll, das Datenaustauschformat allgemein zu halten und etwaige notwendige bzw. sinnvolle Transformationen für das Schreiben in das Content-Repository innerhalb des Adapters vorzunehmen.
  2. Sollen die Daten in mehrere Content-Repositories geschrieben werden, so kann für jedes Content-Repository ein eigener Adapter implementiert werden, der nur die notwendige Logik für dieses Repository enthält. Alternativ kann ein Adapter die Daten in beide Content-Repositories schreiben. Dies bietet sich z.B. an, wenn das Schreiben innerhalb einer Transaktionsklammer erfolgen soll.
  3. Behandelt ein Adapter nur einen bestimmten Objekttyp oder bündelt man die Behandlung von mehreren Objekttypen in einem Adapter? Mit Objekttypen sind hier unterschiedliche Arten von Inhalten gemeint. So möchte man zum Beispiel alle Produkte und alle News aus einer FirstSpirit-Datenquelle über die UX-Bridge zur Verfügung stellen. Hier spielt zum Beispiel eine Rolle ob die beiden Objekttypen in das gleiche Content-Repository und/oder Datenmodell überführt werden sollen oder nicht.
  4. Generell ist zu überlegen, ob man aus Gründen der Entkopplung und Wartung lieber auf mehrere, dafür aber schlanke, Adapter setzt oder lieber einen Adapter verwendet, der sämtliche Logik enthält.
  5. Ein allgemein gehaltenes Datenaustauschformat hat den Vorteil, dass nur eine Nachricht über den UX-Bus geschickt werden muss, die dann aber von mehreren Adaptern verarbeitet und in mehrere Content-Repositories geschrieben werden kann. Zudem sind ggf. keine Anpassungen am Datenaustauschformat notwendig, wenn im Projektverlauf neue Content-Repositories und Webapplikationen angebunden werden sollen.
  6. Soll die UX-Bridge mit einem System kommunizieren, das bereits JMS-Nachrichten entgegen nehmen kann, so kann es sinnvoll sein, eine Transformation direkt auf dem UX-Bus vorzunehmen. So muss kein Adapter implementiert werden, der wiederum nur JMS-Nachrichten erzeugen würde. In solchen Fällen kann das Routing auf dem UX-Bus durch entsprechende Transformationsanweisungen erweitert werden.

2.3. Nachrichtenverteilungen / Routing

Wie im vorherigen Kapitel erwähnt, wird für jede Seitenreferenz innerhalb der Generierung eine Nachricht erzeugt und an den UX-Bus gesendet. Ein Teil des UX-Busses ist eine Routing-Komponente, die die Nachricht entgegen nimmt und an einen anderen sogenannten Endpunkt weiterleitet bzw. routet. Details zur Standardkonfiguration finden Sie im Kapitel Routing.

Diese Konfiguration kann für die projektspezifischen Anforderungen angepasst werden. Hierbei steht mit der Apache Camel Spring XML-Syntax eine einfache Domain-Specific Language (DSL) zur Verfügung, mit der alle gängigen Enterprise Integration Patterns (siehe http://camel.apache.org/enterprise-integration-patterns) umgesetzt werden können. Mit diesem mächtigen Integrationsframework kann der UX-Bus als Informationsdrehscheibe für den Webauftritt und alle beteiligten Systeme verwendet werden.

Hier einige Beispiele, die durch ein Routing auf dem UX-Bus umgesetzt werden können:

  1. Es wird ein Content-Router konfiguriert, der bestimmte Nachrichten nur an bestimmte Endpunkte/Adapter versendet.
  2. Es können neue Endpunkte konfiguriert werden, die als Schnittstelle zu Webapplikationen oder Backendsystemen dienen. Über diese kann zum Beispiel ein Adapter eine Webapplikation anweisen, ihren Cache zu leeren, da neue Daten in das Content-Repository geschrieben wurden.
  3. Bestehende Drittapplikationen können Nachrichten an den UX-Bus schicken, die dann von der Webapplikation, den Adaptern oder FirstSpirit verarbeitet werden.

In der Standard-Konfiguration der UX-Bridge ist bereits ein Routing konfiguriert, welches für Standardszenarien ausreicht. Nur für komplexere Szenarien (siehe Kapitel Datenmodell und Adapter) sind projektspezifische Anpassungen notwendig.

3. Quick Walkthrough

In diesem Kapitel werden die Schritte beschrieben, die notwendig sind, um die UX-Bridge in einem Projekt einzusetzen. Der Quick Walkthrough ist für den erfahrenen FirstSpirit-Vorlagenentwickler und Webapplikationsentwickler gedacht. Eine genauere Schritt-für-Schritt-Anleitung bieten die Tutorials.

3.1. FirstSpirit

3.1.1. Installation

Ausgangspunkt für die Entwicklung im UX-Bridge-Kontext ist die Installation der Komponenten.

Dazu sollte zunächst das mitgelieferte Modul in den Server-Einstellungen des FirstSpirit-Servers installiert werden. Dadurch wird der UX-Bridge-Service gestartet und die UX-Bridge-Komponenten sind in den Projekten des FirstSpirit-Servers verfügbar.

Neben dem FirstSpirit-Modul ist auch die Installation des UX-Busses notwendig. Zur lokalen Entwicklung ist die Installation im Standalone-Betrieb empfohlen.

Weitere Informationen erhalten Sie in der UX-Bridge Installationsanleitung.

3.1.2. Datenaustauschformat – FS Templating vs. WebApp Entwicklung

Die Architektur der UX-Bridge erlaubt es, die Entwicklung von Lösungen auf Basis der UX-Bridge auf zwei Rollen zu verteilen:

  • Ein Vorlagenentwickler erstellt die notwendigen Vorlagen, Arbeitsabläufe und Aufträge.
  • Ein (Web-)Applikationsentwickler entwickelt den Adapter für das Content-Repository und die (Web-)Anwendung.

Werden die Rollen durch unterschiedliche Personen wahrgenommen, so sollte während der Konzeption ein gemeinsames Datenaustauschformat definiert werden. Hiermit ist das Datenformat gemeint, was durch die Vorlagen erzeugt und über den UX-Bus als Nachricht an den Adapter verschickt wird.

Das Datenaustauschformat bildet die Schnittstelle zwischen den Komponenten und damit auch zwischen den beiden Rollen. Aus Sicht des Vorlagenentwicklers handelt es sich hierbei um das Endprodukt seiner Arbeit. Für den (Web-)Applikationsentwickler stellt es den Input für den Adapter dar. Dabei wird seitens der UX-Bridge nur ein äußerer Container vorgegeben. Der Rest kann frei definiert werden (siehe auch Kapitel Ausgabekanal anlegen und befüllen).

Ein geschickt gewähltes Datenaustauschformat kann den Implementierungsaufwand deutlich reduzieren.

Folgende Fragestellungen können bei der Wahl helfen:

  • Existieren die Daten und damit das Datenmodell bereits in FirstSpirit? Falls ja, ist man gewissen Beschränkungen unterworfen. Falls nein, bietet es sich an, das Datenaustauschformat möglichst nah an das Datenformat im Content-Repository bzw. der Webapplikation anzulehnen.
  • Aus Performancegründen kann es sinnvoll sein, die Daten denormalisiert in das Content-Repository zu schreiben. Mögliche Inkonsistenzen können durch ein Volldeployment korrigiert werden, da die Daten in FirstSpirit in der Regel weiterhin normalisiert vorliegen.
  • Sollen die Daten in mehr als ein Content-Repository geschrieben werden? Falls ja, ist zu ermitteln ob ein Datenaustauschformat ausreichend ist und der/die Adapter die Transformation und Persistierung in das Content-Repository übernehmen. In manchen Fällen kann es auch effizienter sein, zwei Datenaustauschformate durch FirstSpirit erzeugen zu lassen, die dann ohne einen Transformationsschritt in das jeweilige Content-Repository übernommen werden können.

3.1.3. Ausgabekanal anlegen und befüllen

Um die UX-Bridge zu nutzen, sollte zunächst unter ProjekteinstellungenVorlagensätze ein neuer Vorlagensatz (UXB) angelegt werden. Als Präsentationskanal sollte XML als Konvertierungsregel Unicode to XML und als Zieldateierweiterung xml konfiguriert werden.

Vorlagensatz anlegen
Abbildung 1. Vorlagensatz anlegen


Die Konvertierungsregel Unicode to XML dient dazu, Sonder- und Steuerzeichen in korrespondierende XML-Entitäten umzuwandeln, die sonst in XML als Teil der Markupsprache interpretiert werden bzw. ungültige Zeichen darstellen würden.

Um Nachrichten an den UX-Bus zu schicken, sind in der entsprechenden Vorlage, die die Nachrichten erzeugen soll, die Felder, die im Datenaustauschformat definiert wurden, in Form von XML auszugeben.

Ausgabekanal im SiteArchitect
Abbildung 2. Ausgabekanal im SiteArchitect


Vorgegeben ist lediglich folgende Struktur:

<uxb_entity uuid = String destinations = String  language = String command = String objectType = String>
 <uxb_content>
   […] definiertes Datenaustauschformat […]
 </uxb_content>
</uxb_entity>

Property

Beschreibung

Beispiel

Pflichtfeld

Uuid

Eindeutiger Bezeichner des Objektes z.B. fs_id

1234

Ja

destinations

Ziel(e) der Nachricht

(Live-Repository, kommasepariert),

postgres, mongodb

Ja

language

Sprache der Nachricht

DE

Nein

command

Auszuführendes Kommando vom Adapter (z.B. anlegen/löschen)

Add

Nein

objectType

Objektyp der vom Adapter ausgewertet wird (z.B. News, Products)

News

Nein

Die Attribute language, command und objectType sind optional, haben sich aber bei den von e-Spirit implementierten Adaptern als hilfreich erwiesen.

3.1.4. Auftrag anlegen und konfigurieren

Um die Daten von FirstSpirit in Nachrichten umzuwandeln, die vom UX-Bus weiterverarbeitet werden können, muss zwingend ein Auftrag angelegt oder ein bestehender Auftrag so erweitert werden, dass er XML generiert und dieses an den UXB-Service weiterreicht, der daraus eine Nachricht erzeugt und diese an den UX-Bus versendet. Der Auftrag kann später über einen Workflow gestartet werden. In diesem Kapitel sollen nun zwei Aufträge erklärt werden, die wahrscheinlich in jedem Projekt, welches die UX-Bridge nutzt, benötigt werden.

Teilgenerierung

Um neue Inhalte schnell auf der Webseite zu publizieren, bietet es sich an, einen Auftrag anzulegen bzw. so zu erweitern, dass er die folgenden beschriebenen Schritte durchführt und hierbei nur die neuen Inhalte generiert und veröffentlicht.

Ein typischer Generierungsauftrag, der die UX-Bridge nutzt, gliedert sich in mehrere Aktionen, wie nachfolgend beschrieben:

Auftragsübersicht
Abbildung 3. Auftragsübersicht


Zunächst sollten in einer Generierungsaktion die komplett statischen Seiten, die zur Anzeige auf der Webseite notwendig sind (z.B. News-Übersichtsseiten), generiert werden. Diese Generierungsaktion findet sich auch in den bisher üblichen Deployment-Aufträgen und muss dann nicht angepasst werden.

Im nächsten Schritt sollten dann die im vorherigen Schritt generierten Inhalte wie gewohnt auf den Webserver übertragen werden (im Beispiel über rsync). Auch in diesem Schritt sind in der Regel keine Anpassungen notwendig.

Um die UX-Bridge einzusetzen, ist danach eine neue, weitere Aktion hinzuzufügen, die mittels Skriptaufruf die Generierung für die UX-Bridge aktiviert:

UX-Bridge Generate. 

#! executable-class
com.espirit.moddev.uxbridge.inline.UxbInlineUtil

In der darauf folgenden Generierungsaktion sollten dann genau die Seite generiert werden (z.B. News-Detailseite), die das XML erzeugt, das an den UXB-Service weitergereicht werden soll. Wichtig zu beachten ist, dass in den erweiterten Eigenschaften auch der UXB-Vorlagensatz aktiviert wurde.

Aktivierung des Vorlagensatzes
Abbildung 4. Aktivierung des Vorlagensatzes


Die Delta-Generierung in FirstSpirit 5 passt die Generierungsaktion automatisch so an, dass nicht mehr alle Seiten, sondern nur noch die gewünschte Seite generiert wird. Dazu kann z.B. in einem Workflowskript, das die Generierung anstößt, die zu generierende Seite an den Auftrag übergeben werden.

Die letzte Aktion UX-Bridge Statistics Report ist optional und ermöglicht es, die Durchlaufzeiten für die Nachrichten im UX-Bus bis zur Veröffentlichung auf der Webseite zu messen.

INFO  22.08.2012 09:59:54.631 (de.espirit.firstspirit.server.scheduler.ScheduleManagerImpl): starting task 'UX-Bridge Statistics Report' - schedule entry 'UX-Bridge-Test (News)' (id=5142)
INFO  22.08.2012 10:00:04.645 (com.espirit.moddev.uxbridge.service.UxbServiceImpl): Time for #uxb/pressreleasesdetails/UXB/EN/256 (postgres): 242ms
INFO  22.08.2012 10:00:04.645 (com.espirit.moddev.uxbridge.service.UxbServiceImpl): Time for #uxb/pressreleasesdetails/UXB/DE/256 (postgres): 224ms
INFO  22.08.2012 10:00:04.645 (com.espirit.moddev.uxbridge.service.UxbServiceImpl): 2/2 deployed successfully (overall: 233ms, postgres: 233ms).
INFO  22.08.2012 10:00:04.646 (de.espirit.firstspirit.server.scheduler.ScheduleManagerImpl): finished task 'UX-Bridge Statistics Report' - schedule entry 'UX-Bridge-Test (News)' (id=5142)

Dazu ist folgender Skriptaufruf notwendig:

UX-Bridge Statistics Report. 

#! executable-class
com.espirit.moddev.uxbridge.inline.UxbResultHandler

Der Service wartet maximal den in der Servicekonfiguration der UX-Bridge definierten Zeitraum, bis die Antworten der Adapter ausgewertet werden. Kommt in diesem Zeitfenster keine Antwort, so gilt die Nachricht als fehlerhaft zugestellt. Da die Antwortzeiten je nach Nachricht und System variieren können, ist dieser Wert konfigurierbar.

Alternativ zu diesem maximalen Zeitraum für den gesamten Auftrag, kann ein Heartbeat konfiguriert werden. Hierfür wird ein maximaler Zeitraum konfiguriert, der zwischen zwei Heartbeat-Nachrichten vergehen darf. Es ist zu beachten, dass alle verwendeten Adapter einen Heartbeat senden müssen. Empfängt der ResultHandler zu lange keinen Heartbeat, wird der Auftrag als fehlerhaft gewertet und eine Timeout-Nachricht angezeigt. Das Versenden von Heartbeat-Nachrichten muss auf Adapterseite implementiert werden. Eine Beispielimplementierung befindet unter https://github.com/e-Spirit/uxbridge-samples/blob/master/newsWidget/adapter/hibernate/src/main/java/com/espirit/moddev/examples/uxbridge/newswidget/jpa/ArticleHandler.java

Zu beachten ist, dass jede Generierungsaktion, die zwischen UX-Bridge Activate Generation und UX-Bridge Statistics Report aufgerufen wird, eine UX-Bridge-Generierung durchführt. Soll im selben Auftrag eine weitere Generierung ins Dateisystem erfolgen, ohne dass zuvor das Skript UX-Bridge Statistics Report aufgerufen wurde, so muss vor dieser Generierung ein Skript zur Deaktivierung der UX-Bridge-Generierung eingefügt werden:

UX-Bridge Deactivate Generation. 

#! executable-class
com.espirit.moddev.uxbridge.inline.UxbDeactivate

Komplettabgleich

Es ist sinnvoll einen weiteren Auftrag anzulegen, der einen Komplettabgleich durchführt, um den Datenbestand im Content-Repository auf dem aktuellsten Stand zu halten. Hierfür müssen die in FirstSpirit gelöschten Daten ebenfalls auch im externen Repository gelöscht werden.

Es empfiehlt sich folgende Vorgehensweise:

  1. Vollgenerierung der statischen Seiten in FirstSpirit
  2. UX-Bridge-Auftrag ausführen, um alle Daten ins ContentRepository zu schreiben (siehe dazu den vorherigen Abschnitt). Diese Daten bekommen einen aktuellen Timestamp übergeben, der im ContentRepository im Feld lastmodified gespeichert wird.
  3. Skript ausführen, welches die cleanup-Methode mit einem Timestamp als Parameter aufruft, der die neueste Projektrevision des Auftrags beschreibt. Die cleanup-Methode löscht dann alle Daten, die eine ältere Zeit, als die übergebene, im Feld lastmodified gespeichert haben. Das sind die Daten, die im FirstSpirit-Projekt bereits gelöscht wurden und somit im Schritt 2 keinen neuen Timestamp in lastmodified gespeichert haben.

cleanup-Skript. 

import com.espirit.moddev.uxbridge.api.v1.service.UxbService;
uxbService = context.getConnection().getService(UxbService.class);
uxbService.removeUxbEntriesByTime(context.getStartTime().getTime(), "news", "postgres,mongodb");

Historische Daten

Um historische Daten mittels der UX-Bridge zu generieren, muss eine neue Skript-Aktion vor der Aktion UX-Bridge - Activate Generation hinzugefügt werden z.B.

Skript. 

import java.util.Date;
Date d = new Date(114, 5, 24);
context.setStartTime(d);

Das gesetzte Datum wird dann in der folgenden Aktion (UX-Bridge - Activate Generation) berücksichtigt.

Auftrag Start / Ende im Adapter erkennen

Um im Adapter auf den Start bzw. das Ende eines Auftrags unter Umständen gezielt reagieren zu können, kann die UX-Bridge zu Beginn und am Ende der Generierung jeweils automatisch eine separate Nachricht versenden (siehe auch UX-Bridge Installationsanleitung).

Die Startnachricht besitzt dabei folgendes Format:

<uxb_entity projectName="PROJEKT_NAME" status="start" schedulerId="AUFTRAGS_ID" createTime="ZEITPUNKT_DER_NACHRICHT" projectId="PROJEKT_ID" startTime="STARTZEITPUNKT_DES_AUFTRAGS" />

Bei einer Vollgenerierung wird noch das Attribut command=“startMaintenanceMode“ hinzugefügt.

Die Endnachricht besitzt folgendes Format:

<uxb_entity projectName="PROJEKT_NAME" status="end" schedulerId="AUFTRAGS_ID" createTime="ZEITPUNKT_DER_NACHRICHT" projectId="PROJEKT_ID" startTime="STARTZEITPUNKT_DES_AUFTRAGS" />

Bei einer Vollgenerierung wird noch das Attribut command=“stopMaintenanceMode“ hinzugefügt.

Sollte bei einer Vollgenerierung die maximale Anzahl an erlaubten Fehlern bzw. Timeouts im Adapter überschritten werden, hat das Attribut command den Wert keepMaintenanceModeUp.

Root-Attribute erweitern

Die Wurzelknoten der über die UX-Bridge verschickten Nachrichten besitzen standardmäßig bereits einige Attribute, wie beispielsweise den Projektnamen oder die ID des Auftrags. Diese lassen sich durch beliebige, weitere Attribute erweitern. Zur Angabe dieser Root-Attribute muss dem Generierungsauftrag als erste Aktion das Skript Configure UXB Message Header hinzugefügt werden, welches den folgenden Inhalt besitzt:

Skript - Configure UXB Message Header. 

import java.util.HashMap;
attributeMap = new HashMap();
attributeMap.put("customAttribute1", "customAttributeValue1");
attributeMap.put("customAttribute2", "customAttributeValue2");
context.setProperty("uxbMessageRootAttributes", attributeMap);

Das Skript erzeugt eine HashMap, in der die gewünschten Attribute in Form von Key/Value-Paaren hinzugefügt werden können. Die HashMap wird anschließend an den Kontext des Auftrags übergeben, damit der UXBService während der Erzeugung der Nachrichten auf sie zugreifen kann.

3.1.5. Überspringen von Seiten bei der Generierung

Sollen bei der Nachrichtengenerierung Seiten übersprungen werden, so ist dies durch das setzen der Seitenvariable uxbSkipMessage möglich.

uxbSkipMessage. 

$CMS_SET(#global.pageContext["uxbSkipMessage"], true)$

Die Benutzung von stopGenerate (siehe Online Dokumentation für FirstSpiritVorlagenentwicklungVorlagensyntaxSystemobjekte#globalvorschaubezogenAbbruch einer Vorschau/Generierung) wird nicht unterstützt und führt in diesem Fall zu ungültigem XML und dadurch zu Fehlermeldungen im Log.

3.1.6. Erweiterte Projektinformationen auslesen

Die UX-Bridge kann zu Beginn der Generierung eine Nachricht mit erweiterten Projektinformationen verschicken (siehe UX-Bridge Installationsanleitung). Zu diesen Informationen zählen zurzeit die definierten Projektsprachen und Auflösungen.

Beispiel. 

<uxb_entity projectName="UXB" objectType="projectInfo" schedulerId="92460" createTime="1371037891875" projectId="88785"  startTime="1375346932923">
 <project key="UXB">
  <id>88785</id>
  <name>UXB</name>
  <languages>
   <language key="DE">
    <name>Deutsch</name>
    <abbreviation>DE</abbreviation>
    <isMasterLanguage>true</isMasterLanguage>
   </language>
  </languages>
  <resolutions>
   <resolution key="ORIGINAL">
    <name>Originalauflösung</name>
    <uid>ORIGINAL</uid>
    <height>0</height>
    <width>0</width>
    <isOriginal>true</isOriginal>
   </resolution>
  </resolutions>
 </project>
</uxb_entity>

3.1.7. Workflow-Kopplung

Die Publikation von Inhalten über die UX-Bridge kann sowohl direkt über Skripte und Aufträge als auch indirekt über Workflows gestartet werden.

Release Workflow

Um Inhalte zu publizieren, muss ein bestehender Workflow lediglich um ein Workflow-Skript erweitert werden, das einen Auftrag startet, der neben Generierung und Deployment auch die XML-Nachrichten erzeugt und an den UXB-Service weiterreicht (siehe Kapitel Teilgenerierung).

Delete Workflow

Um Inhalte zu löschen, muss ein bestehender Löschworkflow um ein Workflow-Skript erweitert werden, das eine XML-Nachricht erzeugt, die an den UXB-Service weitergereicht wird.

Der Aufruf des UXB-Service im Skript lautet wie folgt, wobei msg (String) der XML-Nachricht entspricht:

Aufruf des UXB-Service. 

UxbService uxbService = context.getConnection().getService(UxbService.class);
uxbService.removeUxbEntry(msg);

Die XML-Nachricht folgt dabei folgendem Muster:

<uxb_entity uuid=STRING language=STRING destinations=STRING objectType=STRING command=STRING />

Property

Beschreibung

Beispiel

Pflichtfeld

Uuid

Eindeutiger Bezeichner der Objektes (z.B. fs_id)

12345

Ja

Destinations

Ziel(e) der Nachricht (kommasepariert)

postgres

Ja

Command

Auszuführendes Kommando vom Adapter

delete

Ja

Language

Sprache der Nachricht

DE

Nein

objectType

Objekttyp, der vom Adapter ausgewertet wird

(z.B. News, Products)

news

Nein

3.2. Adapter

Adapter dienen dazu, die Daten aus den JMS-Nachrichten auszulesen und in die ausgewählten Repositories zu schreiben. Im Tutorial werden zwei Adapter beispielhaft als Webanwendungen realisiert, aber auch andere Implementierungen (z.B. standalone Java) sind möglich.

3.2.1. Rückmeldung

FirstSpirit erwartet eine Antwort in Form eines XML-Dokuments vom Adapter, nachdem eine Nachricht in ein Repository geschrieben wurde. Die Antwort wird sowohl bei einer erfolgreichen als auch bei einer fehlhaften Verarbeitung erwartet. Das Antwort-XML-Dokument ist wie folgt aufgebaut:

<uxb_entity command=STRING createTime= STRING destinations=STRING finishTime=STRING language=STRING path=STRING schedulerId=STRING startTime=STRING status=STRING uuid=STRING ><uxb_error>STRING </uxb_error></uxb_entity>

Property

Beschreibung

Beispiel

Pflichtfeld

destinations

Das Ziel-Repository, in das das Objekt geschrieben wurde bzw. geschrieben werden sollte.

postgres

Ja

startTime

Timestamp des Starts der Aktion (Wird von FirstSpirit bei der Aktion ins XML-Dokument eingehangen.)

1314567899516

Ja

finishTime

Timestamp der Fertigstellung des Kommandos

1314567899516

Ja

path

FirstSpirit interner Pfad (Wird von FirstSpirit bei der Aktion ins XML-Dokument eingehangen.)

the/Path/to/

Ja

status

Status der Aktion.

Mögliche Werte:

OK bei Erfolg,

FAIL im Fehlerfall

OK

Ja

uuid

eindeutiger Bezeichner der Objektes z.B. fs_id

123456

Ja

schedulerId

eindeutige ID des Auftrages (Wird von FirstSpirit bei der Aktion ins XML-Dokument eingehangen.)

123456

Ja

command

ausgeführtes Kommando vom Adapter

delete

Nein

language

Sprache der Nachricht

DE

Nein

createTime

Timestamp der Erstellung der Aktion (Wird von FirstSpirit bei der Aktion ins XML-Dokument eingehangen.)

1314567899516

Nein

uxb_error

das Containerelement für die im Fehlerfall vorhandene Fehlermeldung

com.mongodb. MongoException

Nein

3.3. WebApplikation

Durch die offene Architektur der UX-Bridge und den Umstand, dass die Art und Anzahl der Repositories nicht vorgegeben werden, sind die Technologie und das Framework, um die WebApplikation zu entwickeln, frei wählbar. Es bietet sich an, die Auswahl der Technologie und des Frameworks sowohl an den Anwendungsfall als auch an das vorhandene KnowHow bzw. die Unternehmensstandards anzupassen.

3.4. Routing

Die UX-Bridge nutzt Apache Camel zum Routen von Nachrichten. Als Transport- und Nachrichtenprotokoll kommt der Java Message Service (JMS) zum Einsatz. Die beiden beteiligten Komponenten (FirstSpirit-Server und Adapter) fungieren dabei jeweils sowohl in der Rolle eines Producers, der Nachrichten erzeugt und in einem Endpunkt zur Verfügung stellt, als auch in der Rolle eines Consumers, der Nachrichten von einem Endpunkt abholt und weiterverarbeitet. Der UX-Bus übernimmt in diesem Szenario lediglich das Routing der Nachrichten zwischen den beteiligten Endpunkten.