Das Modul "Call Web Service" überträgt Daten von einem Webservice und schreibt sie in eine Tabelle in der Zieldatenbank. Die SQL-Webabfrage und die Kovertierung des Ergebnisses wird vom datasqill Entwickler über die GUI definiert.
Name | Bedeutung |
---|---|
Modul | Call Web Service |
Modulklasse | DsModWebServiceClient |
Typ | Java |
Zweck | Übertragen der Daten zwischen einem Webservice und einer Datenbank |
Transformationscode | SQL Abfrage auf das Ergebnis vom Web Service |
Quellen | Web request (POST) oder URL-Abragen (GET) |
Ziele | Tabellen in der Datenbank |
Das Modul "Call Web Service" schickt einen Request (bzw. eine Anfrage in der URL) an einen Webservice und stellt das vom Webserver zurück gelieferte Ergebnis einer SQL-Abfrage zur Verfügung, die die Antwort überarbeitet. Das Ergebnis der SQL Abfrage wird in die Zieltabelle geschrieben.
Im Gegensatz zu Modulen die innerhalb einer Datenbank operieren, werden in diesem Modul die Daten vom Webservice gelesen und in die Zieldatenbank geschrieben.
Das folgende einfache Beispiel zeigt, wie man mit Hilfe des Moduls von der Europäischen Zentralbank die Wechselkurse zwischen Euro und US$, Britischem Pfund und Japanasiche Yen ab dem 15.05.2009 lädt. Die Abfrage wird in der URL mit angegeben.
Die URL im Objekt sieht folgendermaßen aus:
M.USD+GBP+JPY.EUR.SP00.A?updatedAfter=2009-05-15T14:15:00
Nun die verwendete SQL-Abfrage (die die Daten nicht weiter interpretiert):
SELECT r.ws_response
FROM ${ws_response} r
Die Variable ${ws_response} wird vom Modul mit einer Unterabfrage ersetzt, die 3 Spalten liefert. Siehe weiter unten.
Heißt das Zielschema "datasqill" und die Zieltabelle "response", generiert das Modul für das Einfügen in die Zieldatenbank folgendes SQL:
INSERT INTO datasqill.response (ws_response) VALUES(?)
Wie im Beispiel zu erkennen, müssen die Spaltennamen der Zieltabelle als Aliase angegeben werden, wenn die Quellspalten anders heißen.
Die Quelle des Moduls ist ein Webservice Objekt. Bei GET Abfragen, müssen in der angegebenen URL die Abfrageparameter mit angegeben werden. In der URL können Variablen aus der Loop Query (falls angegeben) verwendet werden.
Wenn es sich um eine SOAP-Abfrage handelt, wird die SOAPAction im Quellobject hinterlegt.
Der verwendete Webservice muss über die datasqill GUI im grafischen Datenmodell mit dem Eingang des Moduls verbunden werden.
Das Ziel des Moduls ist eine einzelne Tabelle. Für diese muss der datasqill Laufzeit-Benutzer Schreibrechte besitzen.
Die Zieltabelle muss mit Hilfe der datasqill GUI im grafischen Datenmodell mit dem Ausgang des Moduls verbunden werden.
In der angegebenen Abfrage wird die Variable ${ws_response} durch eine (datenbankabhängige) Unterabfrage ersetzt. Beispiel für Postgres:
(SELECT a ws_request, b ws_response, c http_code)
Wobei a mit dem versendeten Request, b mit dem erhaltenen Ergebnis und c mit dem Status Code vom Webaufruf ersetzt ist.
Das effektive SQL sieht für das obige Beispiel folgendermaßen aus:
SELECT r.ws_response
FROM (SELECT a ws_request, b ws_response, c http_code) r
Wenn das boolsche Attribut Truncate Before aktiviert ist, dann wird die Tabelle vorher komplett geleert. Wenn die Zieldatenbank einen datasqill Trigger für TRUNCATE TABLE anbietet, wird dieser verwendet. Ansonsten werden alle Zeilen mit dem DELETE Befehl gelöscht.
Bei POST Webservice-Aufrufen wird hier der zu übertragende Request angegeben. Das Format entspricht dem, was der Webservice erwartet (URL-encoded, JSON, XML, ...). Im Request können Variablen aus der Loop Query (falls angegeben) verwendet werden.
Hier kann ein Select Statement angegeben werden. Die Query wird in der Zieldatenbank ausgeführt. Die Spalten, die von der Loop Query zurückkehren, können als Variablen in der Haupt-Query und in der URL verwendet werden. Pro Zeile in der Loop Query wird einmal der Webservice aufgerufen. Loop Queries mit großen Ergebnismengen können die Laufzeit stark erhöhen.
Per default führt der Job zu einem Fehler, wenn der Webservice einen Fehler (Status >= 300) vom Webservice zurückliefert. Dieses kann man abschalten. In dem Fall sollte man sich den Statuscode mit speichern, um es später zu berücksichtigen.
Im keyfile wird die Basis-URL hintelegt, sowie optional weitere Parameter für die Authentifizierung (falls notwendig).
Für den Zugriff auf den Webservice muss man eine Connection einrichten. In der Annahme, dass diese Connection die ID 11 bekommen hat, so sieht der Eintrag im keyfile folgendermaßen aus:
SQTS_DB_11 https://sdw-wsrest.ecb.europa.eu/service/data/EXR||method=GET:encoding=UTF-8|
Ein keyfile besteht aus 4 Sektionen, die mit dem Pipe "|" Symbol getrennt werden. Möchte man ein Pipe Symbol innerhalb eines Feldes verwenden, muss man es mit dem Backslash escapen.
Position | Bedeutung | Bemerkung |
---|---|---|
1 | URL | Basis URL zum Webservice |
2 | User | Derzeit nicht verwendet. In Implementierungen vor Version 4.01 wurde hier die Methode hinterlegt |
3 | Parameter | Siehe Liste unten. In Implementierungen vor Version 4.01 wurde hier der verwendete Zeichensatz hinterlegt |
4 | Kennwort | Hier wird das BASIC encripted User und Passwort paar hinterlegt |
In zukünftigen Versionen wird der User und das Kennwort zur Bildung der Basic Authentifizierung verwendet.
Die Parameter sind immer Name/Wert Paare (Name=Wert). Mehrere Parameter werden duch einen Doppelpunkt getrennt.
Möchte man einen Doppelpunkt innerhalb eines Parameternames -oder wert verwenden, muss man ihn mit dem Backslash escapen. Dieses ist insbesondere bei der Angabe von URLs zu bedenken.
Die folgenden Parameter werden ab Version 4.01 angeboten:
Name | Bedeutung | Default | Bemerkung |
---|---|---|---|
method | Methode | POST | Default Methode mit dem der Webservice aufgerufen wird |
encoding | Charcterset | UTF-8 | Charcterset of posted data or expected result when using GET |
media_type | Format | text/xml | Format vom zu sendenden Request, bzw. der erwarteten Antwort beim GET |
https.proxyHost | Proxy Host | none | Https Proxyadresse |
https.proxyPort | Proxy Port | none | Https Proxyport |
AuthenticationUrl | URL Authentifizierungs Server | none | Server Adresse um einen Token zu erhalten |
AuthenticationMethod | Authentifizierungs Methode | none | POST oder GET |
AuthenticationRequest | Authentifizierungs Request Inhalt | none | Bei Post wird dieser Text gesendet, um einen Token zu erhalten |
AuthenticationRequestContentType | Media Type | none | Media Type um einen Token zu erhalten |
AuthenticationTokenPattern | regular Expression | none | regular Expression um aus dem Response den Token zu extrahieren |
loopDelay | Delay | none | Mindestabstand in Millisekunden zwischen zwei Aufrufen |
Wenn eine AuthenticationUrl angegeben ist, dann müssen auch AuthenticationMethod, AuthenticationRequest und AuthenticationTokenPattern angegeben werden.
Wenn eine AuthenticationUrl angegeben wurde, dann wird ein Token vom angegebenen Server angefragt und das Token wird als BEARER bei allen weiteren Webanfragen mitgesendet. Ist zusätzlich eine BASIC Authentifizierung angegeben, dann wird diese bei der Tokenabfrage verwendet.
Wenn keine AuthenticationUrl angegeben wurde, aber eine BASIC Authentifizierung, dann wird die BASIC Authentifizierung bei jedem Serviceaufruf mit gegeben.
Ist der Parameter loopDelay vorhanden und eine valide Zahl, so wird damit der minimale Abstand zwischen zwei aufeinanderfolgenden Aufrufen sichergestellt. Käme ein nachfolgender Aufruf zu nah am vorherigen Aufruf, wird der Parameter verwendet, um eine Wartezeit zu berechnen, nach der wieder ein Aufruf erlaubt ist.
Ist
waitTime = lastInvocationTime + loopDelay - currentInvocationTime
größer als 0, so wird für diese Zeit gewartet.
Im obigen Beispiel werden die Wechselkurse derart geladen, dass die Antwort als Text in der Datenbank gespeichert wurden.
In diesem Beispiel sollen die Daten strukturiert in eine Oracle Datenbank geladen werden.
Da die EZB nur begrenzte Größen in der Antwort zulässt, werden die Wechselkurse für Dollar, Japanischen Yen und britischem Pfund mit einzeln Serviceaufrufen geladen.
Die Zieltabelle wird folgendermaßen erstellt:
CREATE TABLE datasqill.wechselkurse (
waehrung VARCHAR2(10) NOT NULL
, datum DATE NOT NULL
, wechselkurs NUMBER
, status CHAR
);
Eine Loop Query selektiert die gewünschten Währungen:
SELECT 'GBP' waehrung FROM DUAL UNION ALL
SELECT 'JPY' waehrung FROM DUAL UNION ALL
SELECT 'USD' waehrung FROM DUAL
Die angegebene URL der Webserviceabfrage enthält die Variable waehrung.
M.${waehrung}.EUR.SP00.A
Das Ergebnis der Webanfrage sieht folgendermaßen aus (ersten zwei Einträge):
<generic:Obs
xmlns:generic="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic">
<generic:ObsDimension value="1999-01"/>
<generic:ObsValue value="0.7029125"/>
<generic:Attributes>
<generic:Value id="OBS_STATUS" value="A"/>
<generic:Value id="OBS_CONF" value="F"/>
</generic:Attributes>
</generic:Obs>
<generic:Obs
xmlns:generic="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic">
<generic:ObsDimension value="1999-02"/>
<generic:ObsValue value="0.688505"/>
<generic:Attributes>
<generic:Value id="OBS_STATUS" value="A"/>
<generic:Value id="OBS_CONF" value="F"/>
</generic:Attributes>
</generic:Obs>
Die folgende Abfrage nimmt das Ergebnis der Abfrage und extrahiert mit Oracle Syntax die gewünschten Informationen aus dem XML:
SELECT ab.currency waehrung
, TO_DATE(obs.obs_date, 'YYYY-MM') datum
, CASE WHEN SUBSTR(obs.obs_status,1 ,1) = 'A'
THEN TO_NUMBER(obs.obs_value, 'FM9999.99999999999999999')
END wechselkurs
, SUBSTR(obs.obs_status,1 ,1) status
FROM ${ws_response} r
, XMLTABLE(XMLNamespaces ( 'http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message' AS "message"
, 'http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common' AS "common"
, 'http://www.w3.org/2001/XMLSchema-instance' AS "xsi"
, 'http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic' AS "generic"
),
'$d/message:GenericData/message:DataSet/generic:Series'
PASSING XMLTYPE(r.ws_response) AS "d"
COLUMNS dataset VARCHAR2(255 CHAR) PATH '@action'
, series XMLTYPE PATH '.'
) ar
, XMLTABLE(XMLNamespaces ('http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic' AS "generic")
,'$e/generic:Series' PASSING ar.series AS "e"
COLUMNS obs XMLTYPE PATH 'generic:Obs'
, attributes XMLTYPE PATH 'generic:Attributes'
, currency VARCHAR2(255 CHAR) PATH 'generic:Attributes/generic:Value[@id="UNIT"]/@value'
) ab
, XMLTABLE(XMLNamespaces ('http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic' AS "generic")
,'$f/generic:Obs' PASSING ab.obs AS "f"
COLUMNS obs_date VARCHAR2(255 CHAR) PATH 'generic:ObsDimension/@value'
, obs_value VARCHAR2(255 CHAR) PATH 'generic:ObsValue/@value'
, obs_status VARCHAR2(255 CHAR) PATH 'generic:Attributes/generic:Value[@id="OBS_STATUS"]/@value'
) obs