Die Intrexx Connector API definiert eine Java API, um eigene Intrexx Connectoren zu implementieren, die externe Daten in Intrexx über Fremddatengruppen bereitstellen. Dabei gibt die API im Wesentlichen zwei Java Interfaces vor, die vom Entwickler zu implementieren sind, um Datensätze und Dateien im externen System zu erstellen, lesen, aktualisieren und löschen (sog. CRUD Aktionen). Des Weiteren wird in der Connector Konfigurationsdatei ein Metadaten-Modell hinterlegt, das Datengruppen (Felder, Beziehungen, Konfiguration) beschreibt, die von der Connector Implementierung bereitgestellt werden. Zur Laufzeit bietet die Connector-API vorkonfigurierte Java APIs für HTTP und OData Anfragen, welche automatisch eine Authentifizierung des Benutzers - sofern vom Service benötigt - via HTTP Basic Auth oder OAuth2 durchführen. Ansonsten lassen sich beliebige Java Bibliotheken (z.B. JDBC, REST APIs, etc.) in eigenem Code verwenden.
Für einen schnellen Start in die Connector Entwicklung werden im Folgenden Beispiel-Implementierungen beschrieben, die den Einsatz der API zur Anbindung von Fremdsystemen in Intrexx verdeutlichen.
- Intrexx 21.03 oder Steady Track
- Java 11 oder 17
- Optional wird für die Entwicklung eigener Connectoren eine IDE wie z.B. Eclipse Java IDE oder IntelliJ IDEA empfohlen.
Das Projekt kann in einen beliebigen Ordner (außerhalb Intrexx) geklont werden. Im Folgenden wird davon ausgegangen, dass der Projektornder intrexx-sample-connector-api
heißt.
Um den Quellcode kompilieren zu können, werden einige Intrexx sowie externe Bibliotheken benötigt. Diese sind in der Gradle Projektdatei build.gradle
aufgeführt und werden normalerweise automatisch heruntergeladen. Sollte der Zugriff auf das United Planet Maven Repository nicht möglich sein, können die benötigten JAR-Dateien aus dem lib
Ordner der Intrexx Installation in den lib
Ordner des Projekts kopiert werden.
Das Projekt wird mit Gradle verwaltet und kompiliert. Folgende Befehle können direkt im Hauptordner des Projekts ausgeführt werden:
Windows:
gradlew.bat clean
gradlew.bat build
gradlew.bat jar
Linux/MacOS
./gradlew clean
./gradlew build
./gradlew jar
Eclipse starten und prüfen, dass das Gradle Plugin installiert ist. Anschließend über File->Import->Gradle
den Projektordner in den Workspace importieren. Das Projekt sollte anschließend im Package Explorer verfügbar sein.
IntelliJ bietet von Haus aus Unterstützung für Gradle Projekte. Das Projekt kann einfach über den Öffnen Dialog importiert werden, in diesem ist das Projektverzeichnis auszuwählen.
Um eigenen Java-Code zur Laufzeit in einem Intrexx Portal testen und debuggen zu können, lässt sich der Portalserver in Eclise/IntelliJ im Debug-Modus ausführen. Voraussetzung dafür ist, dass Intrexx und das Intrexx Portal auf dem lokalen PC wie die Entwicklungsumgebung installiert sind und der Portalserver Dienst zuvor beendet wurde. Es folgt die Einrichtung der Run Configuration für den Portalserver in Eclipse, in IntelliJ können dieselben Angaben verwendet werden:
- Unter Run->Run Configurations einen neuen Gradle Task erstellen, Name 'Portalserver'.
- Unter Task den Task
startPortal
wählen. - Die Variablen für den Poralserver Pfad in
settings.gradle
auf die lokale Intrexx Installation anpassen. - Optional: Die Datei
<INTREXX_HOME>\org\<portal>\internal\cfg\log4j2.xml
zulog4j2-console.xml
kopieren und darin die Logausgaben auf die Console mit ausgeben.
Nun kann der Portalserver via Run/Debug in Eclipse/IntelliJ gestartet werden und Breakpoints in eigenem Code gesetzt werden. Wird zur Laufzeit ein Breakpoint erreicht, wird ab dieser Stelle der Debugger aktiviert.
Der Portalserver kann auch aus der Kommandozeile ohne Debugger gestartet werden:
Windows:
gradlew.bat startPortal
Linux/MacOS
./gradlew startPortal
Das Projekt enthält drei Beispiele für den Zugriff auf
- Google Kalender und Google Drive
- MS Office365 Termine
- SonarQube
Die Beispiele für Google und Office365 benötigen eine OAuth2 Konfiguration für die Authentifizierung am Service im Intrexx Portal. Wie diese einzurichten ist, wird in der Intrexx Online-Hilfe beschrieben.
Eigene Connectoren können direkt innerhalb des Beispiel-Projekts entwickelt werden oder es wird eine Kopie des Projektordners erstellt, der Java Quellcode unter /src/main/java gelöscht und eigene Klassen darunter erstellt. Im Folgenden wird Schritt für Schritt die Erstellung eines eigenen Connectors beschrieben.
Hinweis: Sollte die Entwicklung auf Basis eines bereits bestehenden Portals erfolgen, so ist zu prüfen, ob diese beiden Dateien sich bereits im Portalverzeichnis befinden. Ansonsten müssen diese aus dem jeweiligen Ordner unter <INTREXX_HOME>/orgtempl/...
in alle Portale kopiert werden.
- org<portal>\internal\cfg\biaconfig\bia-connector.cfg
- org<portal>\internal\cfg\odata\connector\template\msoffice365.xml
Das InMemory Connector Beispiel bietet den Zugriff auf eine interne Datenstruktur über eine Intrexx Fremddatengruppe. Dabei werden alle CRUD Aktionen sowie Sortierung unter Pagination unterstützt.
Neue Connectoren definieren eine Template Datei unter org\<portal>\internal\cfg\odata\connector\template\
. Als Dateiname sollte ein Connector Bezeichner gewählt werden. Legen Sie in dem Ordner eine neue Datei inmemory.xml an und kopieren Sie diesen Inhalt in die Datei:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<connector>
<guid></guid>
<name>InMemory</name>
<description>Configuration template for the InMemory test connector.</description>
<connectorId>inmemory</connectorId>
<properties>
</properties>
<userMappings>
</userMappings>
<metaData>
<dataGroups>
<dataGroup name="MyDataGroup">
<fields>
<field name="ID" typeName="long" primaryKey="true" />
<field name="Title" typeName="string" primaryKey="false" />
<field name="Double" typeName="double" primaryKey="false" />
<field name="Long" typeName="long" primaryKey="false" />
<field name="Text" typeName="text" primaryKey="false" />
<field name="DateTime" typeName="datetime" primaryKey="false" />
<field name="Boolean" typeName="boolean" primaryKey="false" />
</fields>
<settings>
<setting key="connector.cfg.guid" value=""/>
<setting key="connector.dataGroup.adapter.class" value="de.uplanet.lucy.connectorapi.examples.simple.InMemoryDataGroupConnector"/>
</settings>
</dataGroup>
</dataGroups>
<fileFields>
</fileFields>
</metaData>
</connector>
Der wesentliche Abschnitt im Connector-Template befindet sich unter <metaData>
. Hier werden die Datengruppen, Felder und Expert Settings definiert, die der Connector für Fremddatengruppen in Intrexx bereitstellt. Es können beliebig viele Datengruppen und Felder definiert werden. Weiterhin können auch Dateifelder für den Datei-Upload/Download definiert werden, worauf hier nicht eingegangen wird, da es den Rahmen dieses Quick Starts überschreiten würde.
In diesem Beispiel wird eine Datengruppe mit 7 Feldern für die jeweils möglichen Intrexx Datentypen erstellt. Zusätzlich ist anzugeben, ob das Feld Teil des Primary Keys ist.
Auf Basis dieses Templates können nun konkrete Connector-Konfigurationen in Intrexx registriert werden. Dadurch ist es möglich, unterschiedliche Services mit denselben Metadaten aber unterschiedlicher Konfiguration anzulegen. Dazu kopieren Sie die Datei nach org\<portal>\internal\cfg\odata\connector
und benennen Sie um nach inmemory_test.xml
. Der erste Teil des Namens vor dem Unterstrich bezeichnet die Connector ID (siehe oben <connectorId>
), der zweite Teil ist der Name dieser konkreten Konfiguration (hier test
). Öffnen Sie die Datei dann in einem Editor und ergänzen Sie <guid>
und <name>
wie folgt (GUID muss in allen Dateien eindeutig sein:
<guid>F27302911D5DA4E8FE7A500D3F4E1E699BDF0592</guid>
<name>test</name>
...
<settings>
<setting key="connector.cfg.guid" value="inmemory_test"/>
...
Starten Sie anschließend den Portalserver neu.
Als nächstes kann bereits eine Applikation in Intrexx erstellt werden, die diesen Connector verwendet.
- Legen Sie dazu eine neue 'Leere Applikation' im Anwendungsdesigner an und löschen Sie die Datengruppe 'Datengruppe'.
- Erstellen Sie eine neue Fremddatengruppe mit Namen 'InMemory'.
- Unter 'Datenbankverbindung' wählen Sie den Eintrag
inmemory_test
, unter Datahandler sollte nun 'Connector API - Datenhandler' stehen. - Klicken Sie neben dem 'Tabellen'-Feld auf das Lupen-Symbol und suchen Sie nach allen Tabellen mit '*'. Es sollte eine Tabelle
CONNECTOR_API.MyDataGroup
erscheinen. Wählen Sie diese aus. - Klicken Sie nun auf der Registerkarte 'Datenfelder' auf das
+
Symbol und wählen alle Felder aus. - Wechseln Sie nun auf die Registerkarte Expert und dort auf Settings. Legen Sie folgende zwei neue Settings an:
connector.cfg.guid = inmemory_test
connector.dataGroup.adapter.class = de.uplanet.lucy.connectorapi.examples.simple.InMemoryDataGroupConnector
- Schließen Sie dann den Datengruppendialog mit 'OK'.
- Nun kann auf der Ansichtsseite der Applikation eine neue Ansichtsstabelle erstellt werden, die alle Felder der Datengruppe beinhaltet.
- Veröffentlichen Sie die Applikation und rufen Sie sie im Portal auf. Es wird ein Fehler erscheinen, da die Adapter Klasse noch nicht gefunden wird.
Hinweis: Die App befindet sich auch als Import-Paket im Projektverzeichnis unter docs/InMemoryConnector.lax
und kann so direkt in Intrexx importiert werden.
Damit eigene Connector Klassen zur Laufzeit im Portalserver gefunden werden, muss die Jar-Datei des Projekts in den Intrexx Classpath aufgenommen werden. Am einfachsten geschieht dies, wenn direkt nach Aufruf von gradlew.bat jar
die Datei unter build\libs\connector-examples-8.1.3.jar
nach <INTREXX_HOME>\lib
kopiert wird. Danach muss der Portalserver Dienst neu gestartet werden. Nach dem Neustart und Aufruf der Applikation im Portal sollten drei Datensätze in der Tabelle aufgelistet werden. Diese können geändert, gelöscht oder neu erstellt werden.
Die Logik für den Datenzugriff ist in der Klasse de.uplanet.lucy.connectorapi.examples.simple.InMemoryDataGroupConnector
implementiert. Darin werden die Anhand der übergebenen Abfrage-Parameter die Daten ermittelt und in die Connector API Datenstrukturen überführt bzw. bei Inserts/Updates die Werte aus den Intrexx Objekten in der Tabelle gespeichert.
In den Java Packages de.uplanet.lucy.connectorapi.examples
befinden sich weitere Beispiel Implementierungen, die den Zugriff auf REST Webservices via HTTP und OData aufzeigen. Dabei werden auch Intrexx Filter-, Sortierung- und Pagination-Funktionen verwendet. Weiterführende Dokumentationen dazu befinden sich im Unterverzeichnis docs
.
Im docs/api
Verzeichnis des Projekts befinden sich die Java API Dokumentation der Intrexx Connector API. Darin werden alle wesentlichen Klassen und Interfaces beschrieben. Des Weiteren stehen zur Laufzeit alle Kontextobjekte (Session, Request, etc.) wie in Intrexx Groovy Skripten zur Verfügung.
Die öffentlichen Schnittstellen und Klassen der Connector API befinden sich im Paket de.uplanet.lucy.server.odata.connector.api.v1
. Im Folgenden werden die für eigene Connectoren zu implementierenden Methoden und bereitgestellte Hilfsklassen anhand des InMemory Beispiels beschrieben.
Dieses Interface definiert die benötigten Methoden für Create/Read/Update/Delete-Aktionen von Intrexx Fremddatengruppen.
IConnectorQueryResult queryDataRange(IConnectorQueryCriteria p_criteria)
Diese Methode wird von Intrexx aufgerufen, wenn Datensätze für eine Fremddatengruppe geladen werden sollen. Über dasIConnectorQueryCriteria p_criteria
Argument werden zur Auswahl der Datensätze benötigte Informationen wie Filter, Sortierung, Pagination übergeben.IConnectorRecord queryDataRecord(String p_strRecordId, List<IConnectorField> p_fields)
Diese Methode wird von Intrexx aufgerufen, wenn ein einzelne Datensatz für eine Fremddatengruppe geladen werden sollen. Über dasString p_strRecId
Argument wird die ID des zu ladenden Datensatzes übergeben, währendList<IConnectorField> p_fields
die zu selektierenden Datensatzfelder beinhaltet.String insert(IConnectorRecord p_record)
Diese Methode dient zum Anlegen eines neuen Datensatzes. DasIConnectorRecord p_record
Argument enthält dabei die Datensatz-ID als auch die Feldwerte.boolean update(IConnectorRecord p_record)
Diese Methode dient zum Ändern eines bestehenden Datensatzes. DasIConnectorRecord p_record
Argument enthält dabei die Datensatz-ID sowie die Feldwerte.void delete(IConnectorRecord p_record)
Diese Methode dient zum Löschen eines bestehenden Datensatzes. DasIConnectorRecord p_record
Argument enthält dabei die Datensatz-ID.
Von dieser abstrakten Klasse sollten alle konkreten IConnectorDataGroupAdapter-Implementierungen erben. Die Klasse stellt eine Reihe von Hilfsmethoden und Kontextobjekte zur Verfügung.
Dieses Interface definiert die benötigten Methoden für Create/Read/Update/Delete-Aktionen von Intrexx Dateifeldern. Diese können zu einer Intrexx Datengruppe oder einer Fremddatengruppe gehören.
Von dieser abstrakten Klasse sollten alle konkreten IConnectorFileAdapter-Implementierungen erben. Die Klasse stellt eine Reihe von Hilfsmethoden und Kontextobjekte zur Verfügung.