Zielsysteme
Was ist das
Ein Zielsystem ist eine benannte, einmal hinterlegte Verbindung zu einem externen System. Aktionen rufen REST- und SOAP-Zielsysteme über rest.call und soap.call auf. Ein AMQP-Zielsystem stellt Verbindung und Anmeldung für amqp.publish oder für einen getrennt definierten eingehenden Listener bereit. Die Zugangsdaten stecken nie in der Aktion oder im Listener selbst, sondern am Zielsystem, und dort nur als Verweis auf ein Secret.
Sie legen ein Zielsystem einmal in der Verwaltung an und verwenden danach nur noch seinen Namen, in beliebig vielen Aktionen und Kommando-Schritten. Ändert sich die Adresse des externen Systems oder das dahinterliegende Secret, passen Sie allein das Zielsystem an. Die Aktionen, die es referenzieren, bleiben unverändert, denn sie kennen nur den Namen, nicht die Details dahinter. Der kind eines Zielsystems, rest, soap oder amqp, legt fest, welches Protokoll dahintersteckt und welche Felder die Definition zusätzlich braucht.
Ausgehende Kommando-Schritte verwenden Zielsysteme. Ein eingehender AMQP-Listener bleibt eine getrennte Definition: Er referenziert ein AMQP-Zielsystem, konsumiert eine Queue und erzeugt ein Ereignis für Trigger.
flowchart LR
Action["Aktion"] --> RestCall["rest.call"]
Action --> SoapCall["soap.call"]
Action --> Publish["amqp.publish"]
subgraph Destinations["Zielsysteme"]
RestDest["REST-Zielsystem"]
SoapDest["SOAP-Zielsystem"]
AmqpDest["AMQP-Zielsystem"]
end
subgraph Listeners["Eingehende AMQP-Listener"]
Listener["Listener"] --> Event["Ereignis"]
end
RestCall --> RestDest --> RestService["REST-Dienst"]
SoapCall --> SoapDest --> SoapService["SOAP-Dienst"]
Publish --> AmqpDest --> Broker["AMQP-Broker"]
Broker -->|"Queue"| Listener
Listener -.->|"referenziert Verbindung"| AmqpDest
Event --> Trigger["Trigger"]
Wann einsetzen
- Fertigmeldung ans ERP. Ein Trigger löst nach dem letzten Produktionsschritt automatisch die Aktion
fertigmeldungaus. Diese ruft mitrest.calldas Zielsystemerpauf und schickt Los, Auftrag und Menge im Body mit. Das ERP-System wertet die Rückmeldung aus. - Auftragsdaten von einem Webservice. Ein SOAP-Zielsystem liefert Auftragsdaten aus einem bestehenden Webservice, den eine Aktion über
soap.callabfragt. Der Schritt baut das passende SOAP Envelope mit der zugehörigenSOAPActionund liest das Ergebnis per XPath aus der Antwort. - Nachrichten an einen Broker. Eine Aktion veröffentlicht über
amqp.publisheine Nachricht mit dem Content-Typeapplication/jsonan Exchange und Routing-Key. Für die Gegenrichtung referenziert ein eigener AMQP-Listener dasselbe oder ein anderes AMQP-Zielsystem, konsumiert genau eine Queue und erzeugt daraus einen konfigurierten Ereignistyp.
Anatomie der Definition
Eine Zielsystem-Definition ist ein flaches JSON-Objekt:
name: der Bezeichner des Zielsystems,^[a-z][a-z0-9-]{0,63}$. Kommando-Schritte referenzieren das Zielsystem ausschließlich über diesen Namen.kind:rest,soapoderamqp.base_url: die Basisadresse des Zielsystems.username: nur beikind: amqpgesetzt, der Benutzername für die Broker-Verbindung.auth: ein Objekt ausheaderundsecret. Bei REST oder SOAP istheaderder Name des Auth-Headers, zum BeispielAuthorization, undsecretder Name eines vorhandenen Secrets. Bei AMQP mussheaderleer bleiben;secretverweist auf das Broker-Passwort. Den Wert löst WERKSPUR erst beim tatsächlichen Aufruf auf. Existiert das benannte Secret nicht, scheitert der Aufruf, statt ohne die vorgesehene Anmeldung weiterzumachen.
Bei einem AMQP-Zielsystem tragen username und auth.secret gemeinsam die Zugangsdaten für die Broker-Verbindung. Der Benutzername steht offen in der Definition, das Passwort dagegen ausschließlich als Verweis auf ein Secret, nie als Klartext. Ein REST- oder SOAP-Zielsystem braucht kein username-Feld. Dort tragen auth.header und auth.secret gemeinsam die Authentifizierung, sofern das Zielsystem eine benötigt.
Bei einem SOAP-Zielsystem liest der Editor unter „Zielsysteme“ eine WSDL ein, wahlweise als Datei oder über eine URL. Er zeigt die gefundenen Operationen an und füllt base_url daraus vor. Die WSDL bleibt am Zielsystem gespeichert und hilft später dem Assistenten beim Formulieren neuer Aufrufe: Er liest sie über das Werkzeug describe_destination aus, das Zielnamensraum, Operationsliste und die rohe WSDL zurückgibt, noch bevor er einen soap.call-Schritt vorschlägt.
In einer Aktion binden Sie ein Zielsystem über den passenden Kommando-Schritt ein. rest.call setzt base_url und den am Schritt angegebenen Pfad zu einer vollständigen Adresse zusammen. Der Schritt wählt die Methode (GET, POST, PUT, PATCH oder DELETE) und extrahiert Antwortfelder per JSONPath in eine benannte extract-Zuordnung.
soap.call baut das vollständige SOAP Envelope aus einer Vorlage, setzt den SOAPAction-Header und liest die Antwort per XPath aus. Dabei ignoriert local-name() Namensräume in der Antwort. Meldet die Antwort einen SOAP-Fehler (Fault), wertet WERKSPUR das als Fehler mit Status 502 und bricht die Aktion ab. Die Namen aus extract werden Teil des Schrittergebnisses. Ein späterer Schritt liest sie über ${stepN.feld}, wobei N die Position des rest.call- oder soap.call-Schritts im Ablauf ist.
Beide Schritte laufen in derselben Transaktion wie der Rest der Aktion. Planen Sie externe Aufrufe deshalb früh im Ablauf ein und halten Sie sie kurz. Bei rest.call gilt ein Aufruf als unumkehrbar, wenn seine Methode Daten verändert, also nicht GET ist. Bei soap.call gilt dies unabhängig von der aufgerufenen Operation.
Ein unumkehrbarer, nicht letzter Schritt benötigt ein compensate, das den Aufruf bei einem späteren Fehler fachlich ausgleicht. Das Kapitel Aktionen zeigt einen solchen Fall: Ein rest.call zum Zielsystem erp bucht einen Materialverbrauch ab. Sein compensate nimmt die Buchung zurück, falls ein nachfolgender Schritt scheitert.
amqp.publish verwendet base_url, username und das über auth.secret gelöste Passwort. Der Schritt bekommt zusätzlich exchange, routing_key und body. Er wartet auf die Bestätigung des Brokers und ist immer unumkehrbar. Ein eingehender AMQP-Listener ist kein Feld dieses Schritts und kein Feld des Zielsystems. Er referenziert nur den Zielsystemnamen und ergänzt Queue sowie Ereignistyp.
Beispiele
{
"name": "erp",
"kind": "rest",
"base_url": "http://host.docker.internal:9100",
"auth": {
"header": "",
"secret": ""
}
}Ein Zielsystem vom Typ rest mit einer Basis-URL und ohne Authentifizierung. Die gebündelte Adresse gehört nur zur lokalen Beispielumgebung und ist kein Vorbild für eine echte Anbindung. Die Aktion fertigmeldung ruft das Zielsystem mit rest.call auf.
{
"name": "broker",
"kind": "amqp",
"base_url": "amqp://broker.werk.local:5672/",
"username": "werkspur",
"auth": {
"header": "",
"secret": "broker-passwort"
}
}Ein Zielsystem vom Typ amqp mit username und auth.secret als Namens-Verweis auf das Secret broker-passwort. Der eigentliche Wert des Secrets liegt nicht im Zielsystem, sondern im Secret-Speicher.
{
"name": "erp-soap",
"kind": "soap",
"base_url": "https://erp.example.com/ws",
"auth": {
"header": "Authorization",
"secret": "erp-soap-token"
}
}Ein Zielsystem vom Typ soap. auth.header bestimmt den Namen des Auth-Headers, auth.secret den Namens-Verweis auf dessen Wert.
Fallstricke
- Das Secret muss zuerst existieren. Das in
auth.secretreferenzierte Secret muss existieren, bevor Sie es am Zielsystem nennen. Fehlt es beim Aufruf, sendet WERKSPUR keine Anfrage ohne den vorgesehenen Authentifizierungs-Header. Der Schritt bricht mit einem Fehler ab. Da die Aktion in einer Transaktion läuft, werden auch vorherige Datenbankänderungen zurückgerollt. - Die WSDL bleibt beim Ändern erhalten. Bearbeiten Sie ein SOAP-Zielsystem, bleibt die gespeicherte WSDL bestehen. Der Assistent schlägt beim Anlegen oder Ändern nie selbst ein
wsdl-Feld vor; das übernimmt allein der WSDL-Import im Editor. So bleibt die einmal eingelesene Operationsliste auch nach einer Auth-Änderung als Grundlage für den Assistenten erhalten, ohne dass Sie die WSDL erneut hochladen müssen. base_urlund Pfad teilen sich die Adresse. Die Basisadresse steht am Zielsystem, der Pfad am Kommando-Schritt selbst. Einrest.call-Schritt setzt beide zu einer vollständigen Adresse zusammen. Ändert sich nur der Pfad eines einzelnen Aufrufs, genügt es, den Kommando-Schritt anzupassen: Diebase_urlam Zielsystem bleibt für alle Schritte gültig, die dasselbe Zielsystem verwenden.- Ein AMQP-Zielsystem konsumiert noch keine Queue. Ausgehend verwendet eine Aktion
amqp.publish. Eingehend brauchen Sie zusätzlich einen API-gepflegten Listener mitdestination,queueundevent_type.FOUNDRY_AMQP_URLschaltet die eingehende Bridge nur ein; die tatsächlichen Verbindungsdaten stammen weiterhin aus dem Zielsystem.
Wie eine Aktion einen externen Schritt in ihren Ablauf einbindet, zeigt das Kapitel Aktionen. Eingehenden Queue-Konsum beschreibt AMQP-Listener. Wie ein Trigger auf das daraus entstehende Ereignis reagiert, erklärt Trigger. Eine protokollspezifische Diagnosefolge finden Sie unter Integration: Fehlersuche.