From 6777c2d4cee5e0199d12ab24c2c07318a339e35b Mon Sep 17 00:00:00 2001 From: Enrico Risa Date: Wed, 11 Sep 2024 14:58:15 +0200 Subject: [PATCH] feat: introduces optional JSON-LD context for management API --- .github/workflows/publish-context.yaml | 4 +- .../edc/jsonld/JsonLdConfiguration.java | 10 ++ .../eclipse/edc/jsonld/TitaniumJsonLd.java | 11 +- .../edc/jsonld/TitaniumJsonLdTest.java | 30 +++++ .../DspApiConfigurationExtension.java | 6 + .../DspApiConfigurationExtensionTest.java | 26 ++++ .../ControlApiConfigurationExtension.java | 10 +- .../ControlApiConfigurationExtensionTest.java | 21 ++++ .../ManagementApiConfigurationExtension.java | 24 +++- ...nagementApiConfigurationExtensionTest.java | 29 +++++ .../build.gradle.kts | 48 ------- .../ManagementApiJsonLdContextExtension.java | 72 ----------- ...rg.eclipse.edc.spi.system.ServiceExtension | 15 --- ...nagementApiJsonLdContextExtensionTest.java | 46 ------- .../eclipse/edc/jsonld/JsonLdExtension.java | 16 +-- .../document/management-context-v1.jsonld | 0 .../DataPlaneSignalingClientExtension.java | 4 +- ...DataPlaneSignalingClientExtensionTest.java | 2 +- settings.gradle.kts | 1 - .../edc/spi/constants/CoreConstants.java | 1 + .../build.gradle.kts | 8 ++ .../e2e/managementapi/SerdeEndToEndTest.java | 118 ++++++++++-------- .../e2e/managementapi}/TestFunctions.java | 13 +- 23 files changed, 245 insertions(+), 270 deletions(-) delete mode 100644 extensions/common/api/management-api-json-ld-context/build.gradle.kts delete mode 100644 extensions/common/api/management-api-json-ld-context/src/main/java/org/eclipse/edc/connector/api/management/jsonld/ManagementApiJsonLdContextExtension.java delete mode 100644 extensions/common/api/management-api-json-ld-context/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension delete mode 100644 extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/ManagementApiJsonLdContextExtensionTest.java rename extensions/common/{api/management-api-json-ld-context => json-ld}/src/main/resources/document/management-context-v1.jsonld (100%) rename extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/SerdeIntegrationTest.java => system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/SerdeEndToEndTest.java (83%) rename {extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde => system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi}/TestFunctions.java (96%) diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index 10026258b05..f4a780d68c5 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -26,7 +26,7 @@ on: push: branches: [ main ] paths: - - 'extensions/common/api/management-api-json-ld-context/src/main/resources/document/**' + - 'extensions/common/json-ld/src/main/resources/document/**' jobs: build: @@ -39,7 +39,7 @@ jobs: - name: copy contexts into public folder run: | mkdir -p public/context - cp extensions/common/api/management-api-json-ld-context/src/main/resources/document/management-context-v1.jsonld public/context/ + cp extensions/common/json-ld/src/main/resources/document/management-context-v1.jsonld public/context/ - name: deploy to gh-pages uses: peaceiris/actions-gh-pages@v4 with: diff --git a/core/common/lib/json-ld-lib/src/main/java/org/eclipse/edc/jsonld/JsonLdConfiguration.java b/core/common/lib/json-ld-lib/src/main/java/org/eclipse/edc/jsonld/JsonLdConfiguration.java index da514aae421..f48f957f0ad 100644 --- a/core/common/lib/json-ld-lib/src/main/java/org/eclipse/edc/jsonld/JsonLdConfiguration.java +++ b/core/common/lib/json-ld-lib/src/main/java/org/eclipse/edc/jsonld/JsonLdConfiguration.java @@ -18,6 +18,7 @@ public class JsonLdConfiguration { private boolean httpEnabled = false; private boolean httpsEnabled = false; + private boolean avoidVocab = false; private boolean checkPrefixes = true; private JsonLdConfiguration() { @@ -36,6 +37,10 @@ public boolean shouldCheckPrefixes() { return checkPrefixes; } + public boolean isAvoidVocab() { + return avoidVocab; + } + public static class Builder { private final JsonLdConfiguration configuration = new JsonLdConfiguration(); @@ -54,6 +59,11 @@ public Builder httpsEnabled(boolean httpsEnabled) { return this; } + public Builder avoidVocab(boolean avoidVocab) { + configuration.avoidVocab = avoidVocab; + return this; + } + public Builder checkPrefixes(boolean checkPrefixes) { configuration.checkPrefixes = checkPrefixes; return this; diff --git a/core/common/lib/json-ld-lib/src/main/java/org/eclipse/edc/jsonld/TitaniumJsonLd.java b/core/common/lib/json-ld-lib/src/main/java/org/eclipse/edc/jsonld/TitaniumJsonLd.java index 4dfb2d90829..10cdebc422f 100644 --- a/core/common/lib/json-ld-lib/src/main/java/org/eclipse/edc/jsonld/TitaniumJsonLd.java +++ b/core/common/lib/json-ld-lib/src/main/java/org/eclipse/edc/jsonld/TitaniumJsonLd.java @@ -49,6 +49,7 @@ import static jakarta.json.Json.createBuilderFactory; import static jakarta.json.Json.createObjectBuilder; import static java.util.Optional.ofNullable; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; /** * Implementation of the {@link JsonLd} interface that uses the Titanium library for all JSON-LD operations. @@ -66,6 +67,7 @@ public class TitaniumJsonLd implements JsonLd { private final JsonObjectValidator validator; private final boolean shouldCheckPrefixes; + private final boolean isVocabEnabled; public TitaniumJsonLd(Monitor monitor) { this(monitor, JsonLdConfiguration.Builder.newInstance().build()); @@ -75,6 +77,7 @@ public TitaniumJsonLd(Monitor monitor, JsonLdConfiguration configuration) { this.monitor = monitor; this.documentLoader = new CachedDocumentLoader(configuration, monitor); this.shouldCheckPrefixes = configuration.shouldCheckPrefixes(); + this.isVocabEnabled = configuration.isAvoidVocab(); this.validator = JsonObjectValidator.newValidator() .verify((path) -> new MissingPrefixes(path, this::getAllPrefixes)) .build(); @@ -124,6 +127,10 @@ public Result compact(JsonObject json, String scope) { @Override public void registerNamespace(String prefix, String contextIri, String scope) { + // skip the @vocab if it's not enabled + if (isVocabEnabled && VOCAB.equals(prefix)) { + return; + } var namespaces = scopedNamespaces.computeIfAbsent(scope, k -> new LinkedHashMap<>()); namespaces.put(prefix, contextIri); } @@ -146,9 +153,9 @@ private JsonObject injectVocab(JsonObject json) { if (json.get(JsonLdKeywords.CONTEXT) instanceof JsonObject) { var contextObject = ofNullable(json.getJsonObject(JsonLdKeywords.CONTEXT)).orElseGet(() -> createObjectBuilder().build()); var contextBuilder = createObjectBuilder(contextObject); - if (!contextObject.containsKey(JsonLdKeywords.VOCAB)) { + if (!contextObject.containsKey(VOCAB)) { var newContextObject = contextBuilder - .add(JsonLdKeywords.VOCAB, CoreConstants.EDC_NAMESPACE) + .add(VOCAB, CoreConstants.EDC_NAMESPACE) .build(); jsonObjectBuilder.add(JsonLdKeywords.CONTEXT, newContextObject); } diff --git a/core/common/lib/json-ld-lib/src/test/java/org/eclipse/edc/jsonld/TitaniumJsonLdTest.java b/core/common/lib/json-ld-lib/src/test/java/org/eclipse/edc/jsonld/TitaniumJsonLdTest.java index 7353a421a30..96ede6d4568 100644 --- a/core/common/lib/json-ld-lib/src/test/java/org/eclipse/edc/jsonld/TitaniumJsonLdTest.java +++ b/core/common/lib/json-ld-lib/src/test/java/org/eclipse/edc/jsonld/TitaniumJsonLdTest.java @@ -33,7 +33,9 @@ import static jakarta.json.Json.createArrayBuilder; import static jakarta.json.Json.createObjectBuilder; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.mockito.Mockito.mock; class TitaniumJsonLdTest { @@ -147,6 +149,34 @@ void compact() { }); } + @Test + void compact_withVocab() { + var expanded = Json.createObjectBuilder() + .add(EDC_NAMESPACE + "item", "test") + .build(); + var jsonLd = defaultService(); + jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE); + var compacted = jsonLd.compact(expanded); + + assertThat(compacted).isSucceeded().satisfies(c -> { + Assertions.assertThat(c.getString("item")).isEqualTo("test"); + }); + } + + @Test + void compact_withVocabDisabled() { + var expanded = Json.createObjectBuilder() + .add(EDC_NAMESPACE + "item", "test") + .build(); + var jsonLd = defaultService(JsonLdConfiguration.Builder.newInstance().avoidVocab(true).build()); + jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE); + var compacted = jsonLd.compact(expanded); + + assertThat(compacted).isSucceeded().satisfies(c -> { + Assertions.assertThat(c.getString(EDC_NAMESPACE + "item")).isEqualTo("test"); + }); + } + @Test void compact_withCustomPrefix() { var ns = "https://test.org/schema/"; 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 7754527042b..33d2c788f6a 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 @@ -52,6 +52,7 @@ import java.util.Map; import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_PREFIX; import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_SCHEMA; import static org.eclipse.edc.jsonld.spi.Namespaces.DCT_PREFIX; @@ -61,6 +62,8 @@ 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.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; /** @@ -122,6 +125,9 @@ public void initialize(ServiceExtensionContext context) { 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); + webService.registerResource(ApiContext.PROTOCOL, new ObjectMapperProvider(jsonLdMapper)); webService.registerResource(ApiContext.PROTOCOL, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE)); 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 2226cfc3d77..1f628f7d1b4 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 @@ -14,6 +14,7 @@ package org.eclipse.edc.protocol.dsp.http.api.configuration; +import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.protocol.ProtocolWebhook; import org.eclipse.edc.spi.system.Hostname; @@ -36,8 +37,18 @@ import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_PREFIX; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_SCHEMA; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCT_PREFIX; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCT_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.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.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; @@ -52,6 +63,8 @@ class DspApiConfigurationExtensionTest { private final WebServer webServer = mock(); private final WebService webService = mock(); private final TypeManager typeManager = mock(); + private final JsonLd jsonLd = mock(); + @BeforeEach void setUp(ServiceExtensionContext context) { @@ -60,6 +73,7 @@ void setUp(ServiceExtensionContext context) { context.registerService(WebServiceConfigurer.class, configurer); context.registerService(TypeManager.class, typeManager); context.registerService(Hostname.class, () -> "hostname"); + context.registerService(JsonLd.class, jsonLd); TypeTransformerRegistry typeTransformerRegistry = mock(); when(typeTransformerRegistry.forContext(any())).thenReturn(mock()); context.registerService(TypeTransformerRegistry.class, typeTransformerRegistry); @@ -105,4 +119,16 @@ void initialize_shouldRegisterWebServiceProviders(DspApiConfigurationExtension e verify(webService).registerResource(eq(ApiContext.PROTOCOL), isA(JerseyJsonLdInterceptor.class)); } + @Test + void initialize_shouldRegisterNamespaces(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); + } + } diff --git a/extensions/common/api/control-api-configuration/src/main/java/org/eclipse/edc/connector/api/control/configuration/ControlApiConfigurationExtension.java b/extensions/common/api/control-api-configuration/src/main/java/org/eclipse/edc/connector/api/control/configuration/ControlApiConfigurationExtension.java index b0cc21867e9..f3aa5c965e3 100644 --- a/extensions/common/api/control-api-configuration/src/main/java/org/eclipse/edc/connector/api/control/configuration/ControlApiConfigurationExtension.java +++ b/extensions/common/api/control-api-configuration/src/main/java/org/eclipse/edc/connector/api/control/configuration/ControlApiConfigurationExtension.java @@ -45,10 +45,13 @@ import java.util.stream.Stream; import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_PREFIX; 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.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; /** @@ -63,12 +66,10 @@ public class ControlApiConfigurationExtension implements ServiceExtension { @Setting(value = "Configures endpoint for reaching the Control API. If it's missing it defaults to the hostname configuration.") public static final String CONTROL_API_ENDPOINT = "edc.control.endpoint"; - + public static final String CONTROL_SCOPE = "CONTROL_API"; private static final String WEB_SERVICE_NAME = "Control API"; - @SettingContext("Control API context setting key") private static final String CONTROL_CONFIG_KEY = "web.http." + ApiContext.CONTROL; - public static final WebServiceSettings SETTINGS = WebServiceSettings.Builder.newInstance() .apiConfigKey(CONTROL_CONFIG_KEY) .contextAlias(ApiContext.CONTROL) @@ -77,7 +78,6 @@ public class ControlApiConfigurationExtension implements ServiceExtension { .useDefaultContext(true) .name(WEB_SERVICE_NAME) .build(); - private static final String CONTROL_SCOPE = "CONTROL_API"; private static final String API_VERSION_JSON_FILE = "control-api-version.json"; @Inject @@ -110,6 +110,8 @@ public void initialize(ServiceExtensionContext context) { var jsonLdMapper = typeManager.getMapper(JSON_LD); context.registerService(ControlApiUrl.class, controlApiUrl(context, controlApiConfiguration)); + jsonLd.registerNamespace(EDC_PREFIX, EDC_NAMESPACE, CONTROL_SCOPE); + jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE, CONTROL_SCOPE); jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, CONTROL_SCOPE); jsonLd.registerNamespace(DSPACE_PREFIX, DSPACE_SCHEMA, CONTROL_SCOPE); diff --git a/extensions/common/api/control-api-configuration/src/test/java/org/eclipse/edc/connector/api/control/configuration/ControlApiConfigurationExtensionTest.java b/extensions/common/api/control-api-configuration/src/test/java/org/eclipse/edc/connector/api/control/configuration/ControlApiConfigurationExtensionTest.java index deaee9af35e..adec7a82ce8 100644 --- a/extensions/common/api/control-api-configuration/src/test/java/org/eclipse/edc/connector/api/control/configuration/ControlApiConfigurationExtensionTest.java +++ b/extensions/common/api/control-api-configuration/src/test/java/org/eclipse/edc/connector/api/control/configuration/ControlApiConfigurationExtensionTest.java @@ -16,6 +16,7 @@ import org.eclipse.edc.api.auth.spi.AuthenticationRequestFilter; import org.eclipse.edc.json.JacksonTypeManager; +import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.system.Hostname; @@ -33,6 +34,14 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.edc.connector.api.control.configuration.ControlApiConfigurationExtension.CONTROL_API_ENDPOINT; +import static org.eclipse.edc.connector.api.control.configuration.ControlApiConfigurationExtension.CONTROL_SCOPE; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; +import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_PREFIX; +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.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; @@ -45,6 +54,7 @@ public class ControlApiConfigurationExtensionTest { private final WebServiceConfigurer configurator = mock(); private final WebService webService = mock(); + private final JsonLd jsonLd = mock(); private final WebServiceConfiguration webServiceConfiguration = WebServiceConfiguration.Builder.newInstance() .path("/path") @@ -57,6 +67,7 @@ void setUp(ServiceExtensionContext context) { context.registerService(Hostname.class, () -> "hostname"); context.registerService(WebService.class, webService); context.registerService(TypeManager.class, new JacksonTypeManager()); + context.registerService(JsonLd.class, jsonLd); when(configurator.configure(any(), any(), any())).thenReturn(webServiceConfiguration); } @@ -98,4 +109,14 @@ void shouldRegisterAuthenticationFilter(ControlApiConfigurationExtension extensi verify(webService).registerResource(any(), isA(AuthenticationRequestFilter.class)); } + + @Test + void shouldRegisterNamespaces(ControlApiConfigurationExtension extension, ServiceExtensionContext context) { + extension.initialize(context); + + jsonLd.registerNamespace(EDC_PREFIX, EDC_NAMESPACE, CONTROL_SCOPE); + jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE, CONTROL_SCOPE); + jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, CONTROL_SCOPE); + jsonLd.registerNamespace(DSPACE_PREFIX, DSPACE_SCHEMA, CONTROL_SCOPE); + } } diff --git a/extensions/common/api/management-api-configuration/src/main/java/org/eclipse/edc/connector/api/management/configuration/ManagementApiConfigurationExtension.java b/extensions/common/api/management-api-configuration/src/main/java/org/eclipse/edc/connector/api/management/configuration/ManagementApiConfigurationExtension.java index 4335de44688..24c101c7a89 100644 --- a/extensions/common/api/management-api-configuration/src/main/java/org/eclipse/edc/connector/api/management/configuration/ManagementApiConfigurationExtension.java +++ b/extensions/common/api/management-api-configuration/src/main/java/org/eclipse/edc/connector/api/management/configuration/ManagementApiConfigurationExtension.java @@ -61,8 +61,12 @@ import java.util.stream.Stream; import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; 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.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; /** @@ -75,10 +79,10 @@ public class ManagementApiConfigurationExtension implements ServiceExtension { public static final String API_VERSION_JSON_FILE = "management-api-version.json"; public static final String NAME = "Management API configuration"; public static final String WEB_SERVICE_NAME = "Management API"; + public static final String MANAGEMENT_SCOPE = "MANAGEMENT_API"; @SettingContext("Management API context setting key") private static final String MANAGEMENT_CONFIG_KEY = "web.http." + ApiContext.MANAGEMENT; - public static final WebServiceSettings SETTINGS = WebServiceSettings.Builder.newInstance() .apiConfigKey(MANAGEMENT_CONFIG_KEY) .contextAlias(ApiContext.MANAGEMENT) @@ -87,11 +91,14 @@ public class ManagementApiConfigurationExtension implements ServiceExtension { .useDefaultContext(true) .name(WEB_SERVICE_NAME) .build(); - private static final String MANAGEMENT_SCOPE = "MANAGEMENT_API"; - @Setting(value = "Configures endpoint for reaching the Management API.", defaultValue = "") private static final String MANAGEMENT_API_ENDPOINT = "edc.management.endpoint"; + private static final boolean DEFAULT_MANAGEMENT_API_ENABLE_CONTEXT = false; + + @Setting(value = "If set enable the usage of management api JSON-LD context.", defaultValue = "" + DEFAULT_MANAGEMENT_API_ENABLE_CONTEXT) + private static final String MANAGEMENT_API_ENABLE_CONTEXT = "edc.management.context.enabled"; + @Inject private WebService webService; @Inject @@ -129,7 +136,16 @@ public void initialize(ServiceExtensionContext context) { var authenticationFilter = new AuthenticationRequestFilter(authenticationRegistry, "management-api"); webService.registerResource(ApiContext.MANAGEMENT, authenticationFilter); - jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, MANAGEMENT_SCOPE); + var isManagementContextEnabled = context.getSetting(MANAGEMENT_API_ENABLE_CONTEXT, DEFAULT_MANAGEMENT_API_ENABLE_CONTEXT); + + if (isManagementContextEnabled) { + jsonLd.registerContext(EDC_CONNECTOR_MANAGEMENT_CONTEXT, MANAGEMENT_SCOPE); + } else { + jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE, MANAGEMENT_SCOPE); + jsonLd.registerNamespace(EDC_PREFIX, EDC_NAMESPACE, MANAGEMENT_SCOPE); + jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, MANAGEMENT_SCOPE); + } + var jsonLdMapper = typeManager.getMapper(JSON_LD); webService.registerResource(ApiContext.MANAGEMENT, new ObjectMapperProvider(jsonLdMapper)); webService.registerResource(ApiContext.MANAGEMENT, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, MANAGEMENT_SCOPE)); diff --git a/extensions/common/api/management-api-configuration/src/test/java/org/eclipse/edc/connector/api/management/configuration/ManagementApiConfigurationExtensionTest.java b/extensions/common/api/management-api-configuration/src/test/java/org/eclipse/edc/connector/api/management/configuration/ManagementApiConfigurationExtensionTest.java index 8d995aad2ae..67abaee4371 100644 --- a/extensions/common/api/management-api-configuration/src/test/java/org/eclipse/edc/connector/api/management/configuration/ManagementApiConfigurationExtensionTest.java +++ b/extensions/common/api/management-api-configuration/src/test/java/org/eclipse/edc/connector/api/management/configuration/ManagementApiConfigurationExtensionTest.java @@ -18,6 +18,7 @@ import org.eclipse.edc.boot.system.DefaultServiceExtensionContext; import org.eclipse.edc.boot.system.injection.ObjectFactory; import org.eclipse.edc.json.JacksonTypeManager; +import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.system.ServiceExtensionContext; @@ -36,11 +37,21 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import java.util.Map; + +import static org.eclipse.edc.connector.api.management.configuration.ManagementApiConfigurationExtension.MANAGEMENT_SCOPE; import static org.eclipse.edc.connector.api.management.configuration.ManagementApiConfigurationExtension.SETTINGS; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; +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.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT; +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; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -50,6 +61,7 @@ class ManagementApiConfigurationExtensionTest { private final WebServiceConfigurer configurer = mock(); private final Monitor monitor = mock(); private final WebService webService = mock(); + private final JsonLd jsonLd = mock(); private ManagementApiConfigurationExtension extension; @BeforeEach @@ -60,6 +72,7 @@ void setUp(ServiceExtensionContext context, ObjectFactory factory) { context.registerService(WebServiceConfigurer.class, configurer); context.registerService(TypeTransformerRegistry.class, typeTransformerRegistry); context.registerService(TypeManager.class, new JacksonTypeManager()); + context.registerService(JsonLd.class, jsonLd); extension = factory.constructInstance(ManagementApiConfigurationExtension.class); } @@ -75,6 +88,22 @@ void initialize_shouldConfigureAndRegisterResource() { verify(webService).registerResource(eq(ApiContext.MANAGEMENT), isA(AuthenticationRequestFilter.class)); verify(webService).registerResource(eq(ApiContext.MANAGEMENT), isA(JerseyJsonLdInterceptor.class)); verify(webService).registerResource(eq(ApiContext.MANAGEMENT), isA(ObjectMapperProvider.class)); + + verify(jsonLd).registerNamespace(VOCAB, EDC_NAMESPACE, MANAGEMENT_SCOPE); + verify(jsonLd).registerNamespace(EDC_PREFIX, EDC_NAMESPACE, MANAGEMENT_SCOPE); + verify(jsonLd).registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, MANAGEMENT_SCOPE); + } + + @Test + void initialize_WithContextEnabled() { + var context = contextWithConfig(ConfigFactory.fromMap(Map.of("edc.management.context.enabled", "true"))); + var configuration = WebServiceConfiguration.Builder.newInstance().path("/path").port(1234).build(); + when(configurer.configure(any(), any(), any())).thenReturn(configuration); + + extension.initialize(context); + + verify(jsonLd, times(0)).registerNamespace(any(), any(), any()); + verify(jsonLd).registerContext(EDC_CONNECTOR_MANAGEMENT_CONTEXT, MANAGEMENT_SCOPE); } @NotNull diff --git a/extensions/common/api/management-api-json-ld-context/build.gradle.kts b/extensions/common/api/management-api-json-ld-context/build.gradle.kts deleted file mode 100644 index e27cf312b9e..00000000000 --- a/extensions/common/api/management-api-json-ld-context/build.gradle.kts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 - * - */ - -plugins { - `java-library` -} - -dependencies { - api(project(":spi:common:json-ld-spi")) - - implementation(project(":core:common:lib:transform-lib")) - implementation(project(":core:control-plane:control-plane-transform")) - - testImplementation(project(":spi:common:edr-store-spi")) - testImplementation(project(":core:common:connector-core")) - testImplementation(project(":core:control-plane:control-plane-transform")) - testImplementation(project(":core:common:junit")) - testImplementation(project(":core:common:lib:json-ld-lib")) - testImplementation(project(":extensions:common:json-ld")) - testImplementation(project(":extensions:common:http:jetty-core")) - testImplementation(project(":extensions:common:http:jersey-core")) - testImplementation(project(":extensions:common:api:management-api-configuration")) - testImplementation(project(":extensions:control-plane:api:management-api:contract-definition-api")) - testImplementation(project(":extensions:control-plane:api:management-api:contract-negotiation-api")) - testImplementation(project(":extensions:control-plane:api:management-api:policy-definition-api")) - testImplementation(project(":extensions:control-plane:api:management-api:transfer-process-api")) - testImplementation(project(":extensions:control-plane:api:management-api:secrets-api")) - testImplementation(project(":extensions:control-plane:api:management-api:edr-cache-api")) -} - -edcBuild { - swagger { - apiGroup.set("management-api") - } -} - - diff --git a/extensions/common/api/management-api-json-ld-context/src/main/java/org/eclipse/edc/connector/api/management/jsonld/ManagementApiJsonLdContextExtension.java b/extensions/common/api/management-api-json-ld-context/src/main/java/org/eclipse/edc/connector/api/management/jsonld/ManagementApiJsonLdContextExtension.java deleted file mode 100644 index 2e6b22954d6..00000000000 --- a/extensions/common/api/management-api-json-ld-context/src/main/java/org/eclipse/edc/connector/api/management/jsonld/ManagementApiJsonLdContextExtension.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.connector.api.management.jsonld; - -import org.eclipse.edc.jsonld.spi.JsonLd; -import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.jetbrains.annotations.NotNull; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Map; - -import static java.lang.String.format; - -public class ManagementApiJsonLdContextExtension implements ServiceExtension { - - public static final String EDC_CONNECTOR_MANAGEMENT_CONTEXT = "https://w3id.org/edc/connector/management/v0.0.1"; - public static final String EDC_CONNECTOR_MANAGEMENT_SCOPE = "MANAGEMENT_API"; - - private static final String PREFIX = "document/"; - private static final Map FILES = Map.of( - EDC_CONNECTOR_MANAGEMENT_CONTEXT, PREFIX + "management-context-v1.jsonld"); - - @Inject - private JsonLd jsonLdService; - - @Inject - private Monitor monitor; - - @Override - public void initialize(ServiceExtensionContext context) { - jsonLdService.registerContext(EDC_CONNECTOR_MANAGEMENT_CONTEXT, EDC_CONNECTOR_MANAGEMENT_SCOPE); - FILES.entrySet().stream().map(this::mapToUri) - .forEach(result -> result.onSuccess(entry -> jsonLdService.registerCachedDocument(entry.getKey(), entry.getValue())) - .onFailure(failure -> monitor.warning("Failed to register cached json-ld document: " + failure.getFailureDetail()))); - } - - private Result> mapToUri(Map.Entry fileEntry) { - return getResourceUri(fileEntry.getValue()) - .map(file1 -> Map.entry(fileEntry.getKey(), file1)); - } - - @NotNull - private Result getResourceUri(String name) { - var uri = getClass().getClassLoader().getResource(name); - if (uri == null) { - return Result.failure(format("Cannot find resource %s", name)); - } - - try { - return Result.success(uri.toURI()); - } catch (URISyntaxException e) { - return Result.failure(format("Cannot read resource %s: %s", name, e.getMessage())); - } - } -} diff --git a/extensions/common/api/management-api-json-ld-context/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/common/api/management-api-json-ld-context/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension deleted file mode 100644 index ffbadb7fee3..00000000000 --- a/extensions/common/api/management-api-json-ld-context/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ /dev/null @@ -1,15 +0,0 @@ -# -# 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 -# -# - -org.eclipse.edc.connector.api.management.jsonld.ManagementApiJsonLdContextExtension \ No newline at end of file diff --git a/extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/ManagementApiJsonLdContextExtensionTest.java b/extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/ManagementApiJsonLdContextExtensionTest.java deleted file mode 100644 index 6590f4b4fe7..00000000000 --- a/extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/ManagementApiJsonLdContextExtensionTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.connector.api.management.jsonld.serde; - -import org.eclipse.edc.connector.api.management.jsonld.ManagementApiJsonLdContextExtension; -import org.eclipse.edc.jsonld.spi.JsonLd; -import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import static org.eclipse.edc.connector.api.management.jsonld.ManagementApiJsonLdContextExtension.EDC_CONNECTOR_MANAGEMENT_CONTEXT; -import static org.eclipse.edc.connector.api.management.jsonld.ManagementApiJsonLdContextExtension.EDC_CONNECTOR_MANAGEMENT_SCOPE; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -@ExtendWith(DependencyInjectionExtension.class) -class ManagementApiJsonLdContextExtensionTest { - - private final JsonLd jsonLd = mock(); - private ManagementApiJsonLdContextExtension extension; - - @BeforeEach - void setup(ServiceExtensionContext context) { - context.registerService(JsonLd.class, jsonLd); - } - - @Test - void initialize(ManagementApiJsonLdContextExtension extension, ServiceExtensionContext context) { - extension.initialize(context); - verify(jsonLd).registerContext(EDC_CONNECTOR_MANAGEMENT_CONTEXT, EDC_CONNECTOR_MANAGEMENT_SCOPE); - } -} diff --git a/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/JsonLdExtension.java b/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/JsonLdExtension.java index 89194c80aae..39afe3a20f5 100644 --- a/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/JsonLdExtension.java +++ b/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/JsonLdExtension.java @@ -15,7 +15,6 @@ package org.eclipse.edc.jsonld; import org.eclipse.edc.jsonld.spi.JsonLd; -import org.eclipse.edc.jsonld.spi.JsonLdKeywords; import org.eclipse.edc.jsonld.spi.transformer.JsonLdTransformer; import org.eclipse.edc.jsonld.util.JacksonJsonLd; import org.eclipse.edc.runtime.metamodel.annotation.BaseExtension; @@ -36,8 +35,7 @@ import java.util.stream.Stream; import static java.lang.String.format; -import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; -import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT; import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; /** @@ -64,8 +62,8 @@ public class JsonLdExtension implements ServiceExtension { private static final String HTTP_ENABLE_SETTING = "edc.jsonld.http.enabled"; @Setting(value = "If set enable https json-ld document resolution", type = "boolean", defaultValue = DEFAULT_HTTP_HTTPS_RESOLUTION + "") private static final String HTTPS_ENABLE_SETTING = "edc.jsonld.https.enabled"; - private static final String DEFAULT_AVOID_VOCAB_CONTEXT = "false"; - @Setting(value = "If true disable the @vocab context definition. This could be used to avoid api breaking changes", type = "boolean", defaultValue = DEFAULT_AVOID_VOCAB_CONTEXT) + private static final boolean DEFAULT_AVOID_VOCAB_CONTEXT = false; + @Setting(value = "If true disable the @vocab context definition. This could be used to avoid api breaking changes", type = "boolean", defaultValue = DEFAULT_AVOID_VOCAB_CONTEXT + "") private static final String AVOID_VOCAB_CONTEXT = "edc.jsonld.vocab.disable"; private static final boolean DEFAULT_CHECK_PREFIXES = true; @Setting(value = "If true a validation on expended object will be made against configured prefixes", type = "boolean", defaultValue = DEFAULT_CHECK_PREFIXES + "") @@ -90,18 +88,16 @@ public JsonLd createJsonLdService(ServiceExtensionContext context) { var configuration = JsonLdConfiguration.Builder.newInstance() .httpEnabled(config.getBoolean(HTTP_ENABLE_SETTING, DEFAULT_HTTP_HTTPS_RESOLUTION)) .httpsEnabled(config.getBoolean(HTTPS_ENABLE_SETTING, DEFAULT_HTTP_HTTPS_RESOLUTION)) + .avoidVocab(config.getBoolean(AVOID_VOCAB_CONTEXT, DEFAULT_AVOID_VOCAB_CONTEXT)) .checkPrefixes(config.getBoolean(CHECK_PREFIXES, DEFAULT_CHECK_PREFIXES)) .build(); var monitor = context.getMonitor(); var service = new TitaniumJsonLd(monitor, configuration); - if (!config.getBoolean(AVOID_VOCAB_CONTEXT, Boolean.valueOf(DEFAULT_AVOID_VOCAB_CONTEXT))) { - service.registerNamespace(JsonLdKeywords.VOCAB, EDC_NAMESPACE); - } - service.registerNamespace(EDC_PREFIX, EDC_NAMESPACE); Stream.of( new JsonLdContext("odrl.jsonld", "http://www.w3.org/ns/odrl.jsonld"), - new JsonLdContext("dspace.jsonld", "https://w3id.org/dspace/2024/1/context.json") + new JsonLdContext("dspace.jsonld", "https://w3id.org/dspace/2024/1/context.json"), + new JsonLdContext("management-context-v1.jsonld", EDC_CONNECTOR_MANAGEMENT_CONTEXT) ).forEach(jsonLdContext -> getResourceUri("document/" + jsonLdContext.fileName()) .onSuccess(uri -> service.registerCachedDocument(jsonLdContext.url(), uri)) .onFailure(failure -> monitor.warning("Failed to register cached json-ld document: " + failure.getFailureDetail())) diff --git a/extensions/common/api/management-api-json-ld-context/src/main/resources/document/management-context-v1.jsonld b/extensions/common/json-ld/src/main/resources/document/management-context-v1.jsonld similarity index 100% rename from extensions/common/api/management-api-json-ld-context/src/main/resources/document/management-context-v1.jsonld rename to extensions/common/json-ld/src/main/resources/document/management-context-v1.jsonld diff --git a/extensions/data-plane/data-plane-signaling/data-plane-signaling-client/src/main/java/org/eclipse/edc/connector/dataplane/client/DataPlaneSignalingClientExtension.java b/extensions/data-plane/data-plane-signaling/data-plane-signaling-client/src/main/java/org/eclipse/edc/connector/dataplane/client/DataPlaneSignalingClientExtension.java index 987886313c8..aa42ad92e4f 100644 --- a/extensions/data-plane/data-plane-signaling/data-plane-signaling-client/src/main/java/org/eclipse/edc/connector/dataplane/client/DataPlaneSignalingClientExtension.java +++ b/extensions/data-plane/data-plane-signaling/data-plane-signaling-client/src/main/java/org/eclipse/edc/connector/dataplane/client/DataPlaneSignalingClientExtension.java @@ -69,10 +69,10 @@ public DataPlaneClientFactory dataPlaneClientFactory(ServiceExtensionContext con context.getMonitor().debug(() -> "Using embedded Data Plane client."); return instance -> new EmbeddedDataPlaneClient(dataPlaneManager); } - + jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, CONTROL_CLIENT_SCOPE); jsonLd.registerNamespace(DSPACE_PREFIX, DSPACE_SCHEMA, CONTROL_CLIENT_SCOPE); - jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE); + jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE, CONTROL_CLIENT_SCOPE); var mapper = typeManager.getMapper(JSON_LD); context.getMonitor().debug(() -> "Using remote Data Plane client."); diff --git a/extensions/data-plane/data-plane-signaling/data-plane-signaling-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneSignalingClientExtensionTest.java b/extensions/data-plane/data-plane-signaling/data-plane-signaling-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneSignalingClientExtensionTest.java index 2a8794e7ff7..ab5f4f7e4e9 100644 --- a/extensions/data-plane/data-plane-signaling/data-plane-signaling-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneSignalingClientExtensionTest.java +++ b/extensions/data-plane/data-plane-signaling/data-plane-signaling-client/src/test/java/org/eclipse/edc/connector/dataplane/client/DataPlaneSignalingClientExtensionTest.java @@ -49,7 +49,7 @@ void verifyDataPlaneClientFactory(ServiceExtensionContext context, ObjectFactory assertThat(client).isInstanceOf(DataPlaneSignalingClient.class); verify(jsonLd).registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, CONTROL_CLIENT_SCOPE); verify(jsonLd).registerNamespace(DSPACE_PREFIX, DSPACE_SCHEMA, CONTROL_CLIENT_SCOPE); - verify(jsonLd).registerNamespace(VOCAB, EDC_NAMESPACE); + verify(jsonLd).registerNamespace(VOCAB, EDC_NAMESPACE, CONTROL_CLIENT_SCOPE); } @Test diff --git a/settings.gradle.kts b/settings.gradle.kts index e1bee6771db..db71b6de668 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -158,7 +158,6 @@ include(":extensions:common:store:sql:edr-index-sql") include(":extensions:common:api:control-api-configuration") include(":extensions:common:api:management-api-configuration") -include(":extensions:common:api:management-api-json-ld-context") include(":extensions:control-plane:api:control-plane-api") diff --git a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/constants/CoreConstants.java b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/constants/CoreConstants.java index 8790174990b..a1fca4436ff 100644 --- a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/constants/CoreConstants.java +++ b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/constants/CoreConstants.java @@ -18,4 +18,5 @@ public interface CoreConstants { String JSON_LD = "json-ld"; String EDC_PREFIX = "edc"; String EDC_NAMESPACE = "https://w3id.org/edc/v0.0.1/ns/"; + String EDC_CONNECTOR_MANAGEMENT_CONTEXT = "https://w3id.org/edc/connector/management/v0.0.1"; } diff --git a/system-tests/management-api/management-api-test-runner/build.gradle.kts b/system-tests/management-api/management-api-test-runner/build.gradle.kts index b6157e96f5e..2a91d8a3f83 100644 --- a/system-tests/management-api/management-api-test-runner/build.gradle.kts +++ b/system-tests/management-api/management-api-test-runner/build.gradle.kts @@ -24,6 +24,7 @@ dependencies { testImplementation(project(":spi:control-plane:contract-spi")) testImplementation(project(":spi:data-plane-selector:data-plane-selector-spi")) testImplementation(project(":core:common:connector-core")) + testImplementation(project(":core:common:edr-store-core")) //useful for generic DTOs etc. testImplementation(project(":extensions:common:api:api-core")) @@ -42,6 +43,13 @@ dependencies { testImplementation(project(":extensions:common:transaction:transaction-local")) testImplementation(libs.testcontainers.junit) testImplementation(libs.testcontainers.postgres) + + testImplementation(project(":extensions:control-plane:api:management-api:contract-definition-api")) + testImplementation(project(":extensions:control-plane:api:management-api:contract-negotiation-api")) + testImplementation(project(":extensions:control-plane:api:management-api:policy-definition-api")) + testImplementation(project(":extensions:control-plane:api:management-api:transfer-process-api")) + testImplementation(project(":extensions:control-plane:api:management-api:secrets-api")) + testImplementation(project(":extensions:control-plane:api:management-api:edr-cache-api")) } edcBuild { diff --git a/extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/SerdeIntegrationTest.java b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/SerdeEndToEndTest.java similarity index 83% rename from extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/SerdeIntegrationTest.java rename to system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/SerdeEndToEndTest.java index 5cae1e91f67..ea4ad1b68fb 100644 --- a/extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/SerdeIntegrationTest.java +++ b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/SerdeEndToEndTest.java @@ -12,12 +12,13 @@ * */ -package org.eclipse.edc.connector.api.management.jsonld.serde; +package org.eclipse.edc.test.e2e.managementapi; import jakarta.json.Json; import jakarta.json.JsonObject; import jakarta.json.JsonString; import jakarta.json.JsonValue; +import org.assertj.core.api.Assertions; import org.eclipse.edc.connector.controlplane.api.management.contractnegotiation.model.NegotiationState; import org.eclipse.edc.connector.controlplane.api.management.policy.model.PolicyEvaluationPlanRequest; import org.eclipse.edc.connector.controlplane.api.management.policy.model.PolicyValidationResult; @@ -29,18 +30,12 @@ import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractRequest; import org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition; import org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition; -import org.eclipse.edc.connector.controlplane.services.spi.contractdefinition.ContractDefinitionService; -import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationService; -import org.eclipse.edc.connector.controlplane.services.spi.policydefinition.PolicyDefinitionService; -import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessService; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest; -import org.eclipse.edc.connector.spi.service.SecretService; -import org.eclipse.edc.edr.spi.store.EndpointDataReferenceStore; import org.eclipse.edc.jsonld.spi.JsonLd; -import org.eclipse.edc.junit.annotations.ComponentTest; +import org.eclipse.edc.junit.annotations.EndToEndTest; +import org.eclipse.edc.junit.extensions.EmbeddedRuntime; import org.eclipse.edc.junit.extensions.RuntimeExtension; -import org.eclipse.edc.junit.extensions.RuntimePerClassExtension; import org.eclipse.edc.policy.model.AndConstraint; import org.eclipse.edc.policy.model.AtomicConstraint; import org.eclipse.edc.policy.model.LiteralExpression; @@ -57,8 +52,8 @@ import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; +import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -68,56 +63,38 @@ import static jakarta.json.Json.createObjectBuilder; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.MANAGEMENT_API_CONTEXT; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.MANAGEMENT_API_SCOPE; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.assetObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.contractDefinitionObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.contractRequestObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createContractAgreement; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createContractNegotiation; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createEdrEntry; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createPolicyEvaluationPlan; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createTransferProcess; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.dataAddressObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.inForceDatePermission; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.policyDefinitionObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.policyEvaluationPlanRequest; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.querySpecObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.secretObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.suspendTransferObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.terminateNegotiationObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.terminateTransferObject; -import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.transferRequestObject; import static org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiationStates.REQUESTED; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.MANAGEMENT_API_CONTEXT; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.MANAGEMENT_API_SCOPE; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.assetObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.contractDefinitionObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.contractRequestObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.createContractAgreement; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.createContractNegotiation; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.createEdrEntry; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.createPolicyEvaluationPlan; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.createTransferProcess; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.dataAddressObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.inForceDatePermission; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.policyDefinitionObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.policyEvaluationPlanRequest; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.querySpecObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.secretObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.suspendTransferObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.terminateNegotiationObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.terminateTransferObject; +import static org.eclipse.edc.test.e2e.managementapi.TestFunctions.transferRequestObject; import static org.eclipse.edc.util.io.Ports.getFreePort; -import static org.mockito.Mockito.mock; -@ComponentTest -public class SerdeIntegrationTest { +@EndToEndTest +public class SerdeEndToEndTest { @RegisterExtension - private static final RuntimeExtension RUNTIME; - - static { - RUNTIME = new RuntimePerClassExtension(); - RUNTIME.registerServiceMock(ContractDefinitionService.class, mock()); - RUNTIME.registerServiceMock(ContractNegotiationService.class, mock()); - RUNTIME.registerServiceMock(PolicyDefinitionService.class, mock()); - RUNTIME.registerServiceMock(TransferProcessService.class, mock()); - RUNTIME.registerServiceMock(SecretService.class, mock()); - RUNTIME.registerServiceMock(EndpointDataReferenceStore.class, mock()); - RUNTIME.setConfiguration(Map.of( - "web.http.port", String.valueOf(getFreePort()), - "web.http.path", "/api", - "web.http.management.port", String.valueOf(getFreePort()), - "web.http.management.path", "/api", - "edc.jsonld.vocab.disable", "true" - )); - } + private static final RuntimeExtension RUNTIME = new SerdeRuntime(); @Test void ser_ContractAgreement() { @@ -340,7 +317,7 @@ void de_TerminateTransfer() { var terminateTransfer = deserialize(inputObject, TerminateTransfer.class); assertThat(terminateTransfer).isNotNull(); - assertThat(terminateTransfer.reason()).isEqualTo(inputObject.getString("reason")); + Assertions.assertThat(terminateTransfer.reason()).isEqualTo(inputObject.getString("reason")); } @@ -350,7 +327,7 @@ void de_SuspendTransfer() { var terminateTransfer = deserialize(inputObject, SuspendTransfer.class); assertThat(terminateTransfer).isNotNull(); - assertThat(terminateTransfer.reason()).isEqualTo(inputObject.getString("reason")); + Assertions.assertThat(terminateTransfer.reason()).isEqualTo(inputObject.getString("reason")); } @@ -386,7 +363,7 @@ void de_PolicyEvaluationPlanRequest() { var terminateTransfer = deserialize(inputObject, PolicyEvaluationPlanRequest.class); assertThat(terminateTransfer).isNotNull(); - assertThat(terminateTransfer.policyScope()).isEqualTo(inputObject.getString("policyScope")); + Assertions.assertThat(terminateTransfer.policyScope()).isEqualTo(inputObject.getString("policyScope")); } @@ -472,4 +449,37 @@ private JsonObject policyMapper(JsonObject compacted) { } + static class SerdeRuntime extends ManagementEndToEndExtension { + + protected SerdeRuntime() { + super(context()); + } + + private static ManagementEndToEndTestContext context() { + var managementPort = getFreePort(); + var protocolPort = getFreePort(); + + var runtime = new EmbeddedRuntime( + "control-plane", + new HashMap<>() { + { + put("web.http.path", "/"); + put("web.http.port", String.valueOf(getFreePort())); + put("web.http.protocol.path", "/protocol"); + put("web.http.protocol.port", String.valueOf(protocolPort)); + put("web.http.control.port", String.valueOf(getFreePort())); + put("edc.dsp.callback.address", "http://localhost:" + protocolPort + "/protocol"); + put("web.http.management.path", "/management"); + put("web.http.management.port", String.valueOf(managementPort)); + put("edc.management.context.enabled", "true"); + } + }, + ":system-tests:management-api:management-api-test-runtime" + ); + + return new ManagementEndToEndTestContext(runtime, managementPort, protocolPort); + } + + } + } diff --git a/extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/TestFunctions.java b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/TestFunctions.java similarity index 96% rename from extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/TestFunctions.java rename to system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/TestFunctions.java index 651a5ce5aa0..57c2d0b6fe5 100644 --- a/extensions/common/api/management-api-json-ld-context/src/test/java/org/eclipse/edc/connector/api/management/jsonld/serde/TestFunctions.java +++ b/system-tests/management-api/management-api-test-runner/src/test/java/org/eclipse/edc/test/e2e/managementapi/TestFunctions.java @@ -12,7 +12,7 @@ * */ -package org.eclipse.edc.connector.api.management.jsonld.serde; +package org.eclipse.edc.test.e2e.managementapi; import jakarta.json.Json; import jakarta.json.JsonArrayBuilder; @@ -49,16 +49,14 @@ import static jakarta.json.Json.createArrayBuilder; import static jakarta.json.Json.createObjectBuilder; import static java.util.Collections.emptySet; -import static org.eclipse.edc.connector.api.management.jsonld.ManagementApiJsonLdContextExtension.EDC_CONNECTOR_MANAGEMENT_CONTEXT; import static org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiationStates.REQUESTED; import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess.Type.CONSUMER; import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates.STARTED; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; -import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA; import static org.eclipse.edc.policy.model.Operator.EQ; -import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT; import static org.eclipse.edc.spi.types.domain.callback.CallbackAddress.EVENTS; import static org.eclipse.edc.spi.types.domain.callback.CallbackAddress.IS_TRANSACTIONAL; import static org.eclipse.edc.spi.types.domain.callback.CallbackAddress.URI; @@ -79,10 +77,7 @@ public class TestFunctions { public static JsonArrayBuilder createContextBuilder() { return createArrayBuilder() - .add(EDC_CONNECTOR_MANAGEMENT_CONTEXT) - .add(createObjectBuilder() - .add("edc", EDC_NAMESPACE) - .add("odrl", ODRL_SCHEMA)); + .add(EDC_CONNECTOR_MANAGEMENT_CONTEXT); } public static JsonObject assetObject() { @@ -324,7 +319,7 @@ private static JsonArrayBuilder createCallbackAddress() { public static JsonObjectBuilder policy(JsonObject permission) { return createObjectBuilder() - .add(TYPE, "odrl:Set") + .add(TYPE, "http://www.w3.org/ns/odrl/2/Set") .add("obligation", createArrayBuilder().build()) .add("permission", permission) .add("target", "assetId")