The "Call Web Service" module reads data from a web service and writes it to a table in the target database. The SQL web query and conversion of the result are defined by the datasqill developer via the GUI.
| Name | Meaning |
|---|---|
| Module | Call Web Service |
| Module Class | DsModWebServiceClient |
| Type | Java |
| Purpose | Transfer data between a web service and a database |
| Transformation Code | SQL query on the web service result |
| Sources | Web request (POST) or URL query (GET) |
| Targets | Tables in the database |
The "Call Web Service" module sends a request (or a query in the URL) to a web service and makes the result returned by the web server available for an SQL query that processes the response. The result of the SQL query is written to the target table.
Unlike modules that operate within a database, this module reads data from the web service and writes it to the target database.
The following simple example shows how to load exchange rates between the Euro and US$, British Pound, and Japanese Yen from the European Central Bank as of 15 May 2009. The query is specified in the URL.
The URL in the object looks like this:
M.USD+GBP+JPY.EUR.SP00.A?updatedAfter=2009-05-15T14:15:00
Now the SQL query used (which does not further interpret the data):
SELECT r.ws_response
FROM ${ws_response} r
The variable ${ws_response} is replaced by the module with a subquery that returns 3 columns. See below.
If the target schema is "datasqill" and the target table is "response", the module generates the following SQL for inserting into the target database:
INSERT INTO datasqill.response (ws_response) VALUES(?)
As can be seen in the example, the column names of the target table must be specified as aliases when the source columns have different names.
The source of the module is a web service object. For GET queries, the query parameters must be specified in the URL. Variables from the Loop Query (if specified) can be used in the URL.
For SOAP queries, the SOAPAction is stored in the source object.
The web service used must be connected to the module input in the datasqill graphical data model via the datasqill GUI.
The target of the module is a single table. The datasqill runtime user must have write rights for this table.
The target table must be connected to the module output in the datasqill GUI in the graphical data model.
In the specified query, the variable ${ws_response} is replaced by a (database-dependent) subquery. Example for Postgres:
(SELECT a ws_request, b ws_response, c http_code)
Where a is replaced with the sent request, b with the received result, and c with the status code from the web call.
The effective SQL looks like this for the example above:
SELECT r.ws_response
FROM (SELECT a ws_request, b ws_response, c http_code) r
A select statement can be specified here. The query is executed in the target database. The columns returned by the Loop Query can be used as variables in the main query and in the URL. The web service is called once per row in the Loop Query. Loop queries with large result sets can significantly increase runtime.
For POST web service calls, the request to be transmitted is specified here. The format corresponds to what the web service expects (URL-encoded, JSON, XML, ...). Variables from the Loop Query (if specified) can be used in the request.
"Request header" allows the definition of header fields to be sent with the web service call. The definition is done with a simple JSON:
{
"header1": "value1",
"header2": "value2
}
Variables from the Loop query can be used to replace header keys and values.
When the boolean attribute Truncate Before is enabled, the table is completely emptied beforehand. If the target database offers a datasqill trigger for TRUNCATE TABLE, it will be used. Otherwise, all rows are deleted with the DELETE command.
By default, the run fails when the web service returns an error (status >= 300). This can be disabled. In that case, the status code should be stored for later consideration.
The base URL is stored in the keyfile, as well as optional additional parameters for authentication (if necessary).
A connection must be set up to access the web service. Assuming this connection has ID 11, the entry in the keyfile looks like this:
SQTS_DB_11 https://sdw-wsrest.ecb.europa.eu/service/data/EXR||method=GET:encoding=UTF-8|
A keyfile consists of 4 sections separated by the pipe "|" symbol. To use a pipe symbol within a field, it must be escaped with a backslash.
| Position | Meaning | Note |
|---|---|---|
| 1 | URL | Base URL to the web service |
| 2 | User | Currently not used. In implementations before version 4.01, the method was stored here |
| 3 | Parameters | See list below. In implementations before version 4.01, the character set used was stored here |
| 4 | Password | The BASIC encrypted user and password pair is stored here |
In future versions, the user and password will be used for Basic authentication.
Parameters are always name/value pairs (Name=Value). Multiple parameters are separated by a colon.
To use a colon within a parameter name or value, it must be escaped with a backslash. This should be considered especially when specifying URLs.
The following parameters are available from version 4.01:
| Name | Meaning | Default | Note |
|---|---|---|---|
| method | Method | POST | Default method for calling the web service |
| encoding | Charset | UTF-8 | Charset of posted data or expected result when using GET |
| media_type | Format | text/xml | Format of the request to be sent, or expected response when using GET |
| https.proxyHost | Proxy Host | none | HTTPS proxy address |
| https.proxyPort | Proxy Port | none | HTTPS proxy port |
| AuthenticationUrl | Authentication Server URL | none | Server address to obtain a token |
| AuthenticationMethod | Authentication Method | none | POST or GET |
| AuthenticationRequest | Authentication Request Content | none | For POST, this text is sent to obtain a token |
| AuthenticationRequestContentType | Media Type | none | Media type to obtain a token |
| AuthenticationTokenPattern | Regular Expression | none | Regular expression to extract the token from the response |
| loopDelay | Delay | none | Minimum interval in milliseconds between two calls |
| headerList | Header fields | none | List of header parameters as key-value pairs, e.g. headerList={clientid=xyz,apikey=very-secret} |
When an AuthenticationUrl is specified, AuthenticationMethod, AuthenticationRequest, and AuthenticationTokenPattern must also be specified.
In this case, a token is requested from the specified server and the token is sent as BEARER with all subsequent web requests. If Basic authentication is also specified, it is used for authentication when requesting the token.
If no AuthenticationUrl was specified but Basic authentication was, then Basic authentication is sent with each service call.
If the loopDelay parameter is present and a valid number, it ensures the minimum interval between two successive calls. If a subsequent call would come too close to the previous one, the parameter is used to calculate a wait time after which another call is allowed.
If
waitTime = lastInvocationTime + loopDelay - currentInvocationTime
is greater than 0, the module waits for that time.
In the example above, the exchange rates are loaded such that the response is stored as text in the database.
In this example, the data is to be loaded in structured form into an Oracle database.
Since the ECB allows only limited sizes in the response, the exchange rates for Dollar, Japanese Yen, and British Pound are loaded with separate service calls.
The target table is created as follows:
CREATE TABLE datasqill.wechselkurse (
waehrung VARCHAR2(10) NOT NULL
, datum DATE NOT NULL
, wechselkurs NUMBER
, status CHAR
);
A Loop Query selects the desired currencies:
SELECT 'GBP' waehrung FROM DUAL UNION ALL
SELECT 'JPY' waehrung FROM DUAL UNION ALL
SELECT 'USD' waehrung FROM DUAL
The specified URL of the web service query contains the variable waehrung.
M.${waehrung}.EUR.SP00.A
The result of the web request looks like this (first two entries):
<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>
The following query takes the result of the query and extracts the desired information from the XML using Oracle syntax:
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