You extend Ditto by implementing custom DittoExtensionPoint interfaces and loading them into the service via Pekko’s classloader.
DittoExtensionPoint interface, configure it in a <service>-extension.conf file, and add the JAR to /opt/ditto/extensions in the Docker container.Overview
Ditto provides extension points throughout its codebase, marked by interfaces that extend DittoExtensionPoint. You can replace the default behavior at these points by providing your own implementation.
How it works
Creating an extension
Your implementation needs a public constructor that accepts an ActorSystem and Config parameter, which Pekko’s classloader uses for reflection-based instantiation:
public CustomExtension(final ActorSystem actorSystem, final Config config) {}
Configuring an extension
Tell Pekko’s classloader which implementation to use by adding the extension’s CONFIG_KEY to:
- A
<service-name>-extension.conffile for service-specific extensions - The
reference.conffor a global scope
Each extension configuration has two parts:
extension-class: The fully qualified class name of your implementationextension-config: Custom configuration for the extension (optional)
ditto.extensions.signal-enrichment-provider {
extension-class = org.eclipse.ditto.gateway.service.endpoints.utils.DefaultGatewaySignalEnrichmentProvider
extension-config = {
cache {
enabled = true
maximum-size = 20000
expire-after-create = 2m
}
}
}
If your extension needs no custom configuration, use the shorthand form:
ditto.extensions.signal-enrichment-provider = org.eclipse.ditto.gateway.service.endpoints.utils.DefaultGatewaySignalEnrichmentProvider
Configuration
Adjusting service configuration
For simple configuration changes, use system properties. For extensive changes, create a HOCON file named <ditto-service-name>-extension.conf and place it in the Docker container’s working directory:
| Service | Extension config path |
|---|---|
| Policies | /opt/ditto/policies-extension.conf |
| Things | /opt/ditto/things-extension.conf |
| Search | /opt/ditto/search-extension.conf |
| Connectivity | /opt/ditto/connectivity-extension.conf |
| Gateway | /opt/ditto/gateway-extension.conf |
These files can contain any configuration from the service config files.
For example, the gateway.conf contains the following health-check configuration:
ditto {
gateway {
health-check {
cluster-roles = {
enabled = true
enabled = ${?HEALTH_CHECK_ROLES_ENABLED}
expected = [
"policies",
"things",
"search",
"gateway",
"connectivity"
]
}
}
}
}
To remove the “connectivity” role from the health check (e.g. when not starting ditto-connectivity
at all), create a gateway-extension.conf with:
ditto.gateway.health-check.cluster-roles = {
expected = [
"policies",
"things",
"search",
"gateway"
]
}
Then mount the file into the container at /opt/ditto/gateway-extension.conf.
Adding JARs to the classpath
Ditto Docker images automatically add all JARs from these directories to the classpath:
/opt/ditto/opt/ditto/extensions
Build your extension as a JAR (including extension classes and config files) and place it in the extensions directory.
Examples
Custom API routes
- Create a new implementation of
CustomApiRoutesProvider, overriding theunauthorized(*)andauthorized(*)functions to return custom HTTP API routes. - Build the project into a
gateway-extension.jar. - Add the JAR to the container:
docker cp gateway-extension.jar container_id:/opt/ditto/extensions/ - Create a
gateway-extension.conf:ditto.extensions.custom-api-routes-provider = org.company.project.gateway.service.endpoints.utils.MyCustomApiRoutesProvider - Add the config to the container:
docker cp gateway-extension.conf container_id:/opt/ditto/
Alternatively, mount both files via docker-compose:
connectivity:
image: docker.io/eclipse/ditto-gateway:${DITTO_VERSION:-latest}
environment:
- TZ=Europe/Berlin
- JAVA_TOOL_OPTIONS=-Dlogback.configurationFile=/opt/ditto/logback.xml
volumes:
- ./gateway-extension.conf:/opt/ditto/gateway-extension.conf
- ./logback.xml:/opt/ditto/logback.xml
- ./gateway-extension.jar:/opt/ditto/extensions/gateway-extension.jar