diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-api/build.gradle.kts b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-api/build.gradle.kts index ea483883ac8..e934dd7de90 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-api/build.gradle.kts +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-api/build.gradle.kts @@ -25,7 +25,8 @@ dependencies { api(project(":spi:common:json-ld-spi")) api(project(":spi:control-plane:control-plane-spi")) - + + implementation(project(":extensions:common:http:lib:jersey-providers-lib")) implementation(project(":data-protocols:dsp:dsp-catalog:lib:dsp-catalog-validation-lib")) implementation(libs.jakarta.rsApi) diff --git a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiExtension.java b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiExtension.java index e2064e63e08..2bc13120f3b 100644 --- a/data-protocols/dsp/dsp-catalog/dsp-catalog-http-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiExtension.java +++ b/data-protocols/dsp/dsp-catalog/dsp-catalog-http-api/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiExtension.java @@ -33,16 +33,21 @@ import org.eclipse.edc.spi.query.CriterionOperatorRegistry; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; import static org.eclipse.edc.protocol.dsp.spi.type.DspCatalogPropertyAndTypeNames.DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_IRI; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_2024_1; import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_TRANSFORMER_CONTEXT_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_TRANSFORMER_CONTEXT_V_2024_1; import static org.eclipse.edc.protocol.dsp.spi.version.DspVersions.V_08; import static org.eclipse.edc.protocol.dsp.spi.version.DspVersions.V_2024_1; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; /** * Creates and registers the controller for dataspace protocol catalog requests. @@ -72,7 +77,8 @@ public class DspCatalogApiExtension implements ServiceExtension { private TypeTransformerRegistry transformerRegistry; @Inject private Monitor monitor; - + @Inject + private TypeManager typeManager; @Inject private JsonLd jsonLd; @@ -84,10 +90,12 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { validatorRegistry.register(DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_IRI, CatalogRequestMessageValidator.instance(criterionOperatorRegistry)); - + var jsonLdMapper = typeManager.getMapper(JSON_LD); webService.registerResource(ApiContext.PROTOCOL, new DspCatalogApiController(service, dspRequestHandler, continuationTokenManager(monitor, DSP_TRANSFORMER_CONTEXT_V_08))); webService.registerResource(ApiContext.PROTOCOL, new DspCatalogApiController20241(service, dspRequestHandler, continuationTokenManager(monitor, DSP_TRANSFORMER_CONTEXT_V_2024_1))); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspCatalogApiController.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_08)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspCatalogApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_2024_1)); dataServiceRegistry.register(DataService.Builder.newInstance() .endpointDescription("dspace:connector") diff --git a/data-protocols/dsp/dsp-http-api-configuration/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationExtension.java b/data-protocols/dsp/dsp-http-api-configuration/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationExtension.java index 38257d06713..e5840bdfd75 100644 --- a/data-protocols/dsp/dsp-http-api-configuration/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationExtension.java +++ b/data-protocols/dsp/dsp-http-api-configuration/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationExtension.java @@ -42,7 +42,6 @@ import org.eclipse.edc.transform.transformer.edc.to.JsonObjectToCriterionTransformer; import org.eclipse.edc.transform.transformer.edc.to.JsonObjectToQuerySpecTransformer; import org.eclipse.edc.transform.transformer.edc.to.JsonValueToGenericTypeTransformer; -import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; import org.eclipse.edc.web.jersey.providers.jsonld.ObjectMapperProvider; import org.eclipse.edc.web.spi.WebServer; import org.eclipse.edc.web.spi.WebService; @@ -62,7 +61,8 @@ import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_SCHEMA; import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_PREFIX; import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA; -import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_2024_1; import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_TRANSFORMER_CONTEXT_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_TRANSFORMER_CONTEXT_V_2024_1; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; @@ -124,16 +124,10 @@ public void initialize(ServiceExtensionContext context) { var jsonLdMapper = typeManager.getMapper(JSON_LD); // registers ns for DSP scope - jsonLd.registerNamespace(DCAT_PREFIX, DCAT_SCHEMA, DSP_SCOPE); - jsonLd.registerNamespace(DCT_PREFIX, DCT_SCHEMA, DSP_SCOPE); - jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, DSP_SCOPE); - jsonLd.registerNamespace(DSPACE_PREFIX, DSPACE_SCHEMA, DSP_SCOPE); - jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE, DSP_SCOPE); - jsonLd.registerNamespace(EDC_PREFIX, EDC_NAMESPACE, DSP_SCOPE); - + registerNamespaces(DSP_SCOPE_V_08); + registerNamespaces(DSP_SCOPE_V_2024_1); webService.registerResource(ApiContext.PROTOCOL, new ObjectMapperProvider(jsonLdMapper)); - webService.registerResource(ApiContext.PROTOCOL, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE)); var mapper = typeManager.getMapper(JSON_LD); mapper.registerSubtypes(AtomicConstraint.class, LiteralExpression.class); @@ -142,6 +136,15 @@ public void initialize(ServiceExtensionContext context) { registerTransformers(DSP_TRANSFORMER_CONTEXT_V_2024_1, mapper); } + private void registerNamespaces(String scope) { + jsonLd.registerNamespace(DCAT_PREFIX, DCAT_SCHEMA, scope); + jsonLd.registerNamespace(DCT_PREFIX, DCT_SCHEMA, scope); + jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, scope); + jsonLd.registerNamespace(DSPACE_PREFIX, DSPACE_SCHEMA, scope); + jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE, scope); + jsonLd.registerNamespace(EDC_PREFIX, EDC_NAMESPACE, scope); + } + private void registerTransformers(String version, ObjectMapper mapper) { var jsonBuilderFactory = Json.createBuilderFactory(Map.of()); diff --git a/data-protocols/dsp/dsp-http-api-configuration/src/test/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationExtensionTest.java b/data-protocols/dsp/dsp-http-api-configuration/src/test/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationExtensionTest.java index 1f628f7d1b4..16963829939 100644 --- a/data-protocols/dsp/dsp-http-api-configuration/src/test/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationExtensionTest.java +++ b/data-protocols/dsp/dsp-http-api-configuration/src/test/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationExtensionTest.java @@ -23,7 +23,6 @@ import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; -import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; import org.eclipse.edc.web.jersey.providers.jsonld.ObjectMapperProvider; import org.eclipse.edc.web.spi.WebServer; import org.eclipse.edc.web.spi.WebService; @@ -33,6 +32,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.util.Map; @@ -46,7 +47,8 @@ import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA; import static org.eclipse.edc.protocol.dsp.http.api.configuration.DspApiConfigurationExtension.DSP_CALLBACK_ADDRESS; import static org.eclipse.edc.protocol.dsp.http.api.configuration.DspApiConfigurationExtension.SETTINGS; -import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_2024_1; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; import static org.mockito.ArgumentMatchers.any; @@ -116,19 +118,19 @@ void initialize_shouldRegisterWebServiceProviders(DspApiConfigurationExtension e extension.initialize(context); verify(webService).registerResource(eq(ApiContext.PROTOCOL), isA(ObjectMapperProvider.class)); - verify(webService).registerResource(eq(ApiContext.PROTOCOL), isA(JerseyJsonLdInterceptor.class)); } - @Test - void initialize_shouldRegisterNamespaces(DspApiConfigurationExtension extension, ServiceExtensionContext context) { + @ParameterizedTest + @ValueSource(strings = { DSP_SCOPE_V_08, DSP_SCOPE_V_2024_1 }) + void initialize_shouldRegisterNamespaces(String scope, DspApiConfigurationExtension extension, ServiceExtensionContext context) { extension.initialize(context); - verify(jsonLd).registerNamespace(DCAT_PREFIX, DCAT_SCHEMA, DSP_SCOPE); - verify(jsonLd).registerNamespace(DCT_PREFIX, DCT_SCHEMA, DSP_SCOPE); - verify(jsonLd).registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, DSP_SCOPE); - verify(jsonLd).registerNamespace(VOCAB, EDC_NAMESPACE, DSP_SCOPE); - verify(jsonLd).registerNamespace(EDC_PREFIX, EDC_NAMESPACE, DSP_SCOPE); - verify(jsonLd).registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, DSP_SCOPE); + verify(jsonLd).registerNamespace(DCAT_PREFIX, DCAT_SCHEMA, scope); + verify(jsonLd).registerNamespace(DCT_PREFIX, DCT_SCHEMA, scope); + verify(jsonLd).registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, scope); + verify(jsonLd).registerNamespace(VOCAB, EDC_NAMESPACE, scope); + verify(jsonLd).registerNamespace(EDC_PREFIX, EDC_NAMESPACE, scope); + verify(jsonLd).registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, scope); } } diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-api/build.gradle.kts b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-api/build.gradle.kts index f74d77730b8..f131c52b8ca 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-api/build.gradle.kts +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-api/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { api(project(":extensions:common:json-ld")) implementation(project(":data-protocols:dsp:dsp-negotiation:lib:dsp-negotiation-validation-lib")) + implementation(project(":extensions:common:http:lib:jersey-providers-lib")) implementation(libs.jakarta.rsApi) diff --git a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiExtension.java b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiExtension.java index 9cc6edd3d88..955951dcded 100644 --- a/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiExtension.java +++ b/data-protocols/dsp/dsp-negotiation/dsp-negotiation-http-api/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiExtension.java @@ -16,6 +16,7 @@ import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationProtocolService; import org.eclipse.edc.connector.controlplane.services.spi.protocol.ProtocolVersionRegistry; +import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; import org.eclipse.edc.protocol.dsp.negotiation.http.api.controller.DspNegotiationApiController; import org.eclipse.edc.protocol.dsp.negotiation.http.api.controller.DspNegotiationApiController20241; @@ -29,10 +30,14 @@ import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_2024_1; import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_AGREEMENT_MESSAGE_IRI; import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_AGREEMENT_VERIFICATION_MESSAGE_IRI; import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_NEGOTIATION_EVENT_MESSAGE_IRI; @@ -41,6 +46,7 @@ import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_REQUEST_MESSAGE_IRI; import static org.eclipse.edc.protocol.dsp.spi.version.DspVersions.V_08; import static org.eclipse.edc.protocol.dsp.spi.version.DspVersions.V_2024_1; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; /** * Creates and registers the controller for dataspace protocol negotiation requests. @@ -61,6 +67,12 @@ public class DspNegotiationApiExtension implements ServiceExtension { @Inject private ProtocolVersionRegistry versionRegistry; + @Inject + private JsonLd jsonLd; + + @Inject + private TypeManager typeManager; + @Override public String name() { return NAME; @@ -68,6 +80,8 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { + var jsonLdMapper = typeManager.getMapper(JSON_LD); + validatorRegistry.register(DSPACE_TYPE_CONTRACT_REQUEST_MESSAGE_IRI, ContractRequestMessageValidator.instance()); validatorRegistry.register(DSPACE_TYPE_CONTRACT_OFFER_MESSAGE_IRI, ContractOfferMessageValidator.instance()); validatorRegistry.register(DSPACE_TYPE_CONTRACT_NEGOTIATION_EVENT_MESSAGE_IRI, ContractNegotiationEventMessageValidator.instance()); @@ -77,6 +91,8 @@ public void initialize(ServiceExtensionContext context) { webService.registerResource(ApiContext.PROTOCOL, new DspNegotiationApiController(protocolService, dspRequestHandler)); webService.registerResource(ApiContext.PROTOCOL, new DspNegotiationApiController20241(protocolService, dspRequestHandler)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspNegotiationApiController.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_08)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspNegotiationApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_2024_1)); versionRegistry.register(V_2024_1); versionRegistry.register(V_08); diff --git a/data-protocols/dsp/dsp-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/type/DspConstants.java b/data-protocols/dsp/dsp-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/type/DspConstants.java index 5211c4b532c..01c9d473357 100644 --- a/data-protocols/dsp/dsp-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/type/DspConstants.java +++ b/data-protocols/dsp/dsp-spi/src/main/java/org/eclipse/edc/protocol/dsp/spi/type/DspConstants.java @@ -25,6 +25,8 @@ public interface DspConstants { String DSP_CONTEXT_SEPARATOR = ":"; String DSP_SCOPE = "DSP"; + String DSP_SCOPE_V_08 = DSP_SCOPE + DSP_CONTEXT_SEPARATOR + V_08_VERSION; + String DSP_SCOPE_V_2024_1 = DSP_SCOPE + DSP_CONTEXT_SEPARATOR + V_2024_1_VERSION; String DSP_TRANSFORMER_CONTEXT = "dsp-api"; String DSP_TRANSFORMER_CONTEXT_V_08 = DSP_TRANSFORMER_CONTEXT + DSP_CONTEXT_SEPARATOR + V_08_VERSION; String DSP_TRANSFORMER_CONTEXT_V_2024_1 = DSP_TRANSFORMER_CONTEXT + DSP_CONTEXT_SEPARATOR + V_2024_1_VERSION; diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-api/build.gradle.kts b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-api/build.gradle.kts index 2ad64e51bf9..6e6eddec206 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-api/build.gradle.kts +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-api/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { implementation(project(":spi:common:json-ld-spi")) implementation(project(":data-protocols:dsp:dsp-transfer-process:lib:dsp-transfer-process-validation-lib")) + implementation(project(":extensions:common:http:lib:jersey-providers-lib")) implementation(libs.jakarta.rsApi) diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiExtension.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiExtension.java index 19f7cf84280..7b684bd297e 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiExtension.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-http-api/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiExtension.java @@ -16,6 +16,7 @@ import org.eclipse.edc.connector.controlplane.services.spi.protocol.ProtocolVersionRegistry; import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessProtocolService; +import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; import org.eclipse.edc.protocol.dsp.transferprocess.http.api.controller.DspTransferProcessApiController; import org.eclipse.edc.protocol.dsp.transferprocess.http.api.controller.DspTransferProcessApiController20241; @@ -27,16 +28,21 @@ import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_2024_1; import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_COMPLETION_MESSAGE_IRI; import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_REQUEST_MESSAGE_IRI; import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_START_MESSAGE_IRI; import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_TERMINATION_MESSAGE_IRI; import static org.eclipse.edc.protocol.dsp.spi.version.DspVersions.V_08; import static org.eclipse.edc.protocol.dsp.spi.version.DspVersions.V_2024_1; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; /** * Creates and registers the controller for dataspace protocol transfer process requests. @@ -55,9 +61,15 @@ public class DspTransferProcessApiExtension implements ServiceExtension { private JsonObjectValidatorRegistry validatorRegistry; @Inject private ProtocolVersionRegistry versionRegistry; + @Inject + private JsonLd jsonLd; + @Inject + private TypeManager typeManager; @Override public void initialize(ServiceExtensionContext context) { + var jsonLdMapper = typeManager.getMapper(JSON_LD); + validatorRegistry.register(DSPACE_TYPE_TRANSFER_REQUEST_MESSAGE_IRI, TransferRequestMessageValidator.instance()); validatorRegistry.register(DSPACE_TYPE_TRANSFER_START_MESSAGE_IRI, TransferStartMessageValidator.instance()); validatorRegistry.register(DSPACE_TYPE_TRANSFER_COMPLETION_MESSAGE_IRI, TransferCompletionMessageValidator.instance()); @@ -65,6 +77,8 @@ public void initialize(ServiceExtensionContext context) { webService.registerResource(ApiContext.PROTOCOL, new DspTransferProcessApiController(transferProcessProtocolService, dspRequestHandler)); webService.registerResource(ApiContext.PROTOCOL, new DspTransferProcessApiController20241(transferProcessProtocolService, dspRequestHandler)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspTransferProcessApiController.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_08)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspTransferProcessApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_2024_1)); versionRegistry.register(V_2024_1); versionRegistry.register(V_08); diff --git a/data-protocols/dsp/dsp-version/dsp-version-http-api/build.gradle.kts b/data-protocols/dsp/dsp-version/dsp-version-http-api/build.gradle.kts index 084251fd86e..70f5271ee6d 100644 --- a/data-protocols/dsp/dsp-version/dsp-version-http-api/build.gradle.kts +++ b/data-protocols/dsp/dsp-version/dsp-version-http-api/build.gradle.kts @@ -23,6 +23,7 @@ dependencies { api(project(":spi:common:transform-spi")) api(project(":spi:common:web-spi")) api(project(":data-protocols:dsp:dsp-http-spi")) + implementation(project(":extensions:common:http:lib:jersey-providers-lib")) testImplementation(project(":core:common:junit")) testImplementation(project(":extensions:common:json-ld")) diff --git a/data-protocols/dsp/dsp-version/dsp-version-http-api/src/main/java/org/eclipse/edc/protocol/dsp/version/http/api/DspVersionApiExtension.java b/data-protocols/dsp/dsp-version/dsp-version-http-api/src/main/java/org/eclipse/edc/protocol/dsp/version/http/api/DspVersionApiExtension.java index be44d30728c..338dba314d8 100644 --- a/data-protocols/dsp/dsp-version/dsp-version-http-api/src/main/java/org/eclipse/edc/protocol/dsp/version/http/api/DspVersionApiExtension.java +++ b/data-protocols/dsp/dsp-version/dsp-version-http-api/src/main/java/org/eclipse/edc/protocol/dsp/version/http/api/DspVersionApiExtension.java @@ -16,6 +16,7 @@ import jakarta.json.Json; import org.eclipse.edc.connector.controlplane.services.spi.protocol.VersionProtocolService; +import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; import org.eclipse.edc.protocol.dsp.version.http.api.transformer.JsonObjectFromProtocolVersionsTransformer; import org.eclipse.edc.protocol.dsp.version.http.api.transformer.JsonObjectFromVersionsError; @@ -23,13 +24,17 @@ import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; import java.util.Map; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE_V_08; import static org.eclipse.edc.protocol.dsp.version.http.api.DspVersionApiExtension.NAME; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; /** * Provide API for the protocol versions. @@ -51,6 +56,12 @@ public class DspVersionApiExtension implements ServiceExtension { @Inject private VersionProtocolService service; + @Inject + private JsonLd jsonLd; + @Inject + private TypeManager typeManager; + + @Override public String name() { return NAME; @@ -58,10 +69,13 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { + var jsonLdMapper = typeManager.getMapper(JSON_LD); + transformerRegistry.register(new JsonObjectFromProtocolVersionsTransformer()); transformerRegistry.register(new JsonObjectFromVersionsError(Json.createBuilderFactory(Map.of()))); webService.registerResource(ApiContext.PROTOCOL, new DspVersionApiController(requestHandler, service)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspVersionApiController.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_08)); } } diff --git a/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/JerseyRestService.java b/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/JerseyRestService.java index 8d847e75036..623e3a272d7 100644 --- a/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/JerseyRestService.java +++ b/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/JerseyRestService.java @@ -18,6 +18,7 @@ import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.web.jersey.feature.DynamicResourceFeature; import org.eclipse.edc.web.jersey.mapper.EdcApiExceptionMapper; import org.eclipse.edc.web.jersey.mapper.UnexpectedExceptionMapper; import org.eclipse.edc.web.jersey.providers.jsonld.ObjectMapperProvider; @@ -45,6 +46,7 @@ public class JerseyRestService implements WebService { private final Monitor monitor; private final Map> controllers = new HashMap<>(); + private final Map, List>> dynamicResources = new HashMap<>(); private final JerseyConfiguration configuration; private final List> additionalInstances = new ArrayList<>(); @@ -67,6 +69,14 @@ public void registerResource(String contextAlias, Object resource) { .add(resource); } + @Override + public void registerDynamicResource(String contextAlias, Class target, Object resource) { + dynamicResources + .computeIfAbsent(contextAlias, s -> new HashMap<>()) + .computeIfAbsent(target, s -> new ArrayList<>()) + .add(resource); + } + void registerInstance(Supplier instance) { additionalInstances.add(instance); } @@ -82,6 +92,8 @@ public void start() { private void registerContext(String contextAlias, List controllers) { var resourceConfig = new ResourceConfig(); + var dynamicResourcesForContext = dynamicResources.computeIfAbsent(contextAlias, s -> new HashMap<>()); + // Disable WADL as it is not used and emits a warning message about JAXB (which is also not used) resourceConfig.property(WADL_FEATURE_DISABLE, Boolean.TRUE); @@ -92,6 +104,7 @@ private void registerContext(String contextAlias, List controllers) { resourceConfig.registerInstances(new ObjectMapperProvider(typeManager.getMapper())); resourceConfig.registerInstances(new EdcApiExceptionMapper()); resourceConfig.registerInstances(new UnexpectedExceptionMapper(monitor)); + resourceConfig.registerInstances(new DynamicResourceFeature(dynamicResourcesForContext)); additionalInstances.forEach(supplier -> resourceConfig.registerInstances(supplier.get())); diff --git a/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/feature/DynamicResourceFeature.java b/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/feature/DynamicResourceFeature.java new file mode 100644 index 00000000000..bdf038497d1 --- /dev/null +++ b/extensions/common/http/jersey-core/src/main/java/org/eclipse/edc/web/jersey/feature/DynamicResourceFeature.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.web.jersey.feature; + +import jakarta.ws.rs.container.DynamicFeature; +import jakarta.ws.rs.container.ResourceInfo; +import jakarta.ws.rs.core.FeatureContext; + +import java.util.List; +import java.util.Map; + +import static java.util.Optional.ofNullable; + +/** + * A {@link DynamicFeature} that registers dynamic resources for a given resource class. + */ +public class DynamicResourceFeature implements DynamicFeature { + + private final Map, List> dynamicResources; + + public DynamicResourceFeature(Map, List> dynamicResources) { + this.dynamicResources = dynamicResources; + } + + @Override + public void configure(ResourceInfo resourceInfo, FeatureContext context) { + ofNullable(dynamicResources.get(resourceInfo.getResourceClass())) + .orElse(List.of()) + .forEach(context::register); + } +} diff --git a/extensions/common/http/jersey-core/src/test/java/org/eclipse/edc/web/jersey/feature/DynamicResourceFeatureTest.java b/extensions/common/http/jersey-core/src/test/java/org/eclipse/edc/web/jersey/feature/DynamicResourceFeatureTest.java new file mode 100644 index 00000000000..0272a84acb7 --- /dev/null +++ b/extensions/common/http/jersey-core/src/test/java/org/eclipse/edc/web/jersey/feature/DynamicResourceFeatureTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.web.jersey.feature; + +import jakarta.ws.rs.container.ResourceInfo; +import jakarta.ws.rs.core.FeatureContext; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class DynamicResourceFeatureTest { + + + @Test + void configure() { + var feature = new DynamicResourceFeature(Map.of(Target.class, List.of(new Feature()))); + var resourceInfo = mock(ResourceInfo.class); + var featureContext = mock(FeatureContext.class); + + when(resourceInfo.getResourceClass()).then((a) -> Target.class); + + feature.configure(resourceInfo, featureContext); + + verify(featureContext).register(isA(Feature.class)); + + } + + record Feature() { + + } + + record Target() { + + } +} diff --git a/spi/common/web-spi/src/main/java/org/eclipse/edc/web/spi/WebService.java b/spi/common/web-spi/src/main/java/org/eclipse/edc/web/spi/WebService.java index 8afa02dfda1..8d5304626f1 100644 --- a/spi/common/web-spi/src/main/java/org/eclipse/edc/web/spi/WebService.java +++ b/spi/common/web-spi/src/main/java/org/eclipse/edc/web/spi/WebService.java @@ -41,4 +41,13 @@ public interface WebService { */ void registerResource(String contextAlias, Object resource); + + /** + * Registers a dynamic resource (e.g. a filter) for a specific target class with the webservice, making it available for the default port mapping. + * + * @param target the target class of the dynamic resource + * @param resource a resource + */ + void registerDynamicResource(String contextAlias, Class target, Object resource); + }