Application-Defined Metadata#
Added in version 2.2.0.
Starting in 2.2, ESS adds support for application-defined metadata/properties associated with a request; specifically, ESS supports the use of the baggage HTTP header by applications. ESS further expands on this support by providing configuration to add non-baggage request headers to the baggage for propagation within its system.
With ESS’ support application-defined metadata/properties, application-defined metadata can be:
Included in log messages;
Included in audit events;
Returned as response headers.
Configuration#
To support this feature, ESS provides the following configuration options:
Note
See Manage Application-Defined Metadata Propagation to configure using kustomization.
|
|
|
|
|
|
|
|
|
Considerations#
Baggage Header#
ESS uses the baggage to support application-defined metadata/property.
However, client requests do not need to include a baggage header. If
clients send only non-baggage request headers for application-defined
properties (as determined by
INRUPT_REQUEST_METADATA_PROPAGATOR_HEADER_ALLOW
), ESS creates a
baggage for propagation within its system. However, if a baggage
request header exists, ESS adds the non-baggage requests headers (if
any, as determined by ESS configuration) to the baggage, and propagates
the enhanced baggage. If a property is sent both as a header and as an
entry in the baggage, ESS’ default behavior is to not update the
baggage entry. See Duplicate Property Definition for more
information.
Duplicate Property Definition#
The INRUPT_REQUEST_METADATA_PROPAGATOR_HEADER_ALLOW
configuration
adds headers to the request’s baggage for propagation within ESS.
If a property is sent both as a header and as an entry in the baggage,
ESS’ default behavior is to not replace the baggage entry with the
header. To override this behavior and update the baggage entry with the
header value, you can set
INRUPT_REQUEST_METADATA_PROPAGATOR_HEADER_OVERRIDES
option to true.
Property Definition by Internal Requests#
To process a client request, ESS may make various internal HTTP requests to its microservices. Underlying technologies (such as Kubernetes Ingress) may modify the internal HTTP request header that may affect the metadata values that are included in logs/audit events/response headers.
For example, consider an ESS deployment that uses the Ingress-NGINX
controller. Ingress-NGINX itself adds an x-request-id
header to its
requests. If the INRUPT_REQUEST_METADATA_PROPAGATOR_HEADER_ALLOW
value includes the x-request-id
header:
Scenario 1: Duplicate Property Definition
An application’s request includes an
x-request-id
header.ESS adds the
x-request-id
(and its value) as an entry to the baggage (perINRUPT_REQUEST_METADATA_PROPAGATOR_HEADER_ALLOW
).Then, Ingress-NGINX would send requests with:
the aforementioned baggage that contains the
x-request-id
entry andan
x-request-id
header set by Ingress-NGINX.
ESS’ default behavior is to leave the baggage
x-request-id
entry unchanged. To have ESS override and update the baggage entry with the header value, setINRUPT_REQUEST_METADATA_PROPAGATOR_HEADER_OVERRIDES
totrue
.Scenario 2: Property Only Defined by Internal Technology
An application’s request does not include an
x-request-id
header or a baggage header with anx-request-id
entry.Then, Ingress-NGINX sends internal requests with the
x-request-id
header. ESS adds thisx-request-id
header from Ingress-NGINX to the baggage for propagation within its system.
Inrupt Client Libraries Header Support#
Inrupt’s client libraries (Java and JavaScript) support HTTP header handling:
Tip
Use ISO-8859-1 for the header values.
To specify headers on all client requests, you can set the headers to the SolidClient/SolidSyncClient. For example:
import com.inrupt.client.Headers;
import com.inrupt.client.solid.SolidClient;
// ...
// ...
final SolidClient mySolidClient = SolidClient.getClientBuilder()
.headers(Headers.of(Map.of("x-request-id", List.of("7492595229158059")))).build()
.session(session);
client.read(URI.create(resourceURL), MyExtendedRDF.class)
.thenAccept(response -> {
List<String> responseHeaderValues = response.getHeaders().allValues("x-request-id");
// ...
});
To specify headers per request, you can set the headers at the request operation level. For example:
import com.inrupt.client.Headers;
import com.inrupt.client.solid.SolidClient;
// ...
// ...
final SolidClient mySolidClient = SolidClient.getClient().session(session);
Headers myHeaders = Headers.of(Map.of("x-request-id", List.of("7492595229158059")));
mySolidClient.read(URI.create(resourceURL), myHeaders, Expense.class)
.thenAccept(response -> {
List<String> responseHeaderValues = response.getHeaders().allValues("x-request-id");
// ...
});
import { Session } from "@inrupt/solid-client-authn-browser";
import { getSolidDataset } from "@inrupt/solid-client";
const session = new Session();
// ... log the session in.
const customizeHeaders = (
customizedFetch,
requestHeaders,
bindResponseHeaders,
) => {
return async (info, init) => {
const response = await customizedFetch(info, {
...init,
headers: {
...init?.headers,
...requestHeaders,
},
});
bindResponseHeaders(response.headers);
return response;
};
};
let responseHeaders = new Headers();
const customFetch = customizeHeaders(
session.fetch,
{"x-request-id": "7492595229158059"},
(headers) => {
// Bind the headers to the current scope.
responseHeaders = headers;
},
);
await getSolidDataset(
"https://storage.example.com/7865026e-5450/some-resource",
{ fetch: customFetch }
);
console.log(responseHeaders.get("x-request-id"));
See also:
Limits and Restrictions#
Use ISO-8859-1 for the header values.
Per https://www.w3.org/TR/baggage/#limits, ESS limits the baggage string to a maximum of 8192 bytes and to a maximum of 64 list members.