Call Web Service

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

Beschreibung

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.

Datenquellen

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.

Datenziel

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.

SQL Abfrage (Inhalt der Transformation)

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

Attribute

Truncate Before

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.

WS Request

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.

Query for Loop

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.

Fail on Error

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.

Konfiguration eines webservies im keyfile

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.

Parameter im keyfile

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.

Beispiele

Laden der Wechselkurse in eine strukturierte Tabelle

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