This guide explains how to create a custom extension (Adapter, Gate, Converter, Access and Usage Control, or Discovery) for the Dataspace Consumer Framework.
Start by creating a new Maven project and use the provided template-pom.xml as your base pom.xml.
Open the pom.xml and replace the following placeholders:
<groupId>: Replaceyour-group-idwith your organization's group ID (e.g.,com.example)<artifactId>: Replaceyour-artifact-idwith your plugin's artifact ID (e.g.,my-custom-adapter)<name>: Replaceyour-project-namewith a descriptive name (e.g.,My Custom Adapter Plugin)<plugin.id>: Replaceyour-plugin-id/your-artifact-idwith a unique plugin identifier, could be the artifactid (e.g.,com.example/my-custom-adapter)<plugin.provider>: Replaceyour-organizationwith your organization name (e.g.,Example Corp)
Create a new Java class in src/main/java and implement one of the interfaces. Annotate it with @Extension so PF4J can discover it.
Example: Creating a Custom Adapter
package com.example.adapter;
import de.fraunhofer.iosb.ilt.dataspace_consumer.api.adapter.Adapter;
import de.fraunhofer.iosb.ilt.dataspace_consumer.api.adapter.AdapterPayloadType;
import de.fraunhofer.iosb.ilt.dataspace_consumer.api.adapter.AdapterRequest;
import org.pf4j.Extension;
import java.util.List;
@Extension
public class MyCustomAdapter implements Adapter {
@Override
public List<AdapterPayloadType> supportedPayloadTypes() {
return List.of(AdapterPayloadType.TEXT, AdapterPayloadType.JSON);
}
@Override
public void adapt(AdapterRequest request) {
// Your logic to send data to an external system
System.out.println("Adapting payload: " + request.getPayload());
}
}Implement the Configurable interface when your plugin needs custom configuration values from the application.yaml file. This allows users to configure your plugin per MX-Port instance without modifying your code.
Example use cases:
- Endpoint URLs
- Authentication credentials
- Retry counts or timeout values
- Feature flags
Add the Configurable interface to your class and implement the setConfiguration method:
package com.example.adapter;
import de.fraunhofer.iosb.ilt.dataspace_consumer.api.adapter.Adapter;
import de.fraunhofer.iosb.ilt.dataspace_consumer.api.adapter.AdapterPayloadType;
import de.fraunhofer.iosb.ilt.dataspace_consumer.api.adapter.AdapterRequest;
import de.fraunhofer.iosb.ilt.dataspace_consumer.api.config.Configurable;
import org.pf4j.Extension;
import java.util.List;
import java.util.Map;
@Extension
public class MyCustomAdapter implements Adapter, Configurable {
private String endpoint;
private int maxRetries = 3;
private String apiKey;
@Override
public void setConfiguration(Map<String, Object> config) {
if (config == null) return;
// Extract configuration values
Object endpointObj = config.get("endpoint");
if (endpointObj instanceof String) {
endpoint = (String) endpointObj;
}
Object retriesObj = config.get("maxRetries");
if (retriesObj instanceof Number) {
maxRetries = ((Number) retriesObj).intValue();
}
Object keyObj = config.get("apiKey");
if (keyObj instanceof String) {
apiKey = (String) keyObj;
}
}
@Override
public List<AdapterPayloadType> supportedPayloadTypes() {
return List.of(AdapterPayloadType.TEXT, AdapterPayloadType.JSON);
}
@Override
public void adapt(AdapterRequest request) {
// Use configured values
System.out.println("Sending to " + endpoint);
System.out.println("Max retries: " + maxRetries);
System.out.println("Using API key: " + (apiKey != null ? "***" : "none"));
// Your adapter logic here
}
}In the Dataspace Consumer Framework's application.yaml, reference your implementation and provide the configuration:
mx-port:
- name: my-custom-port
adapter:
implementation: com.example.adapter.MyCustomAdapter
config:
endpoint: "https://api.example.com/ingest"
maxRetries: 5
apiKey: "your-secret-key"The framework will automatically call setConfiguration(...) with the values from the config section.
Run Maven to build your plugin JAR:
mvn clean packageThis creates a JAR with all dependencies in the target/ directory, named your-artifact-id-<version>-all.jar.
Copy the generated JAR file to the extensions/ directory of your Dataspace Consumer Framework installation:
cp target/my-custom-adapter-0.0.1-all.jar /path/to/framework/extensions/Update the application.yaml to use your plugin by specifying the full class name in the implementation field:
mx-port:
- name: example-port
adapter:
implementation: com.example.adapter.MyCustomAdapter
config:
endpoint: "https://api.example.com"Start (or restart) the Framework. The framework will:
- Scan the
extensions/directory - Load your plugin JAR
- Discover classes annotated with
@Extension - Inject configuration via
setConfiguration()ifConfigurableis implemented - Use your implementation when the corresponding MX-Port is executed
Check the logs to verify your plugin was loaded successfully.
- Use the
template-pom.xmland customize the placeholders - Implement one of the interfaces of the api package
- Add
@Extensionannotation to make your class discoverable - Implement
Configurablewhen you need custom configuration fromapplication.yaml - Build with Maven (
mvn clean package) - Deploy the JAR to the
extensions/directory - Configure the plugin in
application.yamlusing the full class name
You now have a working plugin for the Dataspace Consumer Framework!