Im letzten Blog (So verbindet man den Micro Integrator mit der Mastodon-API – Teil 1) habe ich mich mit der API beschäftigt, die Mastodon bereitstellt, um z. B. das Posten von neuen Toots (der Name einer Nachricht bei Mastodon) zu automatisieren. Warum ist das wichtig? Wie schon Twitter entwickelt sich auch dieser Dienst zu einem Kommunikationskanal für Unternehmen. Für normale Nutzer ist eine browsergestützte Schnittstelle völlig ausreichend, aber für Unternehmen ist eine Integration in die IT-Landschaft durchaus attraktiv.
Die Möglichkeit, Nachrichten zu automatisieren (sowohl das Lesen als auch das Senden), kann Prozesse optimieren. In diesem zweiten Teil zeige ich Ihnen, wie man so eine Integration mithilfe der Konnektor-Funktion des WSO2 Micro Integrator erstellt.
Den Konnektor erstellen
Ein Konnektor besteht aus einer Reihe gebündelter Dienste, die in den Micro Integrator integriert werden können. Es handelt sich dabei um eine ZIP-Datei, die geparst wird. Die einzelnen Dienste werden dem Server hinzugefügt, sodass Sie deren Funktionen – wie das automatischen Versenden von Nachrichten – nutzen können.
Was die Entwicklung betrifft, so kann derselbe Konnektor im Integration Studio verwendet werden, um neue Artefakte zu entwickeln, die die neue Funktionalität nutzen. Im weiteren Verlauf dieses Artikels werden wir uns das genauer ansehen.
Die Erstellung eines umfangreichen Konnektors ist eine Menge Arbeit, und ich werde Ihnen jetzt nur zeigen, wie Sie die Struktur einrichten und eine einfache Implementierung vornehmen. Ansonsten würde der Blog nämlich sehr lang werden.
Als Parameter nehme ich das Zugriffstoken, das wir aus dem letzten API-Aufruf im vorherigen Blog erhalten haben. Es wird als Parameter definiert und anschließend als Header an die Backend-API gesendet.
Das Einrichten einer Struktur für einen Konnektor für den Micro Integrator ist ganz einfach. Sie müssen lediglich einen Maven-Archetyp verwenden und ihn so konfigurieren, dass er die API enthält, die Sie bereitstellen möchten.
Der Maven-Befehl lautet wie folgt:
mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate -DarchetypeGroupId=org.wso2.carbon.extension.archetype -DarchetypeArtifactId=org.wso2.carbon.extension.esb.connector-archetype -DarchetypeVersion=2.0.4 -DgroupId=org.wso2.carbon.esb.connector -DartifactId=org.wso2.carbon.esb.connector.mastodon -Dversion=1.0.0 -DarchetypeRepository=http://maven.wso2.org/nexus/content/repositories/wso2-public/
Hier sehen Sie einen Teil der Struktur:
Ein Konnektor kann je nach Anforderung aus Synapse-Konfigurationen, aber auch aus Java- und Soap-Diensten bestehen.
Wir werden die notwendigen Änderungen auf eine sehr einfache und leichte Weise im Ordner src/main/resources vornehmen. Wenn ich das Verzeichnis source main resources öffne, werden Sie zwei Unterverzeichnisse sehen, nämlich sample und config, auf die in der Konnektor-Datei verwiesen wird.
Wir werden ein neues Unterverzeichnis namens statuses erstellen, in dem wir die Statusvorlage definieren. So können wir einen Status in unserem Benutzerkonto auf Mastodon posten.
Löschen Sie das Verzeichnis sample und erstellen Sie das Verzeichnis statuses. Achten Sie außerdem darauf, auch die Konnektor-Datei zu aktualisieren. Ich habe ein Unterverzeichnis icon erstellt, in dem ich zwei Mastodon-Icons (25×25 und 72×80 png) abgelegt habe. Die Dokumentation ist recht vage, weil in einigen Beispielen auf die Icons in der Konnektor-Datei im Stammverzeichnis verwiesen wird und in anderen nicht, dort ist nur das Verzeichnis angegeben.
Ich habe nicht auf sie verwiesen, sondern sie einfach mit den richtigen Namen an die richtige Stelle gesetzt.
Der API-Aufruf ist einfach zu erfassen. Das ist der Synapse-Quellcode. Wie Sie sehen können, stellen wir ihn als API bereit. Für den Konnektor werde ich keine API verwenden, sondern eine Sequenzvorlage, die einen Parameter übernimmt. In diesem Fall ist das der Status, den wir vom API-Aufruf erhalten. Dieser wird an den HTTP-Endpunkt gesendet.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/mastodon" name="Status" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" url-mapping="/status">
<inSequence>
<property expression="json-eval($.status)" name="uri.var.status"/>
<header name="Authorization" scope="transport" value="Bearer IfC08KP8LtDT9I1bofk-yhoZ9zgswn6CRK23okW42Gk"/>
<call>
<endpoint>
<http method="post" uri-template="https://mastodon.nl/api/v1/statuses?status={uri.var.status}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Hier sehen Sie auch, dass der API-Aufruf erfolgreich war und dass die Statusaktualisierung auf Mastodon verfügbar ist.
Jetzt werden wir die API ändern, um die Änderungen zu berücksichtigen. Anstelle des Aufrufs über die API werden wir also die Vorlage mit dem Parameter aufrufen.
Anstatt die API aufzurufen, rufen wir jetzt eine Vorlage auf, die die Statusaktualisierung an Mastodon übermittelt.
<?xml version="1.0" encoding="UTF-8"?>
<template name="write-status" xmlns="http://ws.apache.org/ns/synapse">
<parameter isMandatory="false" name="status"/>
<sequence>
<property expression="$func:status" name="uri.var.status" scope="default" type="STRING"/>
<header name="Authorization" scope="transport" value="Bearer IfC08KP8LtDT9I1bofk-yhoZ9zgswn6CRK23okW42Gk"/>
<call>
<endpoint>
<http method="post" uri-template="https://mastodon.nl/api/v1/statuses?status={uri.var.status}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</sequence>
</template>
And
<?xml version="1.0" encoding="UTF-8"?>
<component name="statuses" type="synapse/template" >
<subComponents>
<component name="write-status" >
<file>write-status.xml</file>
<description>mastodon simple connection</description>
</component>
</subComponents>
</component>
Ich nehme einen mvn build (mvn clean install) vor und erzeuge einen Konnektor.
Ich füge ihn dem Integration Studio in meinem Projekt hinzu.
Und da ist er, ein Mastodon-Konnektor mit unseren implementierten Operationen.
Mit dem Mastodon-Konnektor kann ich jetzt Artefakte entwickeln. Ich werde einen Proxy erstellen, der einfach eine Nachricht, die in den Nutzdaten enthalten ist, an unser Mastodon-Konto sendet.
Das Setup ist eine einfache Soap-Nachricht, die eine XML als Nutzdaten und die Nachricht aus den Nutzdaten (//incoming) übernimmt und sie an die Vorlage sendet, um sie bei Mastodon einzustellen.
In der grafischen Übersicht sieht das so aus:
In der Quellansicht so:
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="MProxy" startOnLoad="true" transports="http https" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<mastodon.write-status>
<status>{//incoming}</status>
</mastodon.write-status>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
</proxy>
Ich habe ein Soap-Projekt in SoapUI erstellt, für das ich einen sehr einfachen Body konstruiert habe. Das <incoming> Tag enthält die Nachricht, die durch den Befehl //incoming Xpath im obigen Code abgerufen wird.
Sie können die Nachricht sehen, die Mastodon erreicht. Weil ich die Antwort von Mastodon nehme und an den Client zurücksende – in diesem Fall an SoapUI – können Sie die ursprüngliche Antwort der API sehen.
HTTP/1.1 200 OK
[ … ]{„id“:“109823997802502951″,“created_at“:“2023-02-07T14:46:56.499Z“,“in_reply_to_id“:null,“in_reply_to_account_id“:null,“sensitive“:false,“spoiler_text“:““,“visibility“:“public“,“language“:“en“,“uri“:“https://mastodon.nl/users/yenlo/statuses/109823997802502951″,“url“:“https://mastodon.nl/@yenlo/109823997802502951″,“replies_count“:0,“reblogs_count“:0,“favourites_count“:0,“edited_at“:null,“favourited“:false,“reblogged“:false,“muted“:false,“bookmarked“:false,“pinned“:false,“content“:“\u003cp\u003ethis is mymessage\u003c/p\u003e“,“filtered“:[],“reblog“:null,“application“:{„name“:“yenlo-app“,“website“:null},“account“:{„id“:“109703822406851413″,“username“:“yenlo“,“acct“:“yenlo“,“display_name“:“yenlo“,“locked“:false,“bot“:false,“discoverable“:false,“group“:false
[ … ]}
In Mastodon sieht man natürlich nur die Nachricht.
Ergebnis
In relativ kurzer Zeit habe ich einen sehr einfachen Konnektor erstellt, der eine Verbindung zu einem Dienst herstellt. Wie bereits erwähnt, würde es sehr viel Zeit in Anspruch nehmen, die API zu verstehen und alle verfügbaren APIs und Dienste zu implementieren, wenn man es so umsetzen möchte, dass es über einen einfachen Blog wie diesen hinaus genutzt werden kann. Die Einrichtung mit einem fest kodierten Zugriffstoken für die Mastodon-API kommt in der Realität natürlich nie vor. Wenn ich das in einem realen Szenario entwickeln würde, würde ich den Client-Schlüssel, das Client-Geheimnis, die Token und die Codes verschlüsseln und sie in einer Art Tresor speichern, um sie bei Bedarf abrufen zu können.
Der große Vorteil bei der Arbeit mit Konnektoren ist, dass ein großer Teil der Arbeit bereits erledigt ist. Sie müssen nur noch die Verbindung zum Dienst herstellen, indem Sie Ihre Anmeldeinformationen irgendwo speichern und/oder abrufen. Dann können Sie damit beginnen, Integrationen auf sehr einfache Weise zu erstellen, indem Sie sie per Drag & Drop in eine grafische Ansicht ziehen und die Details in der Quellansicht eingeben.