### GET /check/startup Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/api/api-observability/README.md Indicates whether the application within the container is started. This is similar to the readiness endpoint but is completed only after _all_ extensions have started. ```APIDOC ## GET /check/startup ### Description From the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes): Indicates whether the application within the container is started. This is very similar to the `/check/readiness` endpoint, but a connector may be able to respond to requests as soon as all extensions contributing APIs (e.g. REST controllers) have been registered, thus being `ready`, whereas the startup is only completed after _all_ extensions have started. This can only be determined by the runtime. Again, parallel subsystems like crawlers will **not** affect system startup state. ### Method GET ### Endpoint /api/check/startup ### Response #### Success Response (200) - **HealthStatus** (object) - Indicates the health status of the system. #### Error Response (503) - **HealthStatus** (object) - Indicates the health status of the system, with one or more systems reported as unhealthy. ### Response Example ```json { "status": "HEALTHY", "componentResults": { "some-component": { "status": "HEALTHY" } } } ``` ``` -------------------------------- ### Example URL with Major Versioning Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2023-11-09-api-versioning/README.md Illustrates how the major version of an API is represented in the URL path. ```plaintext https://some.host.com/api/management/v4/... ``` -------------------------------- ### DSP API Versioning Example Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2024-11-19-transformer-version-scheme/README.md Illustrates the current approach for versioning transformers in the DSP context, where new instances are created for each version. ```java var dspApiTransformerRegistryV08 = transformerRegistry.forContext("dsp-api:v0.8"); var dspApiTransformerRegistryV2024_1 = transformerRegistry.forContext("dsp-api:2024/1"); ``` -------------------------------- ### GET /check/readiness Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/api/api-observability/README.md Indicates whether the container is ready to respond to requests. This endpoint returns success only after all extensions that contribute an API have started successfully. ```APIDOC ## GET /check/readiness ### Description From the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes): Indicates whether the container is ready to respond to requests. Thus, the readiness endpoint must return a value indicating success _only after_ all extensions that contribute an API have started successfully. Note, that other subsystems like the catalog crawlers might not yet be completed at that point, but technically the connector is "ready to respond to requests", even if they might not produce the desired - or even a sensible - outcome. Catalog queries may produce an empty or incomplete result until crawlers have completed. ### Method GET ### Endpoint /api/check/readiness ### Response #### Success Response (200) - **HealthStatus** (object) - Indicates the health status of the system. #### Error Response (503) - **HealthStatus** (object) - Indicates the health status of the system, with one or more systems reported as unhealthy. ### Response Example ```json { "status": "HEALTHY", "componentResults": { "some-component": { "status": "HEALTHY" } } } ``` ``` -------------------------------- ### Scope Examples and Availability Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2026-06-06-scope-based-api-authorization/README.md Illustrates various scope notations and their meanings, indicating current and future availability. Shorthand notations and specific resource scopes are shown. ```plaintext | Scope | Meaning | Availability | |----------------------------------|--------------------------------------|----------------------------| | `management-api:read` / `:write` | shorthand for `*:read` / `*:write` | now | | `management-api:*:write` | write any (ordinary) resource | now (equivalent to above) | | `management-api:admin` | cross-tenant elevation / superuser | now | | `management-api:policies:write` | write **only** policies | later, no code change | ``` -------------------------------- ### Example of Publishing an Event Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2023-03-09-event-framework-refactoring/README.md Demonstrates how to create and publish an EventEnvelope using the updated EventRouter.publish method. It includes setting event ID, timestamp, and payload. ```java public void created(Asset asset){ var event=EventEnvelope.Builder.newInstance() .id("event-id") .at(Clock.systemUTC().millis()) .payload(AssetCreatedNew.Builder.newInstance().id("id").build()) .build(); eventRouter.publish(event); } ``` -------------------------------- ### Deploy Azure Resources and Run Server Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-03-01-serverless-transfers/README.md Execute this bash script to deploy necessary Azure resources and start the EDC server. Resource names can be customized within the script. ```bash docs/developer/decision-records/2022-03-01-serverless-transfers/create-resources-and-run-server.sh ``` -------------------------------- ### Build Endpoints Instance Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-10-22-e2e-testing-improvements/README.md Example of building an Endpoints instance using the builder pattern. It configures multiple endpoints with dynamic URIs. ```java Endpoints ENDPOINTS = Endpoints.Builder.newInstance() .endpoint("default", () -> URI.create("http://localhost:" + getFreePort() + "/api")) .endpoint("management", () -> URI.create("http://localhost:" + getFreePort() + "/management")) .endpoint("control", () -> URI.create("http://localhost:" + getFreePort() + "/control")) .endpoint("protocol", () -> URI.create("http://localhost:" + getFreePort() + "/protocol")) .build(); ``` -------------------------------- ### Launch Docker Compose Services Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-02-03-integration-testing/README.md Command to build and start the Docker Compose services defined in the docker-compose.yaml file. This command should be executed from the samples/04.0-file-transfer directory. ```shell $ (cd samples/04.0-file-transfer && docker-compose up -d) ``` -------------------------------- ### RetryProcessor Usage Example Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-02-05-state-machine-retry-processor-refactor/README.md Demonstrates the external usage of the RetryProcessor by chaining multiple operations with success, failure, and retry handlers. ```java ... // instantiate the retry processor on a `TransferProcess Instance return entityRetryProcessFactory.retryProcessor(process) // add a first processor that executes synchronously and returns a `StatusResult` .doProcess(result("Start DataFlow", (t, c) -> dataFlowManager.start(process, policy))) // add a second processor that executes asynchronously and returns a `CompletableFuture>` .doProcess(futureResult("Dispatch TransferRequestMessage to: " + process.getCounterPartyAddress(), (t, dataFlowResponse) -> { var messageBuilder = TransferStartMessage.Builder.newInstance().dataAddress(dataFlowResponse.getDataAddress()); return dispatch(messageBuilder, t, Object.class).>thenApply(result -> result.map(i -> dataFlowResponse)); }) ) // on success handler, it will get the output of the last processor in input .onSuccess((t, dataFlowResponse) -> transitionToStarted(t, dataFlowResponse.getDataPlaneId())) // on failure handler .onFailure((t, throwable) -> onFailure.accept(t)) // on retry exhausted or unrecoverable error handler .onFinalFailure((t, throwable) -> transitionToTerminating(t, throwable.getMessage(), throwable)) .execute(); ``` -------------------------------- ### Configure Token-Based Authentication for Custom Context Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/auth/auth-configuration/README.md Example configuration for setting up token-based authentication for a custom web context. Specifies the path, port, authentication type, and API key. ```properties web.http.custom.path=/custom web.http.custom.port=8081 web.http.custom.auth.type=tokenbased web.http.custom.auth.key=apiKey ``` -------------------------------- ### Custom Event Hierarchy Example Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2023-03-09-event-framework-refactoring/README.md Illustrates how to create a custom event hierarchy using abstract base classes. This allows subscribers to register for specific events or broader categories within the hierarchy. ```java public abstract class AssetEvent extends Event { } public class AssetCreatedEvent extends AssetEvent { } public class AssetDeletedEvent extends AssetEvent { } ``` -------------------------------- ### DCAT Catalog Structure Example Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/management-domains/management-domains.md Illustrates a DCAT Catalog structure with nested catalogs and distributions, used to represent remote catalogs within the EDC. ```json { "@context": "https://w3id.org/dspace/v0.8/context.json", "@id": "urn:uuid:3afeadd8-ed2d-569e-d634-8394a8836d57", "@type": "dcat:Catalog", "dct:title": "Data Provider Root Catalog", "dct:description": [ "A catalog of catalogs" ], "dct:publisher": "Data Provider A", "dcat:catalog": { "@type": "dcat:Catalog", "dct:publisher": "Data Provider A", "dcat:distribution": { "@type": "dcat:Distribution", "dcat:accessService": "urn:uuid:4aa2dcc8-4d2d-569e-d634-8394a8834d77" }, "dcat:service": [ { "@id": "urn:uuid:4aa2dcc8-4d2d-569e-d634-8394a8834d77", "@type": "dcat:DataService", "dcat:endpointURL": "https://provder-a.com/subcatalog" } ] } } ``` -------------------------------- ### Callback Configuration Example Source: https://github.com/eclipse-edc/connector/blob/main/extensions/control-plane/callback/callback-static-endpoint/README.md Configure two static callbacks with different event subscriptions and transactional settings. The first callback is transactional for contract negotiation and transfer process events. The second is asynchronous for finalized contract negotiation and completed transfer process events, with authentication headers. ```properties edc.callback.endpoint1.uri=http://localhost:8080/hooks edc.callback.endpoint1.events=contract.negotiation,transfer.process edc.callback.endpoint1.transactional=true edc.callback.endpoint2.uri=http://localhost:8081/hooks edc.callback.endpoint2.events=contract.negotiation.finalized,transfer.process.completed edc.callback.endpoint2.transactional=false edc.callback.endpoint2.auth-key=X-API-KEY edc.callback.endpoint2.auth-code-id=mysecret ``` -------------------------------- ### Instrumenting OkHttp Client with Micrometer Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-02-07-micrometer-metrics/README.md Example of instrumenting an OkHttpClient instance with Micrometer's metrics listener. This captures count and duration histogram metrics for outgoing REST calls, tagged by target URL. ```java OkHttpClient client = new OkHttpClient.Builder() .eventListener(OkHttpMetricsEventListener.builder(registry, "okhttp.requests").build()) ``` -------------------------------- ### Configure TokenBasedAuthenticationService for Management Context Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2024-06-24-api-authentication-configuration/README.md Example configuration to associate the TokenBasedAuthenticationService with the 'management' web context. This involves setting the authentication type and key alias. ```properties web.http.management.auth.type=tokenbased web.http.management.auth.key.alias=vaultAlias ``` -------------------------------- ### Expose Custom Web Context with Port Mapping Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/http/jetty-core/README.md Configure a named port mapping to expose a specific part of the API under a different port and path. This example creates a 'health' context. ```properties web.http.health.port=9191 web.http.health.path=/api/v1/health ``` -------------------------------- ### DCP Scope Configuration Properties Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2026-01-30-dynamic-dcp-scopes/README.md Example configuration properties for bootstrapping default and policy DCP scopes. These properties define the scope ID, type, value, and prefix mapping for policy-based scopes. ```properties edc.iam.dcp.scopes.membership.id:"membership-scope" edc.iam.dcp.scopes.membership.type:"DEFAULT" edc.iam.dcp.scopes.membership.value:"org.eclipse.edc.vc.type:MembershipCredential:read" # edc.iam.dcp.scopes.manufacturer.id:"manufacturer-scope" edc.iam.dcp.scopes.manufacturer.type:"POLICY" edc.iam.dcp.scopes.manufacturer.value:"org.eclipse.edc.vc.type:ManufacturerCredential:read" edc.iam.dcp.scopes.manufacturer.prefix-mapping:"ManufacturerCredential" ``` -------------------------------- ### Introspect Settings with @Setting Annotation Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-08-04-documentation-automation/README.md Settings are introspected and collated from code using the @Setting annotation. This example shows how to define configuration entries, including resolving constant values like PREFIX. ```java private static final String PREFIX="edc.core."; @Setting("Specifies the maximum number of retries") public static final String MAX_RETRIES=PREFIX+"retry.retries.max"; @Setting public static final String BACKOFF_MIN_MILLIS="edc.core.retry.backoff.min"; ``` -------------------------------- ### Get Shared Clock from Context Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-06-09-shared-clock/README.md Retrieve the shared Clock instance from the ServiceExtensionContext within the initialize method. ```java @Override public void initialize(ServiceExtensionContext context) { var clock = context.getClock(); ... } ``` -------------------------------- ### Build and Instantiate Endpoints Separately Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-10-22-e2e-testing-improvements/README.md Demonstrates building an Endpoints configuration and then instantiating separate runtime endpoints from it. This allows sharing common endpoint configurations across multiple runtimes. ```java Endpoints.Builder ENDPOINTS = Endpoints.Builder.newInstance() .endpoint("default", () -> URI.create("http://localhost:" + getFreePort() + "/api")) .endpoint("management", () -> URI.create("http://localhost:" + getFreePort() + "/management")) .endpoint("control", () -> URI.create("http://localhost:" + getFreePort() + "/control")) .endpoint("protocol", () -> URI.create("http://localhost:" + getFreePort() + "/protocol")); var providerEndpoints = ENDPOINTS.build(); var consumerEndpoints = ENDPOINTS.build(); ``` -------------------------------- ### Injecting Custom Participant Client Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-10-22-e2e-testing-improvements/README.md Example of using paramProvider to inject a custom ManagementApiClientV4 into a test. It derives configuration from the ComponentRuntimeContext. ```java @RegisterExtension static final RuntimeExtension CONSUMER_RUNTIME = ComponentRuntimeExtension.Builder.newInstance() // other configuration .paramProvider(ManagementApiClientV4.class, (ctx) -> { var participantId = context.getConfig().getString("edc.participant.id"); return ManagementApiClientV4.Builder.newInstance().participantId(participantId) .controlPlaneManagement(context.getEndpoint("management")) .controlPlaneProtocol(context.getEndpoint("protocol")) .build(); }) .build(); ``` -------------------------------- ### Get ID Extraction Function for Protocol Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-07-25-multiple-participant-identifiers/README.md Retrieves the specific participant ID extraction function for a given protocol context. ```java ParticipantIdExtractionFunction getIdExtractionFunction(String protocol); ``` -------------------------------- ### Kubernetes Readiness, Liveness, and Startup Probes Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/api/api-observability/README.md Define readiness, liveness, and startup probes in your Kubernetes deployment configuration. These probes leverage the Observability API endpoints to manage the container lifecycle effectively. ```kubernetes # ... spec: containers: - name: yourContainerName imagePullPolicy: IfNotPresent image: yourRepo/YourImageName ports: - name: http containerPort: 8181 readinessProbe: initialDelaySeconds: 1 periodSeconds: 5 httpGet: port: http path: /api/check/readiness livenessProbe: initialDelaySeconds: 3 periodSeconds: 5 httpGet: port: http path: /api/check/liveness startupProbe: initialDelaySeconds: 1 periodSeconds: 3 httpGet: port: http path: /api/startup ``` -------------------------------- ### GET /check/liveness Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/api/api-observability/README.md Checks if the container is running. In the event that the connector crashes, all REST endpoints become unavailable, and this endpoint would reflect that state. ```APIDOC ## GET /check/liveness ### Description From the [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes): indicates whether the container is running. We can assume, that in the event that the connector crashes, all REST endpoints become unavailable. ### Method GET ### Endpoint /api/check/liveness ### Response #### Success Response (200) - **HealthStatus** (object) - Indicates the health status of the system. #### Error Response (503) - **HealthStatus** (object) - Indicates the health status of the system, with one or more systems reported as unhealthy. ### Response Example ```json { "status": "HEALTHY", "componentResults": { "some-component": { "status": "HEALTHY" } } } ``` ``` -------------------------------- ### Get Participant ID for Protocol Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-07-25-multiple-participant-identifiers/README.md Retrieves the participant ID associated with a specific protocol context. Returns null if no dedicated ID is defined. ```java String getParticipantId(String protocol); ``` -------------------------------- ### Execute Integration Test with Gradle Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-02-03-integration-testing/README.md Command to clean, build, and run a specific integration test using Gradle, including the test class name for targeted execution. ```shell time ./gradlew cleanTest :samples:04.0-file-transfer:integration-tests:test --tests org.eclipse.dataspaceconnector.samples.ClassLoaderWithGradleClasspathTest ``` -------------------------------- ### Run File Transfer Integration Tests Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-02-03-integration-testing/README.md Executes the file transfer integration tests using Gradle. This command sets the necessary environment variables for the provider connector host and runs the specific test class. ```shell RUN_INTEGRATION_TEST=true EDC_PROVIDER_CONNECTOR_HOST=http://sample04-connector-provider:8181 time ./gradlew cleanTest :samples:04.0-file-transfer:integration-tests:test --tests org.eclipse.dataspaceconnector.samples.FileTransferSystemTest ``` -------------------------------- ### Implement Decorating Serializer for Metadata Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-07-04-type-manager/README.md Example of a user-defined serializer that decorates a serialized type with additional metadata, such as an '@context' field. This serializer can be registered with the TypeManager for specific types. ```java public class DecoratingSerializer extends JsonSerializer { private Class type; public DecoratingSerializer(Class type) { this.type = type; } public void serialize(Object value, JsonGenerator generator, SerializerProvider provider) throws IOException { generator.writeStartObject(); var javaType = provider.constructType(type); var beanDescription = provider.getConfig().introspect(javaType); var staticTyping = provider.isEnabled(MapperFeature.USE_STATIC_TYPING); var serializer = BeanSerializerFactory.instance.findBeanOrAddOnSerializer(provider, javaType, beanDescription, staticTyping); serializer.unwrappingSerializer(null).serialize(value, generator, provider); generator.writeObjectField("@context", "some data"); generator.writeEndObject(); } } ``` ```java manager.registerSerializer("foo", Bar.class, new DecoratingSerializer<>(Bar.class)); manager.registerSerializer("foo", Baz.class, new DecoratingSerializer<>(Baz.class)); ``` -------------------------------- ### Acquire, Save, and Break Lease in Cosmos DB Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-03-30-cosmosdb-lease-mechanism/README.md Demonstrates the sequence of acquiring a lease, saving a document, and then breaking the lease. This pattern ensures exclusive access to a document during processing. ```java leaseContext.acquireLease(process.getId()); failsafeExecutor.run(() -> cosmosDbApi.saveItem(document)); leaseContext.breakLease(process.getId()); ``` -------------------------------- ### Exemplary Management API Configuration Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/api/management-api-configuration/README.md Defines the port and path for the Management API. Ensure these are set correctly to avoid filters being applied to the default context. ```properties web.http.management.port=9191 web.http.management.path=/api/v1/management web.http.port=8181 web.http.path=/api ``` -------------------------------- ### Run PostgreSQL Container Source: https://github.com/eclipse-edc/connector/blob/main/system-tests/e2e-transfer-test/README.md Use this command to spin up a PostgreSQL container for the EndToEndTransferPostgresqlTest. Ensure the necessary environment variables and port mappings are configured. ```shell docker run --rm --name edc-postgres -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres ``` -------------------------------- ### Example: SqlQueryExecutor executeQuery Signature Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-12-07-transaction-synchronization/README.md Illustrative signature for a method that might use transaction synchronization to manage JDBC resources. This method returns a stream of results from a SQL query. ```java public static Stream executeQuery(Connection connection, boolean closeConnection, ResultSetMapper resultSetMapper, String sql, Object... arguments) ``` -------------------------------- ### Implement PresentationRequestService Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-11-10-presentation-request-service/README.md This class implements the PresentationRequestService interface. It handles the creation of an SI token and the subsequent request for a Verifiable Presentation. ```java public class DefaultPresentationRequestService implements PresentationRequestService { // services & constructor @Override public Result> requestPresentation(String participantContextId, String ownDid, String counterPartyDid, String counterPartySiToken, List requestedScopes) { Map siTokenClaims = Map.of(PRESENTATION_TOKEN_CLAIM, counterPartyToken, ISSUED_AT, Instant.now().getEpochSecond(), AUDIENCE, counterPartyDid, ISSUER, ownDid, SUBJECT, ownDid, EXPIRATION_TIME, Instant.now().plus(5, ChronoUnit.MINUTES).getEpochSecond()); var siToken = secureTokenService.createToken(participantContextId, siTokenClaims, null); if (siToken.failed()) { return siToken.mapFailure(); } var siTokenString = siToken.getContent().getToken(); return credentialServiceUrlResolver.resolve(counterPartyDid) .compose(url -> credentialServiceClient.requestPresentation(url, siTokenString, requestedScopes)); } } ``` -------------------------------- ### Custom Entity Pending Guard Implementation Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2023-07-20-state-machine-guards/README.md Example of a custom PendingGuard implementation for an entity. It defines a 'test' method to determine if an entity's state and other conditions require it to be marked as pending. ```java class EntityPendingGuard implements PendingGuard { // custom collaborators as other services boolean test(Entity entity) { // custom condition return entity.getState() = SPECIFIC_STATE.code() && otherCondition; // if true, the entity will be pending } } ``` -------------------------------- ### Default Participant Identity Resolver Implementation Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-10-29-participant-identifiers/README.md Provides a default implementation for resolving participant identifiers by retrieving the configured ID from properties. This implementation is suitable for single-context setups and applies to all protocols. ```java @Provider(isDefault = true) public ParticipantIdentityResolver participantIdentityResolver() { // retrieve participant id from config `edc.participant.id` return (context, protocol) -> participantId; } ``` -------------------------------- ### ComponentRuntimeExtension Builder API Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2025-10-22-e2e-testing-improvements/README.md Illustrates the fluent builder API for ComponentRuntimeExtension. Use this to configure runtime name, modules, and configuration providers before building the extension. ```java public class ComponentRuntimeExtension extends RuntimePerClassExtension { public static class Builder { protected String name; protected List modules = new ArrayList<>(); protected final List> configurationProviders = new ArrayList<>(); protected Builder() { } public static Builder newInstance() { return new Builder(); } public Builder name(String name) { this.name = name; return this; } public Builder modules(String... modules) { this.modules.addAll(Arrays.stream(modules).toList()); return this; } public Builder configurationProvider(Supplier configurationProvider) { this.configurationProviders.add(configurationProvider); return this; } public ComponentRuntimeExtension build() { Objects.requireNonNull(name, "name"); // logic to consolidate configuration providers } } } ``` -------------------------------- ### Configure EDC Runtimes with JarRuntimeExtension Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-02-03-integration-testing/README.md Sets up EDC consumer and provider runtimes using JarRuntimeExtension for integration testing. The consumer runtime is configured with specific ports and API keys, while the provider runtime is initialized. ```java // EDC Consumer runtime @RegisterExtension @Order(1) static JarRuntimeExtension otherConnector = new JarRuntimeExtension( "../consumer/build/libs/consumer.jar", Map.of( "web.http.port", "9191", "edc.api.control.auth.apikey.value", API_KEY_CONTROL_AUTH, "ids.webhook.address", "http://localhost:9191")); // EDC Provider runtime @RegisterExtension @Order(2) static EdcExtension edc = new EdcExtension(); ``` -------------------------------- ### Configure Test Task to Show Standard Output Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-02-03-integration-testing/README.md Configures the 'test' task in Gradle to display standard output streams, which is useful for debugging integration tests. ```kotlin // samples/04.0-file-transfer/integration-tests/build.gradle.kts tasks.getByName("test") { testLogging { showStandardStreams = true } } ``` -------------------------------- ### Management API Incremental Versioning Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2024-11-19-transformer-version-scheme/README.md Demonstrates the proposed approach for incremental versioning in the management API context, allowing overrides within specific versions. ```java var mgmtContext = transformerRegistry.forContext("management-api"); var mgmtContextV4Alpha = mgmtContext.forContext("V4Alpha"); // override mgmtContext transformer mgmtContextV4Alpha.registerTransformer(); ``` -------------------------------- ### GET /check/health Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/api/api-observability/README.md Returns information about the system status. This endpoint is primarily intended for use in HEALTHCHECK instructions in Dockerfiles. It returns HTTP 200 if all systems are healthy, and HTTP 503 if any system is unhealthy. ```APIDOC ## GET /check/health ### Description Returns information about the system status. This is primarily intended to be used in [`HEALTHCHECK` instructions in Docker files](https://docs.docker.com/engine/reference/builder/#healthcheck). Here, this endpoint will return HTTP 200 indicating that the system is healthy as soon as the connector has finished starting. Therefore, the `/check/health` and `/api/check/startup` endpoints will have the same behaviour. ### Method GET ### Endpoint /api/check/health ### Response #### Success Response (200) - **HealthStatus** (object) - Indicates the health status of the system. #### Error Response (503) - **HealthStatus** (object) - Indicates the health status of the system, with one or more systems reported as unhealthy. ### Response Example ```json { "status": "HEALTHY", "componentResults": { "some-component": { "status": "HEALTHY" } } } ``` ``` -------------------------------- ### Controller Implementation with Jakarta Annotations Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-03-15-swagger-annotations/README.md Controller implementations should only use Jakarta annotations for framework-specific configurations like media types and paths. This keeps controllers focused on implementation logic. ```java @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) @Path("/assets") public class AssetApiController implements AssetApi ``` -------------------------------- ### Transfer Process Created Event Implementation Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-06-03-event-framework/README.md An example implementation of an event, specifically for when a transfer process is created. It extends the base Event class and includes relevant details like the transfer process ID. ```java public class TransferProcessCreatedEvent extends Event { private String id; ... } ``` -------------------------------- ### Collect Jetty Connection Metrics Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-02-07-micrometer-metrics/README.md Integrates Micrometer with Jetty to collect connection counts, and inbound/outbound byte counters and histograms. This requires the Micrometer Jetty integration to be available. ```java JettyConnectionMetrics.addToAllConnectors(server, registry); ``` -------------------------------- ### DataspaceProfileContext Record Definition Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2026-05-11-multi-profile-virtual-connector/README.md Defines the structure for holding dataspace profile information, including name, protocol details, and context URLs. This record is central to managing multiple profiles in a virtual connector setup. ```java public record DataspaceProfileContext(String name, ProtocolVersion protocolVersion, ProtocolWebhook webhook, ParticipantIdExtractionFunction idExtractionFunction, JsonLdNamespace protocolNamespace, List jsonLdContextsUrl) { } ``` -------------------------------- ### Configure Default Datasource Properties Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2023-08-01-default-datasource/README.md Configure the default datasource properties by specifying user, password, and URL. This applies when no specific datasource name is configured for SQL store extensions. ```properties edc.datasource.default.user= ``` ```properties edc.datasource.default.password= ``` ```properties edc.datasource.default.url= ``` -------------------------------- ### Explicitly close stream in PolicyDefinitionServiceImpl Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-09-29-sql-query-streaming/README.md When using the streaming approach, it is crucial to explicitly close the stream to prevent connection leaks. This example shows how a try-with-resources statement ensures the stream (and its associated resources) are closed after use. ```java public class PolicyDefinitionServiceImpl implements PolicyDefinitionService { ... @Override public @NotNull ServiceResult deleteById(String policyId) { ... try (var contractDefinitionOnPolicy = contractDefinitionStore.findAll(queryContractPolicyFilter)) { // this will close the stream after the use if (contractDefinitionOnPolicy.findAny().isPresent()) { return ServiceResult.conflict(format("PolicyDefinition %s cannot be deleted as it is referenced by at least one contract definition", policyId)); } } ... } ``` -------------------------------- ### Default Web Context Configuration Source: https://github.com/eclipse-edc/connector/blob/main/extensions/common/http/jetty-core/README.md Default configuration for the web server port and path. Resources are exposed under http://:8181/api/*. ```properties web.http.port=8181 web.http.path=/api ``` -------------------------------- ### Load and Execute Main Class from Shadow JAR Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-02-03-integration-testing/README.md Loads the main class from a Shadow JAR using a custom ClassLoader and executes its main method. This is used to run the connector within an integration test environment. Ensure the JAR file path and main class name are correctly specified. ```java // JarRuntimeExtension var classLoader = URLClassLoader.newInstance(new URL[]{jarFile.toURI().toURL()}, ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(classLoader); var mainClass = classLoader.loadClass(mainClassName); var mainMethod = mainClass.getMethod("main", String[].class); mainMethod.invoke(null, new Object[]{new String[0]}); ``` -------------------------------- ### Integration Test for Asset API Controller Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2023-04-18-api-controllers-testing/README.md This concrete test class extends the base integration test setup to test the AssetApiController. It mocks dependencies and uses RestAssured to verify the 'getAllAssets' endpoint's behavior and response. ```java @ApiTest public class AssetApiControllerIntegrationTest extends JerseyIntegrationTestBase { private final AssetService service = mock(AssetService.class); private final DataAddressResolver dataAddressResolver = mock(DataAddressResolver.class); private final DtoTransformerRegistry transformerRegistry = mock(DtoTransformerRegistry.class); @Override protected Object controller() { return new AssetApiController(monitor, service, dataAddressResolver, transformerRegistry); } @Test void getAllAssets() { when(service.query(any())).thenReturn(ServiceResult.success(Stream.of(Asset.Builder.newInstance().build()))); when(transformerRegistry.transform(isA(Asset.class), eq(AssetResponseDto.class))) .thenReturn(Result.success(AssetResponseDto.Builder.newInstance().build())); when(transformerRegistry.transform(isA(QuerySpecDto.class), eq(QuerySpec.class))) .thenReturn(Result.success(QuerySpec.Builder.newInstance().offset(10).build())); baseRequest() .get("/assets") .then() .statusCode(200) .contentType(JSON) .body("size()", is(1)); } } ``` -------------------------------- ### Management API Token Shape Example Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2026-06-06-scope-based-api-authorization/README.md Illustrates the structure of a Management API access token, which now includes the participant context ID in the 'sub' claim and scopes in the 'scope' claim. Custom claims for participant context ID and role are no longer used. ```json { "iss": "https://idp.example.org/", "sub": "did:web:participant-a", "scope": "management-api:read management-api:write", "exp": 1700000000 } ``` -------------------------------- ### Proposed Module Structure for SQL Implementations Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-08-17-remove_h2_database_tests/README.md Illustrates a potential future modular structure for SQL implementations, separating generic SQL logic from database-specific components like statements and tests. ```plaintext extensions ├── sql │ ├── asset-index // <- only contains unit test │ ├── contract-definition-store │ ├── ... ├── postgres │ ├── asset-index-postgres // <- contributes PostgresDialectStatements.java and PostgresAssetIndexTest.java │ ├── contract-definition-store-postgres │ ├── ... ├── mssql │ ├── asset-index-mssql // <- contributes MssqlDialectStatements.java and MssqlAssetIndexTest.java │ ├── contract-definition-store-mssql │ ├── ... ``` -------------------------------- ### Test Async Events with CountDownLatch Source: https://github.com/eclipse-edc/connector/blob/main/docs/developer/decision-records/2022-08-04-async-code-testing-practices/README.md Demonstrates testing asynchronous event dispatching using CountDownLatch. Requires manual latch management and awaits. ```java public class AssetEventDispatchTest { //... @Test void shouldDispatchEventsOnAssetCreationAndDeletion(AssetService service, EventRouter eventRouter) throws InterruptedException { var createdLatch = onDispatchLatch(AssetCreated.class); var deletedLatch = onDispatchLatch(AssetDeleted.class); eventRouter.register(eventSubscriber); var asset = Asset.Builder.newInstance().id("assetId").build(); var dataAddress = DataAddress.Builder.newInstance().type("any").build(); service.create(asset, dataAddress); assertThat(createdLatch.await(10, SECONDS)).isTrue(); verify(eventSubscriber).on(isA(AssetCreated.class)); service.delete(asset.getId()); assertThat(deletedLatch.await(10, SECONDS)).isTrue(); verify(eventSubscriber).on(isA(AssetDeleted.class)); } private CountDownLatch onDispatchLatch(Class eventType) { var latch = new CountDownLatch(1); doAnswer(i -> { latch.countDown(); return null; }).when(eventSubscriber).on(isA(eventType)); return latch; } } ```