Skip to content

Commit

Permalink
feat: introduces optional JSON-LD context for management API
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf4ood committed Sep 11, 2024
1 parent 89946ff commit 74ad6bc
Show file tree
Hide file tree
Showing 22 changed files with 238 additions and 264 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -36,6 +37,10 @@ public boolean shouldCheckPrefixes() {
return checkPrefixes;
}

public boolean isAvoidVocab() {
return avoidVocab;
}

public static class Builder {

private final JsonLdConfiguration configuration = new JsonLdConfiguration();
Expand All @@ -54,6 +59,11 @@ public Builder httpsEnabled(boolean httpsEnabled) {
return this;
}

public Builder vocabEnabled(boolean vocabEnabled) {
configuration.avoidVocab = vocabEnabled;
return this;
}

public Builder checkPrefixes(boolean checkPrefixes) {
configuration.checkPrefixes = checkPrefixes;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,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());
Expand All @@ -75,6 +76,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();
Expand Down Expand Up @@ -124,6 +126,10 @@ public Result<JsonObject> 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 && JsonLdKeywords.VOCAB.equals(prefix)) {
return;
}
var namespaces = scopedNamespaces.computeIfAbsent(scope, k -> new LinkedHashMap<>());
namespaces.put(prefix, contextIri);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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().vocabEnabled(false).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/";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.eclipse.edc.connector.controlplane.transform.odrl.OdrlTransformersFactory;
import org.eclipse.edc.connector.controlplane.transform.odrl.from.JsonObjectFromPolicyTransformer;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.jsonld.spi.JsonLdKeywords;
import org.eclipse.edc.policy.model.AtomicConstraint;
import org.eclipse.edc.policy.model.LiteralExpression;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
Expand Down Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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(JsonLdKeywords.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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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")
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.edc.connector.controlplane.transform.odrl.OdrlTransformersFactory;
import org.eclipse.edc.connector.controlplane.transform.odrl.from.JsonObjectFromPolicyTransformer;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.jsonld.spi.JsonLdKeywords;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.runtime.metamodel.annotation.Provides;
Expand Down Expand Up @@ -63,6 +64,9 @@
import static java.lang.String.format;
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;

/**
Expand All @@ -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)
Expand All @@ -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 = "<hostname:management.port/management.path>")
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
Expand Down Expand Up @@ -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(JsonLdKeywords.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));
Expand Down
Loading

0 comments on commit 74ad6bc

Please sign in to comment.