Perform HTTP request (with verbs GET, POST, PUT, PATCH) to HTTP endpoints via targets.
Specific connection configuration
The common configuration for connections in Connections > Targets applies here as well. Following are some specifics for HTTP connections:
Source format
Target format
A HTTP connection requires the protocol configuration target object to have an address
property.
This property has the following format: <http_verb>:<http_path>
The supported HTTP <http_verb>
values are:
- GET
- POST
- PUT
- PATCH
The specified <http_path>
contains the path - including optionally potential query parameters - to be appended to the
configured uri
of the connection.
The body of the HTTP request is either the outgoing Ditto Protocol message (e.g. an event) or - if a payload mapping was specified in the connection - a transformed body.
The target address may contain placeholders; see placeholders section for more information.
The target may define a header mapping specifying which additional HTTP headers to send along with the performed HTTP requests.
Further, "topics"
is a list of strings, each list entry representing a subscription of
Ditto protocol topics, see
target topics and filtering for more information on that.
Outbound messages are published to the configured target address if one of the subjects in "authorizationContext"
has READ permission on the thing, which is associated with a message.
{
"address": "<http_verb>:<http_path>",
"topics": [
"_/_/things/twin/events",
"_/_/things/live/messages"
],
"authorizationContext": ["ditto:outbound-auth-subject"],
"headerMapping": {
"content-type": "application/json"
}
}
Target header mapping
HTTP 1.1 connections supports specific header mapping.
The following header have a special meaning in that the values are applied directly to the published message:
http.query
: sets the value of this header as query parameterhttp.path
: sets the value of this header as the path of the HTTP request
Target acknowledgement handling
For HTTP targets, whenever a message is published to the HTTP endpoint, you have two different options in order to acknowledge receiving the message:
Explicitly responding with Ditto Protocol acknowledgement message
Whenever an HTTP endpoint, which received a message
requesting acknowledgements,
responds with a Ditto Protocol Acknowledgement and sets the
Content-Type
header of the HTTP response to application/vnd.eclipse.ditto+json
, this received message is treated
as custom acknowledgement.
This however is only the case if no automatically issued acknowledgement label was configured for that target (see section below). If such an issued acknowledgement label was configured, this one always gets issued instead of a custom sent back Ditto Protocol Acknowledgement.
Implicitly create acknowledgement from HTTP response
When for the target an
automatically issued acknowledgement label was configured
and the HTTP response was not a Ditto Protocol message (with Content-Type header application/vnd.eclipse.ditto+json
),
an acknowledgement is produced automatically in the following way:
The HTTP response and following HTTP response information is mapped to the automatically created acknowledgement:
Acknowledgement.headers
: the HTTP response headers are added.Acknowledgement.status
: the HTTP response status code is used.Acknowledgement.value
: the HTTP response body is used - if the response body was ofcontent-type: application/json
, the JSON is inlined into the acknowledgement, otherwise the payload is added as JSON string.
Responding to messages
For live messages that are published via an HTTP target you have two different options to respond to that message:
Explicitly responding with Ditto Protocol message response
Whenever an HTTP endpoint, which received a live message,
responds with a Ditto Protocol Message Response
and sets the Content-Type
header of the HTTP response to application/vnd.eclipse.ditto+json
, this received message
is treated as custom live message response.
In this case, the correlation-id
, thing-id
and potentially feature-id
of the response have to match the
message properties to respond to.
Implicitly responding via HTTP response
When for the target an
automatically issued acknowledgement label with the label
live-response
was configured and the HTTP response was not a Ditto Protocol message
(with Content-Type header application/vnd.eclipse.ditto+json
), a message response is produced automatically in the
following way:
The HTTP response and following HTTP response information is mapped to the automatically created message response:
Message.headers
: the HTTP response headers are added.Message.status
: the HTTP response status code is used.Message.value
: the HTTP response body is used - if the response body was ofcontent-type: application/json
, the JSON is inlined into the acknowledgement, otherwise the payload is added as JSON string.
Specific configuration properties
The specific configuration properties contain the following optional keys:
parallelism
(optional): Configures how many parallel requests per connection to perform, each takes one outgoing TCP connection. Default (if not provided): 1omitRequestBody
(optional): Configures for which HTTP methods, provided as a comma separated list, the request body is omitted for requests made via this connection. Default (if not provided):GET,DELETE
. Leave empty to always send the request body.
Establishing connecting to an HTTP endpoint
Ditto’s Connectivity service is responsible for creating new and managing existing connections.
This can be done dynamically at runtime without the need to restart any microservice using a Ditto DevOps command.
Example connection configuration to create a new HTTP connection in order to make request to an HTTP endpoint:
{
"connection": {
"id": "http-example-connection-123",
"connectionType": "http-push",
"connectionStatus": "open",
"failoverEnabled": true,
"uri": "http://user:password@localhost:80",
"specificConfig": {
"parallelism": "2"
},
"sources": [],
"targets": [
{
"address": "PUT:/api/2/some-entity/{{ thing:id }}",
"topics": [
"_/_/things/twin/events"
],
"authorizationContext": ["ditto:outbound-auth-subject", "..."],
"headerMapping": {
"content-type": "{{ header:content-type }}",
"api-key": "this-is-a-secret-api-key-to-send-along"
}
}
]
}
}
Client-certificate authentication
Ditto supports certificate-based authentication for HTTP connections. Consult Certificates for Transport Layer Security for how to set it up.
Here is an example HTTP connection that checks the server certificate and authenticates by a client certificate.
{
"connection": {
"id": "http-example-connection-123",
"connectionType": "http-push",
"connectionStatus": "open",
"failoverEnabled": true,
"uri": "https://localhost:443",
"validateCertificates": true,
"ca": "-----BEGIN CERTIFICATE-----\n<localhost certificate>\n-----END CERTIFICATE-----",
"credentials": {
"type": "client-cert",
"cert": "-----BEGIN CERTIFICATE-----\n<signed client certificate>\n-----END CERTIFICATE-----",
"key": "-----BEGIN PRIVATE KEY-----\n<client private key>\n-----END PRIVATE KEY-----"
},
"specificConfig": {
"parallelism": "2"
},
"sources": [],
"targets": [
{
"address": "PUT:/api/2/some-entity/{{ thing:id }}",
"topics": [
"_/_/things/twin/events"
],
"authorizationContext": ["ditto:outbound-auth-subject", "..."],
"headerMapping": {
"content-type": "{{ header:content-type }}",
"api-key": "this-is-a-secret-api-key-to-send-along"
}
}
]
}
}
HMAC request signing
Ditto supports HMAC request signing for HTTP push connections. Find detailed information on this in Connectivity API > HMAC request signing.
OAuth2 client credentials flow
HTTP push connections can authenticate themselves via OAuth2 client credentials flow as described in section 4.4 of RFC-6749. To configure OAuth2 credentials:
- Set
type
tooauth-client-credentials
- Set
tokenEndpoint
to the URI of the access token request endpoint - Set
clientId
to the client ID to include in access token requests - Set
clientSecret
to the client secret to include in access token requests - Set
requestedScopes
to the scopes to request in access token requests
This is an example connection with OAuth2 credentials.
{
"connection": {
"id": "http-example-connection-124",
"connectionType": "http-push",
"connectionStatus": "open",
"uri": "https://localhost:443/event-publication",
"credentials": {
"type": "oauth-client-credentials",
"tokenEndpoint": "https://localhost:443/oauth2/token",
"clientId": "my-client-id",
"clientSecret": "my-client-secret",
"requestedScopes": "user-scope-1 role-scope-2"
},
...
}
Each HTTP request to https://localhost:443/event-publication
includes a bearer token issued by
https://localhost:443/oauth2/token
. The HTTP connection will obtain a new token before the old token expires
according to a configured max-clock-skew
. To prevent looping access token requests, each token is used once even if
the token endpoint responds with expired tokens. Rejected or malformed access token responses are considered
misconfiguration errors.
It is possible to configure max-clock-skew
and whether to enforce HTTPS for token endpoints in
connectivity-extension.conf
or by environment variables.
ditto {
connectivity {
connection {
http-push {
oauth2 {
# Maximum clock skew of OAuth2 token endpoints.
# Access tokens are refreshed this long before expiration.
max-clock-skew = 60s
max-clock-skew = ${?CONNECTIVITY_HTTP_OAUTH2_MAX_CLOCK_SKEW}
# Whether to enforce HTTPS for OAuth2 token endpoints.
# Should be `true` for production environments
# in order not to transmit client secrets in plain text.
enforce-https = true
enforce-https = ${?CONNECTIVITY_HTTP_OAUTH2_ENFORCE_HTTPS}
}
}
}
}
}