Skip to content

Commit

Permalink
feat: add configurable JSON-LD namespaces/context for each scope (#3516)
Browse files Browse the repository at this point in the history
* feat: add configurable JSON-LD namespaces/context for each scope

* pr remarks
  • Loading branch information
wolf4ood authored Oct 9, 2023
1 parent 9d39f5c commit 9ba98a6
Show file tree
Hide file tree
Showing 18 changed files with 318 additions and 76 deletions.
2 changes: 1 addition & 1 deletion DEPENDENCIES
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ maven/mavencentral/org.testcontainers/jdbc/1.19.1, Apache-2.0, approved, #10348
maven/mavencentral/org.testcontainers/junit-jupiter/1.19.1, MIT, approved, #10344
maven/mavencentral/org.testcontainers/postgresql/1.19.1, MIT, approved, #10350
maven/mavencentral/org.testcontainers/testcontainers/1.19.1, Apache-2.0 AND MIT, approved, #10347
maven/mavencentral/org.testcontainers/vault/1.19.1, None, restricted, #10852
maven/mavencentral/org.testcontainers/vault/1.19.1, MIT, approved, #10852
maven/mavencentral/org.xerial.snappy/snappy-java/1.1.10.4, Apache-2.0 AND (Apache-2.0 AND BSD-3-Clause), approved, #9098
maven/mavencentral/org.xmlunit/xmlunit-core/2.9.1, Apache-2.0, approved, #6272
maven/mavencentral/org.xmlunit/xmlunit-placeholders/2.9.1, Apache-2.0, approved, clearlydefined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ public class JerseyJsonLdInterceptor implements ReaderInterceptor, WriterInterce
private final JsonLd jsonLd;
private final ObjectMapper objectMapper;

public JerseyJsonLdInterceptor(JsonLd jsonLd, ObjectMapper objectMapper) {
private final String scope;

public JerseyJsonLdInterceptor(JsonLd jsonLd, ObjectMapper objectMapper, String scope) {
this.jsonLd = jsonLd;
this.objectMapper = objectMapper;
this.scope = scope;
}

@Override
Expand Down Expand Up @@ -80,7 +83,7 @@ public void aroundWriteTo(WriterInterceptorContext context) throws IOException,
}

private JsonObject compact(JsonObject jsonObject) {
return jsonLd.compact(jsonObject)
return jsonLd.compact(jsonObject, scope)
.orElseThrow(f -> new InternalServerErrorException("Failed to compact JsonObject: " + f.getFailureDetail()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import static io.restassured.http.ContentType.JSON;
import static org.hamcrest.CoreMatchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
Expand All @@ -41,8 +42,9 @@
@ApiTest
class JerseyJsonLdInterceptorTest extends RestControllerTestBase {

private static final String SCOPE = "scope";
private final JsonLd jsonLd = mock();
private final JerseyJsonLdInterceptor interceptor = new JerseyJsonLdInterceptor(jsonLd, objectMapper);
private final JerseyJsonLdInterceptor interceptor = new JerseyJsonLdInterceptor(jsonLd, objectMapper, SCOPE);

@Test
void expansion_shouldSucceed_whenInputIsJsonObject() {
Expand Down Expand Up @@ -101,7 +103,7 @@ void expansion_shouldNotHappen_whenInputIsNotJsonObject() {

@Test
void compaction_single_shouldSucceed_whenOutputIsJsonObject() {
when(jsonLd.compact(any())).thenReturn(Result.success(compactedJson()));
when(jsonLd.compact(any(), eq(SCOPE))).thenReturn(Result.success(compactedJson()));

given()
.port(port)
Expand All @@ -111,12 +113,12 @@ void compaction_single_shouldSucceed_whenOutputIsJsonObject() {
.statusCode(200)
.body("compacted-key", is("compacted-value"));

verify(jsonLd).compact(expandedJson());
verify(jsonLd).compact(expandedJson(), SCOPE);
}

@Test
void compaction_single_shouldReturnInternalServerError_whenCompactionFails() {
when(jsonLd.compact(any())).thenReturn(Result.failure("compaction failure"));
when(jsonLd.compact(any(), eq(SCOPE))).thenReturn(Result.failure("compaction failure"));

given()
.port(port)
Expand All @@ -140,7 +142,7 @@ void compaction_single_shouldNotHappen_whenOutputIsNotJsonObject() {

@Test
void compaction_multiple_shouldSucceed_whenOutputIsJsonObject() {
when(jsonLd.compact(any())).thenReturn(Result.success(compactedJson()));
when(jsonLd.compact(any(), eq(SCOPE))).thenReturn(Result.success(compactedJson()));

given()
.port(port)
Expand All @@ -151,12 +153,12 @@ void compaction_multiple_shouldSucceed_whenOutputIsJsonObject() {
.body("size()", is(1))
.body("[0].compacted-key", is("compacted-value"));

verify(jsonLd).compact(expandedJson());
verify(jsonLd).compact(expandedJson(), SCOPE);
}

@Test
void compaction_multiple_shouldReturnInternalServerError_whenCompactionFails() {
when(jsonLd.compact(any())).thenReturn(Result.failure("compaction failure"));
when(jsonLd.compact(any(), eq(SCOPE))).thenReturn(Result.failure("compaction failure"));

given()
.port(port)
Expand Down Expand Up @@ -188,6 +190,18 @@ protected Object additionalResource() {
return interceptor;
}

private JsonObject expandedJson() {
return Json.createObjectBuilder().add("expanded-key", "expanded-value").add("bau", 3).build();
}

private JsonObject compactedJson() {
return Json.createObjectBuilder().add("compacted-key", "compacted-value").add("bau", 3).build();
}

private Map<String, String> notJsonObject() {
return Map.of("key", "value");
}

@Path("/")
public class TestController {

Expand Down Expand Up @@ -230,16 +244,4 @@ public List<Map<String, String>> getMultipleNotJsonObject() {
}

}

private JsonObject expandedJson() {
return Json.createObjectBuilder().add("expanded-key", "expanded-value").add("bau", 3).build();
}

private JsonObject compactedJson() {
return Json.createObjectBuilder().add("compacted-key", "compacted-value").add("bau", 3).build();
}

private Map<String, String> notJsonObject() {
return Map.of("key", "value");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@

import java.util.Map;

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.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.protocol.dsp.type.DspConstants.DSP_SCOPE;
import static org.eclipse.edc.spi.CoreConstants.JSON_LD;

/**
Expand Down Expand Up @@ -87,28 +96,20 @@ public class DspApiConfigurationExtension implements ServiceExtension {
.defaultPort(DEFAULT_PROTOCOL_PORT)
.name("Protocol API")
.build();

@Inject
private TypeManager typeManager;

@Inject
private WebService webService;

@Inject
private WebServer webServer;

@Inject
private WebServiceConfigurer configurator;

@Inject
private JsonLd jsonLd;

@Inject
private TypeTransformerRegistry transformerRegistry;

@Inject
private IdentityService identityService;

@Inject
private JsonObjectValidatorRegistry validatorRegistry;

Expand All @@ -126,8 +127,16 @@ public void initialize(ServiceExtensionContext context) {
context.registerService(DspRequestHandler.class, new DspRequestHandlerImpl(context.getMonitor(), dspWebhookAddress, identityService, validatorRegistry, transformerRegistry));

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);

webService.registerResource(config.getContextAlias(), new ObjectMapperProvider(jsonLdMapper));
webService.registerResource(config.getContextAlias(), new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper));
webService.registerResource(config.getContextAlias(), new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE));

registerTransformers();
}
Expand Down
3 changes: 2 additions & 1 deletion data-protocols/dsp/dsp-http-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ dependencies {
api(project(":spi:common:json-ld-spi"))
api(project(":spi:control-plane:transfer-spi"))
api(project(":extensions:common:json-ld"))
api(project(":data-protocols:dsp:dsp-spi"))
api(project(":data-protocols:dsp:dsp-http-spi"))

testImplementation(project(":core:common:junit"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.eclipse.edc.spi.types.TypeManager;
import org.eclipse.edc.transform.spi.TypeTransformerRegistry;

import static org.eclipse.edc.protocol.dsp.type.DspConstants.DSP_SCOPE;
import static org.eclipse.edc.spi.CoreConstants.JSON_LD;

/**
Expand Down Expand Up @@ -118,7 +119,7 @@ public DspHttpRemoteMessageDispatcher dspHttpRemoteMessageDispatcher(ServiceExte

@Provider
public JsonLdRemoteMessageSerializer jsonLdRemoteMessageSerializer() {
return new JsonLdRemoteMessageSerializerImpl(transformerRegistry, typeManager.getMapper(JSON_LD), jsonLdService);
return new JsonLdRemoteMessageSerializerImpl(transformerRegistry, typeManager.getMapper(JSON_LD), jsonLdService, DSP_SCOPE);
}

private void registerNegotiationPolicyScopes(DspHttpRemoteMessageDispatcher dispatcher) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,13 @@ public class JsonLdRemoteMessageSerializerImpl implements JsonLdRemoteMessageSer
private final ObjectMapper mapper;
private final JsonLd jsonLdService;

public JsonLdRemoteMessageSerializerImpl(TypeTransformerRegistry registry, ObjectMapper mapper, JsonLd jsonLdService) {
private final String scope;

public JsonLdRemoteMessageSerializerImpl(TypeTransformerRegistry registry, ObjectMapper mapper, JsonLd jsonLdService, String scope) {
this.registry = registry;
this.mapper = mapper;
this.jsonLdService = jsonLdService;
this.scope = scope;
}

/**
Expand All @@ -55,7 +58,7 @@ public String serialize(RemoteMessage message) {
var transformResult = registry.transform(message, JsonObject.class);

if (transformResult.succeeded()) {
var compacted = jsonLdService.compact(transformResult.getContent());
var compacted = jsonLdService.compact(transformResult.getContent(), scope);
if (compacted.succeeded()) {
return mapper.writeValueAsString(compacted.getContent());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ class JsonLdRemoteMessageSerializerImplTest {
private final ObjectMapper mapper = mock(ObjectMapper.class);
private final RemoteMessage message = mock(RemoteMessage.class);
private JsonLdRemoteMessageSerializerImpl serializer;
private TitaniumJsonLd jsonLdService;

@BeforeEach
void setUp() {
jsonLdService = new TitaniumJsonLd(mock(Monitor.class));
var jsonLdService = new TitaniumJsonLd(mock(Monitor.class));
jsonLdService.registerNamespace("schema", "http://schema/"); //needed for compaction
serializer = new JsonLdRemoteMessageSerializerImpl(registry, mapper, jsonLdService);
serializer = new JsonLdRemoteMessageSerializerImpl(registry, mapper, jsonLdService, "scope");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2023 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.protocol.dsp.type;

/**
* Dataspace protocol constants.
*/
public interface DspConstants {
String DSP_SCOPE = "DSP";
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

import java.util.Map;

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.CoreConstants.JSON_LD;

/**
Expand All @@ -62,25 +64,19 @@ public class ManagementApiConfigurationExtension implements ServiceExtension {
.useDefaultContext(true)
.name(WEB_SERVICE_NAME)
.build();

private static final String MANAGEMENT_SCOPE = "MANAGEMENT_API";
@Inject
private WebService webService;

@Inject
private WebServer webServer;

@Inject
private AuthenticationService authenticationService;

@Inject
private WebServiceConfigurer configurator;

@Inject
private TypeManager typeManager;

@Inject
private JsonLd jsonLd;

@Inject
private TypeTransformerRegistry transformerRegistry;

Expand All @@ -96,9 +92,10 @@ public void initialize(ServiceExtensionContext context) {
context.registerService(ManagementApiConfiguration.class, new ManagementApiConfiguration(webServiceConfiguration));
webService.registerResource(webServiceConfiguration.getContextAlias(), new AuthenticationRequestFilter(authenticationService));

jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, MANAGEMENT_SCOPE);
var jsonLdMapper = typeManager.getMapper(JSON_LD);
webService.registerResource(webServiceConfiguration.getContextAlias(), new ObjectMapperProvider(jsonLdMapper));
webService.registerResource(webServiceConfiguration.getContextAlias(), new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper));
webService.registerResource(webServiceConfiguration.getContextAlias(), new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, MANAGEMENT_SCOPE));
}

@Provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@
import java.net.URISyntaxException;

import static java.lang.String.format;
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.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.CoreConstants.EDC_NAMESPACE;
import static org.eclipse.edc.spi.CoreConstants.EDC_PREFIX;
import static org.eclipse.edc.spi.CoreConstants.JSON_LD;
Expand Down Expand Up @@ -89,10 +81,6 @@ public JsonLd createJsonLdService(ServiceExtensionContext context) {
var monitor = context.getMonitor();
var service = new TitaniumJsonLd(monitor, configuration);
service.registerNamespace(EDC_PREFIX, EDC_NAMESPACE);
service.registerNamespace(DCAT_PREFIX, DCAT_SCHEMA);
service.registerNamespace(DCT_PREFIX, DCT_SCHEMA);
service.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA);
service.registerNamespace(DSPACE_PREFIX, DSPACE_SCHEMA);

getResourceUri("document" + File.separator + "odrl.jsonld")
.onSuccess(uri -> service.registerCachedDocument("http://www.w3.org/ns/odrl.jsonld", uri))
Expand Down
Loading

0 comments on commit 9ba98a6

Please sign in to comment.