Skip to content

Commit

Permalink
fix: add deterministic ObjectMapper for JSON-LD
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf4ood committed Jan 20, 2025
1 parent 65a9f3f commit 1024e45
Show file tree
Hide file tree
Showing 44 changed files with 225 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void setupModule(SetupContext context) {
}
};
mapper.registerModule(module);
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
return mapper;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,13 @@ public String name() {

@Override
public void initialize(ServiceExtensionContext context) {
var jsonLdMapper = typeManager.getMapper(JSON_LD);
registerValidators(DSP_NAMESPACE_V_08);
registerValidators(DSP_NAMESPACE_V_2024_1);

webService.registerResource(ApiContext.PROTOCOL, new DspCatalogApiController(service, dspRequestHandler, continuationTokenManager(monitor, DSP_TRANSFORMER_CONTEXT_V_08, DSP_NAMESPACE_V_08)));
webService.registerResource(ApiContext.PROTOCOL, new DspCatalogApiController20241(service, dspRequestHandler, continuationTokenManager(monitor, DSP_TRANSFORMER_CONTEXT_V_2024_1, DSP_NAMESPACE_V_2024_1)));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspCatalogApiController.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_08));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspCatalogApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_2024_1));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspCatalogApiController.class, new JerseyJsonLdInterceptor(jsonLd, () -> typeManager.getMapper(JSON_LD), DSP_SCOPE_V_08));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspCatalogApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, () -> typeManager.getMapper(JSON_LD), DSP_SCOPE_V_2024_1));

dataServiceRegistry.register(DataService.Builder.newInstance()
.endpointDescription("dspace:connector")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.types.TypeManager;
import org.eclipse.edc.transform.spi.TypeTransformerRegistry;

Expand Down Expand Up @@ -64,16 +63,14 @@ public String name() {
}

@Override
public void initialize(ServiceExtensionContext context) {
public void prepare() {
var mapper = typeManager.getMapper(JSON_LD);

registerV08Transformers(mapper);
registerV2024Transformers(mapper);

registerTransformers(DSP_TRANSFORMER_CONTEXT_V_08, DSP_NAMESPACE_V_08, mapper);
registerTransformers(DSP_TRANSFORMER_CONTEXT_V_2024_1, DSP_NAMESPACE_V_2024_1, mapper);


}

private void registerTransformers(String version, JsonLdNamespace namespace, ObjectMapper mapper) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,17 @@ public void initialize(ServiceExtensionContext context) {
var dspWebhookAddress = ofNullable(callbackAddress).orElseGet(() -> format("http://%s:%s%s", hostname.get(), portMapping.port(), portMapping.path()));
context.registerService(ProtocolWebhook.class, () -> dspWebhookAddress);

var jsonLdMapper = typeManager.getMapper(JSON_LD);

// registers ns for DSP scope
registerNamespaces(DSP_SCOPE_V_08, DSP_NAMESPACE_V_08);
registerNamespaces(DSP_SCOPE_V_2024_1, DSP_NAMESPACE_V_2024_1);

webService.registerResource(ApiContext.PROTOCOL, new ObjectMapperProvider(jsonLdMapper));
webService.registerResource(ApiContext.PROTOCOL, new ObjectMapperProvider(() -> typeManager.getMapper(JSON_LD)));


}

@Override
public void prepare() {
var mapper = typeManager.getMapper(JSON_LD);
mapper.registerSubtypes(AtomicConstraint.class, LiteralExpression.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public DspRequestHandler dspRequestHandler() {

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

@Provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.eclipse.edc.spi.types.domain.message.RemoteMessage;
import org.eclipse.edc.transform.spi.TypeTransformerRegistry;

import java.util.function.Supplier;

import static java.lang.String.format;
import static java.lang.String.join;
import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_CONTEXT_SEPARATOR;
Expand All @@ -34,16 +36,16 @@
*/
public class JsonLdRemoteMessageSerializerImpl implements JsonLdRemoteMessageSerializer {

private final ObjectMapper mapper;
private final Supplier<ObjectMapper> mapperSupplier;
private final JsonLd jsonLdService;
private final String scopePrefix;
private final DspProtocolTypeTransformerRegistry dspTransformerRegistry;
private final DspProtocolParser protocolParser;

public JsonLdRemoteMessageSerializerImpl(DspProtocolTypeTransformerRegistry dspTransformerRegistry,
ObjectMapper mapper, JsonLd jsonLdService, DspProtocolParser protocolParser, String scopePrefix) {
Supplier<ObjectMapper> mapperSupplier, JsonLd jsonLdService, DspProtocolParser protocolParser, String scopePrefix) {
this.dspTransformerRegistry = dspTransformerRegistry;
this.mapper = mapper;
this.mapperSupplier = mapperSupplier;
this.jsonLdService = jsonLdService;
this.scopePrefix = scopePrefix;
this.protocolParser = protocolParser;
Expand Down Expand Up @@ -73,7 +75,7 @@ public String serialize(RemoteMessage message) {
var compacted = protocolParser.parse(message.getProtocol())
.compose(protocol -> jsonLdService.compact(transformResult.getContent(), scopePrefix + DSP_CONTEXT_SEPARATOR + protocol.version()));
if (compacted.succeeded()) {
return mapper.writeValueAsString(compacted.getContent());
return mapperSupplier.get().writeValueAsString(compacted.getContent());
}
throw new EdcException("Failed to compact JSON-LD: " + compacted.getFailureDetail());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import java.io.IOException;
import java.util.function.Function;
import java.util.function.Supplier;

import static java.lang.String.format;
import static java.lang.String.join;
Expand All @@ -35,21 +36,21 @@
*/
public class JsonLdResponseBodyDeserializer<T> implements DspHttpResponseBodyExtractor<T> {
private final Class<T> type;
private final ObjectMapper objectMapper;
private final Supplier<ObjectMapper> objectMapperSupplier;
private final JsonLd jsonLd;
private final DspProtocolTypeTransformerRegistry dspTransformerRegistry;

public JsonLdResponseBodyDeserializer(Class<T> type, ObjectMapper objectMapper, JsonLd jsonLd, DspProtocolTypeTransformerRegistry dspTransformerRegistry) {
public JsonLdResponseBodyDeserializer(Class<T> type, Supplier<ObjectMapper> objectMapperSupplier, JsonLd jsonLd, DspProtocolTypeTransformerRegistry dspTransformerRegistry) {
this.type = type;
this.objectMapper = objectMapper;
this.objectMapperSupplier = objectMapperSupplier;
this.jsonLd = jsonLd;
this.dspTransformerRegistry = dspTransformerRegistry;
}

@Override
public T extractBody(ResponseBody responseBody, String protocol) {
try {
var jsonObject = objectMapper.readValue(responseBody.byteStream(), JsonObject.class);
var jsonObject = objectMapperSupplier.get().readValue(responseBody.byteStream(), JsonObject.class);
var transformerRegistryResult = dspTransformerRegistry.forProtocol(protocol);
if (transformerRegistryResult.failed()) {
throw new EdcException(format("Failed to extract body: %s", join(", ", transformerRegistryResult.getFailureMessages())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void setUp() {
var jsonLdService = new TitaniumJsonLd(mock(Monitor.class));
jsonLdService.registerNamespace("schema", "http://schema/"); //needed for compaction
when(registry.forContext(DSP_TRANSFORMER_CONTEXT_V_08)).thenReturn(registry);
serializer = new JsonLdRemoteMessageSerializerImpl(dspTransformerRegistry, mapper, jsonLdService, protocolParser, "scope");
serializer = new JsonLdRemoteMessageSerializerImpl(dspTransformerRegistry, () -> mapper, jsonLdService, protocolParser, "scope");
when(message.getProtocol()).thenReturn(DATASPACE_PROTOCOL_HTTP);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class JsonLdResponseBodyDeserializerTest {
private final TypeTransformerRegistry transformerRegistry = mock();
private final DspProtocolTypeTransformerRegistry dspTransformerRegistry = mock();
private final JsonLdResponseBodyDeserializer<Object> bodyExtractor =
new JsonLdResponseBodyDeserializer<>(Object.class, objectMapper, jsonLd, dspTransformerRegistry);
new JsonLdResponseBodyDeserializer<>(Object.class, () -> objectMapper, jsonLd, dspTransformerRegistry);


@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,14 @@ public String name() {

@Override
public void initialize(ServiceExtensionContext context) {
var jsonLdMapper = typeManager.getMapper(JSON_LD);

registerValidators(DSP_NAMESPACE_V_08);
registerValidators(DSP_NAMESPACE_V_2024_1);

webService.registerResource(ApiContext.PROTOCOL, new DspNegotiationApiController(protocolService, dspRequestHandler));
webService.registerResource(ApiContext.PROTOCOL, new DspNegotiationApiController20241(protocolService, dspRequestHandler));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspNegotiationApiController.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_08));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspNegotiationApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_2024_1));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspNegotiationApiController.class, new JerseyJsonLdInterceptor(jsonLd, () -> typeManager.getMapper(JSON_LD), DSP_SCOPE_V_08));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspNegotiationApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, () -> typeManager.getMapper(JSON_LD), DSP_SCOPE_V_2024_1));

versionRegistry.register(V_2024_1);
versionRegistry.register(V_08);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public String name() {
@Override
public void initialize(ServiceExtensionContext context) {
var contractNegotiationAckDeserializer = new JsonLdResponseBodyDeserializer<>(
ContractNegotiationAck.class, typeManager.getMapper(JSON_LD), jsonLd, dspTransformerRegistry);
ContractNegotiationAck.class, () -> typeManager.getMapper(JSON_LD), jsonLd, dspTransformerRegistry);

messageDispatcher.registerMessage(
ContractAgreementMessage.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,14 @@ public class DspTransferProcessApiExtension implements ServiceExtension {

@Override
public void initialize(ServiceExtensionContext context) {
var jsonLdMapper = typeManager.getMapper(JSON_LD);

registerValidators(DSP_NAMESPACE_V_08);
registerValidators(DSP_NAMESPACE_V_2024_1);

webService.registerResource(ApiContext.PROTOCOL, new DspTransferProcessApiController(transferProcessProtocolService, dspRequestHandler));
webService.registerResource(ApiContext.PROTOCOL, new DspTransferProcessApiController20241(transferProcessProtocolService, dspRequestHandler));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspTransferProcessApiController.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_08));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspTransferProcessApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, DSP_SCOPE_V_2024_1));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspTransferProcessApiController.class, new JerseyJsonLdInterceptor(jsonLd, () -> typeManager.getMapper(JSON_LD), DSP_SCOPE_V_08));
webService.registerDynamicResource(ApiContext.PROTOCOL, DspTransferProcessApiController20241.class, new JerseyJsonLdInterceptor(jsonLd, () -> typeManager.getMapper(JSON_LD), DSP_SCOPE_V_2024_1));

versionRegistry.register(V_2024_1);
versionRegistry.register(V_08);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void initialize(ServiceExtensionContext context) {
messageDispatcher.registerMessage(
TransferRequestMessage.class,
new PostDspHttpRequestFactory<>(remoteMessageSerializer, dspProtocolParser, m -> BASE_PATH + TRANSFER_INITIAL_REQUEST),
new JsonLdResponseBodyDeserializer<>(TransferProcessAck.class, typeManager.getMapper(JSON_LD), jsonLd, dspTransformerRegistry)
new JsonLdResponseBodyDeserializer<>(TransferProcessAck.class, () -> typeManager.getMapper(JSON_LD), jsonLd, dspTransformerRegistry)
);
messageDispatcher.registerMessage(
TransferCompletionMessage.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.types.TypeManager;
import org.eclipse.edc.transform.spi.TypeTransformerRegistry;

Expand Down Expand Up @@ -71,7 +70,7 @@ public String name() {
}

@Override
public void initialize(ServiceExtensionContext context) {
public void prepare() {
var objectMapper = typeManager.getMapper(JSON_LD);

registerV08transformers();
Expand All @@ -80,7 +79,6 @@ public void initialize(ServiceExtensionContext context) {
registerTransformers(DSP_TRANSFORMER_CONTEXT_V_2024_1, DSP_NAMESPACE_V_2024_1, objectMapper);
}


private void registerTransformers(String version, JsonLdNamespace namespace, ObjectMapper objectMapper) {
var builderFactory = Json.createBuilderFactory(Map.of());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ public String name() {
public void initialize(ServiceExtensionContext context) {
var portMapping = new PortMapping(ApiContext.CONTROL, apiConfiguration.port(), apiConfiguration.path());
portMappingRegistry.register(portMapping);
var jsonLdMapper = typeManager.getMapper(JSON_LD);
context.registerService(ControlApiUrl.class, controlApiUrl(context, portMapping));

jsonLd.registerNamespace(EDC_PREFIX, EDC_NAMESPACE, CONTROL_SCOPE);
Expand All @@ -107,8 +106,8 @@ public void initialize(ServiceExtensionContext context) {

var authenticationRequestFilter = new AuthenticationRequestFilter(authenticationRegistry, "control-api");
webService.registerResource(ApiContext.CONTROL, authenticationRequestFilter);
webService.registerResource(ApiContext.CONTROL, new ObjectMapperProvider(jsonLdMapper));
webService.registerResource(ApiContext.CONTROL, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, CONTROL_SCOPE));
webService.registerResource(ApiContext.CONTROL, new ObjectMapperProvider(() -> typeManager.getMapper(JSON_LD)));
webService.registerResource(ApiContext.CONTROL, new JerseyJsonLdInterceptor(jsonLd, () -> typeManager.getMapper(JSON_LD), CONTROL_SCOPE));

registerVersionInfo(getClass().getClassLoader());
}
Expand All @@ -129,7 +128,7 @@ private void registerVersionInfo(ClassLoader resourceClassLoader) {

private ControlApiUrl controlApiUrl(ServiceExtensionContext context, PortMapping config) {
var callbackAddress = ofNullable(controlEndpoint).orElseGet(() -> format("http://%s:%s%s", hostname.get(), config.port(), config.path()));

try {
var url = URI.create(callbackAddress);
return () -> url;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,15 @@ public void initialize(ServiceExtensionContext context) {
jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, MANAGEMENT_SCOPE);
}

webService.registerResource(ApiContext.MANAGEMENT, new ObjectMapperProvider(() -> typeManager.getMapper(JSON_LD)));
webService.registerResource(ApiContext.MANAGEMENT, new JerseyJsonLdInterceptor(jsonLd, () -> typeManager.getMapper(JSON_LD), MANAGEMENT_SCOPE));

registerVersionInfo(getClass().getClassLoader());
}

@Override
public void prepare() {
var jsonLdMapper = typeManager.getMapper(JSON_LD);
webService.registerResource(ApiContext.MANAGEMENT, new ObjectMapperProvider(jsonLdMapper));
webService.registerResource(ApiContext.MANAGEMENT, new JerseyJsonLdInterceptor(jsonLd, jsonLdMapper, MANAGEMENT_SCOPE));

var managementApiTransformerRegistry = transformerRegistry.forContext(MANAGEMENT_API_CONTEXT);

Expand All @@ -159,8 +165,6 @@ public void initialize(ServiceExtensionContext context) {
var managementApiTransformerRegistryV4Alpha = managementApiTransformerRegistry.forContext(MANAGEMENT_API_V_4_ALPHA);

managementApiTransformerRegistryV4Alpha.register(new JsonObjectFromPolicyTransformer(factory, participantIdMapper, true));

registerVersionInfo(getClass().getClassLoader());
}

private void registerVersionInfo(ClassLoader resourceClassLoader) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;

/**
* Computes the cryptographic integrity of a VerifiablePresentation when it's represented as JWT. Internally, for the actual
Expand Down Expand Up @@ -68,16 +69,16 @@ public class JwtPresentationVerifier implements CredentialVerifier {
public static final String VERIFIABLE_CREDENTIAL_JSON_KEY = "verifiableCredential";
public static final String VP_CLAIM = "vp";
public static final String VC_CLAIM = "vc";
private final ObjectMapper objectMapper;
private final Supplier<ObjectMapper> objectMapperSupplier;
private final TokenValidationService tokenValidationService;
private final TokenValidationRulesRegistry tokenValidationRulesRegistry;
private final PublicKeyResolver publicKeyResolver;

/**
* Verifies the JWT presentation by checking the cryptographic integrity.
*/
public JwtPresentationVerifier(ObjectMapper objectMapper, TokenValidationService tokenValidationService, TokenValidationRulesRegistry tokenValidationRulesRegistry, PublicKeyResolver publicKeyResolver) {
this.objectMapper = objectMapper;
public JwtPresentationVerifier(Supplier<ObjectMapper> objectMapperSupplier, TokenValidationService tokenValidationService, TokenValidationRulesRegistry tokenValidationRulesRegistry, PublicKeyResolver publicKeyResolver) {
this.objectMapperSupplier = objectMapperSupplier;
this.tokenValidationService = tokenValidationService;
this.tokenValidationRulesRegistry = tokenValidationRulesRegistry;
this.publicKeyResolver = publicKeyResolver;
Expand Down Expand Up @@ -177,7 +178,7 @@ private List<String> extractCredentials(Object credentialsObject) {
if (credentialsObject instanceof Collection<?>) {
return ((Collection) credentialsObject).stream().map(obj -> {
try {
return (obj instanceof String) ? obj.toString() : objectMapper.writeValueAsString(obj);
return (obj instanceof String) ? obj.toString() : objectMapperSupplier.get().writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
Expand Down
Loading

0 comments on commit 1024e45

Please sign in to comment.