From 1ec7eb516006956109e5677d62e3ca7137d974f9 Mon Sep 17 00:00:00 2001 From: Paul Latzelsperger <43503240+paullatzelsperger@users.noreply.github.com> Date: Wed, 26 Apr 2023 13:21:28 +0200 Subject: [PATCH] feat(dsp): add transformer for JsonObjectToDataAddress (#2811) * feat(dsp): add transformer for JsonObjectToDataAddress * pr remarks --- .../DspTransferProcessTransformExtension.java | 2 + .../JsonObjectFromDataAddressTransformer.java | 4 +- ...nObjectFromDataAddressTransformerTest.java | 39 ++++-- .../from/JsonObjectFromAssetTransformer.java | 4 +- .../JsonObjectToDataAddressTransformer.java | 62 +++++++++ .../transformer/PayloadTransformer.java | 7 +- .../JsonObjectFromAssetTransformerTest.java | 12 +- .../to/JsonObjectToAssetTransformerTest.java | 26 +--- ...sonObjectToDataAddressTransformerTest.java | 127 ++++++++++++++++++ .../org/eclipse/edc/spi/CoreConstants.java | 20 +++ .../edc/spi/types/domain/DataAddress.java | 19 +-- .../eclipse/edc/jsonld/spi/Namespaces.java | 3 - .../edc/jsonld/spi/PropertyAndTypeNames.java | 14 +- 13 files changed, 273 insertions(+), 66 deletions(-) create mode 100644 extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToDataAddressTransformer.java create mode 100644 extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToDataAddressTransformerTest.java create mode 100644 spi/common/core-spi/src/main/java/org/eclipse/edc/spi/CoreConstants.java diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/DspTransferProcessTransformExtension.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/DspTransferProcessTransformExtension.java index 2262bfd4b34..074d7431210 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/DspTransferProcessTransformExtension.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/DspTransferProcessTransformExtension.java @@ -16,6 +16,7 @@ import jakarta.json.Json; import org.eclipse.edc.jsonld.spi.transformer.JsonLdTransformerRegistry; +import org.eclipse.edc.jsonld.transformer.to.JsonObjectToDataAddressTransformer; import org.eclipse.edc.protocol.dsp.transferprocess.transformer.type.from.JsonObjectFromDataAddressTransformer; import org.eclipse.edc.protocol.dsp.transferprocess.transformer.type.from.JsonObjectFromTransferCompletionMessageTransformer; import org.eclipse.edc.protocol.dsp.transferprocess.transformer.type.from.JsonObjectFromTransferProcessTransformer; @@ -66,5 +67,6 @@ public void initialize(ServiceExtensionContext context) { registry.register(new JsonObjectToTransferCompletionMessageTransformer()); registry.register(new JsonObjectToTransferStartMessageTransformer()); registry.register(new JsonObjectToTransferTerminationMessageTransformer()); + registry.register(new JsonObjectToDataAddressTransformer()); } } diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/from/JsonObjectFromDataAddressTransformer.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/from/JsonObjectFromDataAddressTransformer.java index b6b1ea8b813..a04276706cf 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/from/JsonObjectFromDataAddressTransformer.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/type/from/JsonObjectFromDataAddressTransformer.java @@ -32,10 +32,10 @@ public JsonObjectFromDataAddressTransformer(JsonBuilderFactory jsonBuilderFactor } @Override - public @Nullable JsonObject transform(@NotNull DataAddress transferCompletionMessage, @NotNull TransformerContext context) { + public @Nullable JsonObject transform(@NotNull DataAddress dataAddress, @NotNull TransformerContext context) { var builder = jsonBuilderFactory.createObjectBuilder(); - transferCompletionMessage.getProperties().forEach((k, v) -> builder.add(k, v)); + dataAddress.getProperties().forEach(builder::add); return builder.build(); } diff --git a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/from/JsonObjectFromDataAddressTransformerTest.java b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/from/JsonObjectFromDataAddressTransformerTest.java index c97337d8261..03a1f288169 100644 --- a/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/from/JsonObjectFromDataAddressTransformerTest.java +++ b/data-protocols/dsp/dsp-transfer-process/dsp-transfer-process-transform/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/transformer/from/JsonObjectFromDataAddressTransformerTest.java @@ -32,14 +32,10 @@ class JsonObjectFromDataAddressTransformerTest { + private static final String TEST_KEY = "region"; + private static final String TEST_VALUE = "europe"; private final String type = "testType"; - private final String key = "testKey"; - - private final String propertyKey = "region"; - - private final String propertyValue = "europe"; - private final JsonBuilderFactory jsonFactory = Json.createBuilderFactory(Map.of()); private final TransformerContext context = mock(TransformerContext.class); @@ -51,20 +47,35 @@ void setUp() { } @Test - void transformTransferCompletionMessage() { + void transform() { var message = DataAddress.Builder.newInstance() - .type(type) - .keyName(key) - .property(propertyKey, propertyValue) - .build(); + .type(type) + .keyName(key) + .property(TEST_KEY, TEST_VALUE) + .build(); var result = transformer.transform(message, context); assertThat(result).isNotNull(); - assertThat(result.getJsonString(propertyKey).getString()).isEqualTo(propertyValue); - assertThat(result.getJsonString("type").getString()).isEqualTo(type); - assertThat(result.getJsonString("keyName").getString()).isEqualTo(key); + assertThat(result.getJsonString(TEST_KEY).getString()).isEqualTo(TEST_VALUE); + assertThat(result.getJsonString(DataAddress.TYPE).getString()).isEqualTo(type); + assertThat(result.getJsonString(DataAddress.KEY_NAME).getString()).isEqualTo(key); + + verify(context, never()).reportProblem(anyString()); + } + + @Test + void transform_withNamespace() { + var schema = "https://some.custom.org/schema/"; + var message = DataAddress.Builder.newInstance() + .type(type) + .keyName(key) + .property(schema + TEST_KEY, TEST_VALUE) + .build(); + var result = transformer.transform(message, context); + assertThat(result).isNotNull(); + assertThat(result.getJsonString(schema + TEST_KEY).getString()).isEqualTo(TEST_VALUE); verify(context, never()).reportProblem(anyString()); } } diff --git a/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/transformer/from/JsonObjectFromAssetTransformer.java b/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/transformer/from/JsonObjectFromAssetTransformer.java index 18e0de6e412..3daa0c9f5f0 100644 --- a/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/transformer/from/JsonObjectFromAssetTransformer.java +++ b/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/transformer/from/JsonObjectFromAssetTransformer.java @@ -17,7 +17,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.json.JsonBuilderFactory; import jakarta.json.JsonObject; -import org.eclipse.edc.jsonld.spi.Namespaces; import org.eclipse.edc.jsonld.spi.PropertyAndTypeNames; import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; import org.eclipse.edc.spi.types.domain.asset.Asset; @@ -30,6 +29,7 @@ import static java.util.stream.Collectors.toMap; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; public class JsonObjectFromAssetTransformer extends AbstractJsonLdTransformer { private final ObjectMapper mapper; @@ -49,7 +49,7 @@ public JsonObjectFromAssetTransformer(JsonBuilderFactory jsonFactory, ObjectMapp // replace the special asset properties, starting with "asset:prop:", with the EDC_SCHEMA var props = asset.getProperties().entrySet().stream() - .collect(toMap(entry -> entry.getKey().replace("asset:prop:", Namespaces.EDC_SCHEMA), Map.Entry::getValue)); + .collect(toMap(entry -> entry.getKey().replace("asset:prop:", EDC_NAMESPACE), Map.Entry::getValue)); transformProperties(props, builder, mapper, context); diff --git a/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToDataAddressTransformer.java b/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToDataAddressTransformer.java new file mode 100644 index 00000000000..da9b28e6979 --- /dev/null +++ b/extensions/common/json-ld/src/main/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToDataAddressTransformer.java @@ -0,0 +1,62 @@ +/* + * 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.jsonld.transformer.to; + +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonValue; +import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.transform.spi.TransformerContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; + + +/** + * Converts from an {@link DataAddress} as a {@link JsonObject} in JSON-LD expanded form to an {@link DataAddress}. + */ +public class JsonObjectToDataAddressTransformer extends AbstractJsonLdTransformer { + + //TODO: move into a module-level constants file + public static final String PROPERTIES_KEY = EDC_NAMESPACE + "properties"; + + public JsonObjectToDataAddressTransformer() { + super(JsonObject.class, DataAddress.class); + } + + @Override + public @Nullable DataAddress transform(@NotNull JsonObject jsonObject, @NotNull TransformerContext context) { + var builder = DataAddress.Builder.newInstance(); + visitProperties(jsonObject, (s, v) -> transformProperties(s, v, builder, context)); + return builder.build(); + } + + private void transformProperties(String key, JsonValue jsonValue, DataAddress.Builder builder, TransformerContext context) { + if ((PROPERTIES_KEY).equals(key) && jsonValue instanceof JsonArray) { + var props = jsonValue.asJsonArray().getJsonObject(0); + visitProperties(props, (k, val) -> transformProperties(k, val, builder, context)); + } else { + var object = transformGenericProperty(jsonValue, context); + if (object instanceof String) { + builder.property(key, object.toString()); + } else { + context.reportProblem("DataAddress#properties can only contain Strings, but an attempt was made to put in a " + object.getClass()); + } + } + + } +} diff --git a/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/PayloadTransformer.java b/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/PayloadTransformer.java index daeff30f13f..d2b3e6d6690 100644 --- a/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/PayloadTransformer.java +++ b/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/PayloadTransformer.java @@ -15,12 +15,13 @@ package org.eclipse.edc.jsonld.transformer; import jakarta.json.JsonObject; -import org.eclipse.edc.jsonld.spi.Namespaces; import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; import org.eclipse.edc.transform.spi.TransformerContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; + public class PayloadTransformer extends AbstractJsonLdTransformer { public PayloadTransformer() { @@ -30,8 +31,8 @@ public PayloadTransformer() { @Override public @Nullable Payload transform(@NotNull JsonObject jsonObject, @NotNull TransformerContext context) { var payload = new Payload(); - var nameObj = jsonObject.get(Namespaces.EDC_SCHEMA + "name"); - var ageObj = jsonObject.get(Namespaces.EDC_SCHEMA + "age"); + var nameObj = jsonObject.get(EDC_NAMESPACE + "name"); + var ageObj = jsonObject.get(EDC_NAMESPACE + "age"); transformString(nameObj, payload::setName, context); var age = (Double) transformGenericProperty(ageObj, context); payload.setAge(age.intValue()); diff --git a/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/from/JsonObjectFromAssetTransformerTest.java b/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/from/JsonObjectFromAssetTransformerTest.java index b82d0139a3b..5cf121f37a7 100644 --- a/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/from/JsonObjectFromAssetTransformerTest.java +++ b/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/from/JsonObjectFromAssetTransformerTest.java @@ -16,7 +16,6 @@ import jakarta.json.Json; import jakarta.json.JsonObject; -import org.eclipse.edc.jsonld.spi.Namespaces; import org.eclipse.edc.jsonld.spi.PropertyAndTypeNames; import org.eclipse.edc.jsonld.transformer.Payload; import org.eclipse.edc.spi.types.domain.asset.Asset; @@ -30,6 +29,7 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.edc.jsonld.util.JacksonJsonLd.createObjectMapper; +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; import static org.mockito.Mockito.mock; class JsonObjectFromAssetTransformerTest { @@ -56,11 +56,11 @@ void transform_noCustomProperties() { assertThat(jsonObject).isNotNull().hasSize(7); assertThat(jsonObject.getJsonString(ID).getString()).isEqualTo(TEST_ASSET_ID); assertThat(jsonObject.getJsonString(TYPE).getString()).isEqualTo(PropertyAndTypeNames.EDC_ASSET_TYPE); - assertThat(jsonObject.getJsonString(Namespaces.EDC_SCHEMA + "id").getString()).isEqualTo(TEST_ASSET_ID); - assertThat(jsonObject.getJsonString(Namespaces.EDC_SCHEMA + "contenttype").getString()).isEqualTo(TEST_CONTENT_TYPE); - assertThat(jsonObject.getJsonString(Namespaces.EDC_SCHEMA + "description").getString()).isEqualTo(TEST_DESCRIPTION); - assertThat(jsonObject.getJsonString(Namespaces.EDC_SCHEMA + "name").getString()).isEqualTo(TEST_ASSET_NAME); - assertThat(jsonObject.getJsonString(Namespaces.EDC_SCHEMA + "version").getString()).isEqualTo(TEST_VERSION); + assertThat(jsonObject.getJsonString(EDC_NAMESPACE + "id").getString()).isEqualTo(TEST_ASSET_ID); + assertThat(jsonObject.getJsonString(EDC_NAMESPACE + "contenttype").getString()).isEqualTo(TEST_CONTENT_TYPE); + assertThat(jsonObject.getJsonString(EDC_NAMESPACE + "description").getString()).isEqualTo(TEST_DESCRIPTION); + assertThat(jsonObject.getJsonString(EDC_NAMESPACE + "name").getString()).isEqualTo(TEST_ASSET_NAME); + assertThat(jsonObject.getJsonString(EDC_NAMESPACE + "version").getString()).isEqualTo(TEST_VERSION); } @Test diff --git a/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToAssetTransformerTest.java b/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToAssetTransformerTest.java index 2037e5e210a..755295e520d 100644 --- a/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToAssetTransformerTest.java +++ b/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToAssetTransformerTest.java @@ -18,9 +18,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.json.Json; import jakarta.json.JsonBuilderFactory; -import jakarta.json.JsonObject; import jakarta.json.JsonObjectBuilder; -import org.eclipse.edc.jsonld.spi.Namespaces; import org.eclipse.edc.jsonld.spi.PropertyAndTypeNames; import org.eclipse.edc.jsonld.spi.transformer.JsonLdTransformerRegistryImpl; import org.eclipse.edc.jsonld.transformer.Payload; @@ -39,7 +37,7 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; import static org.eclipse.edc.jsonld.util.JacksonJsonLd.createObjectMapper; -import static org.eclipse.edc.junit.testfixtures.TestUtils.getResourceFileContentAsString; +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; class JsonObjectToAssetTransformerTest { @@ -63,7 +61,7 @@ void setUp() throws JsonProcessingException { typeTransformerRegistry.register(new JsonValueToGenericTypeTransformer(jsonPmapper)); typeTransformerRegistry.register(transformer); typeTransformerRegistry.register(new PayloadTransformer()); - typeTransformerRegistry.registerTypeAlias(Namespaces.EDC_SCHEMA + "customPayload", Payload.class); + typeTransformerRegistry.registerTypeAlias(EDC_NAMESPACE + "customPayload", Payload.class); } @Test @@ -103,7 +101,7 @@ void transform_withCustomProperty() { AbstractResultAssert.assertThat(asset).withFailMessage(asset::getFailureDetail).isSucceeded(); assertThat(asset.getContent().getProperties()) .hasSize(6) - .hasEntrySatisfying(Namespaces.EDC_SCHEMA + "payload", o -> assertThat(o).isInstanceOf(Payload.class) + .hasEntrySatisfying(EDC_NAMESPACE + "payload", o -> assertThat(o).isInstanceOf(Payload.class) .hasFieldOrPropertyWithValue("age", CUSTOM_PAYLOAD_AGE) .hasFieldOrPropertyWithValue("name", CUSTOM_PAYLOAD_NAME)); } @@ -163,22 +161,8 @@ private JsonObjectBuilder createPropertiesBuilder() { private JsonObjectBuilder createContextBuilder() { return jsonFactory.createObjectBuilder() - .add(VOCAB, Namespaces.EDC_SCHEMA) - .add("edc", Namespaces.EDC_SCHEMA); - } - - /** - * will read the resource with the given name, assuming it's JSON, and expand it to JSON-LD's expanded form. - */ - private JsonObject parseJson(String filename) { - try { - var jsonLd = getResourceFileContentAsString(filename); - JsonObject assetJsonObject = jsonPmapper.readValue(jsonLd, JsonObject.class); - var expandedJsonLd = JsonLdUtil.expand(assetJsonObject).getJsonObject(0); - return expandedJsonLd; - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } + .add(VOCAB, EDC_NAMESPACE) + .add("edc", EDC_NAMESPACE); } diff --git a/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToDataAddressTransformerTest.java b/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToDataAddressTransformerTest.java new file mode 100644 index 00000000000..947c8fe9afa --- /dev/null +++ b/extensions/common/json-ld/src/test/java/org/eclipse/edc/jsonld/transformer/to/JsonObjectToDataAddressTransformerTest.java @@ -0,0 +1,127 @@ +/* + * 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.jsonld.transformer.to; + +import jakarta.json.JsonObject; +import jakarta.json.JsonObjectBuilder; +import jakarta.json.JsonValue; +import org.eclipse.edc.jsonld.transformer.Payload; +import org.eclipse.edc.jsonld.util.JsonLdUtil; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.transform.spi.TransformerContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static jakarta.json.Json.createObjectBuilder; +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; +import static org.eclipse.edc.jsonld.util.JacksonJsonLd.createObjectMapper; +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.endsWith; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class JsonObjectToDataAddressTransformerTest { + private static final int CUSTOM_PAYLOAD_AGE = 34; + private static final String CUSTOM_PAYLOAD_NAME = "max"; + private static final String TEST_TYPE = "test-type"; + private static final String TEST_KEY_NAME = "test-key-name"; + private final JsonValueToGenericTypeTransformer objectTransformer = new JsonValueToGenericTypeTransformer(createObjectMapper()); + private JsonObjectToDataAddressTransformer transformer; + private TransformerContext transformerContext; + + @BeforeEach + void setUp() { + transformer = new JsonObjectToDataAddressTransformer(); + transformerContext = mock(TransformerContext.class); + when(transformerContext.transform(isA(JsonObject.class), eq(Object.class))) + .thenAnswer(i -> objectTransformer.transform(i.getArgument(0), transformerContext)); + } + + @Test + void transform() { + var json = JsonLdUtil.expand(createDataAddress().build()).getJsonObject(0); + + var dataAddress = transformer.transform(json, transformerContext); + assertThat(dataAddress).isNotNull(); + assertThat(dataAddress.getType()).isEqualTo(TEST_TYPE); + assertThat(dataAddress.getKeyName()).isEqualTo(TEST_KEY_NAME); + } + + @Test + void transform_withCustomProps() { + var json = createDataAddress() + .add(EDC_NAMESPACE + "properties", createObjectBuilder() + .add("my-test-prop", "some-test-value") + .build()) + .build(); + json = JsonLdUtil.expand(json) + .getJsonObject(0); + + var dataAddress = transformer.transform(json, transformerContext); + assertThat(dataAddress).isNotNull(); + assertThat(dataAddress.getType()).isEqualTo(TEST_TYPE); + assertThat(dataAddress.getProperty(EDC_NAMESPACE + "my-test-prop")).isEqualTo("some-test-value"); + } + + @Test + void transform_withComplexCustomProps_shouldReportProblem() { + when(transformerContext.typeAlias(endsWith("customPayload"))).thenAnswer(i -> Payload.class); + when(transformerContext.transform(isA(JsonValue.class), eq(Payload.class))).thenReturn(new Payload(CUSTOM_PAYLOAD_NAME, CUSTOM_PAYLOAD_AGE)); + var json = createDataAddress() + .add(EDC_NAMESPACE + "properties", createObjectBuilder() + .add("payload", createPayloadBuilder().build()) + .build()) + .build(); + json = JsonLdUtil.expand(json) + .getJsonObject(0); + + var dataAddress = transformer.transform(json, transformerContext); + assertThat(dataAddress).isNotNull(); + assertThat(dataAddress.getType()).isEqualTo(TEST_TYPE); + assertThat(dataAddress.getKeyName()).isEqualTo(TEST_KEY_NAME); + assertThat(dataAddress.getProperties()).hasSize(2); + + verify(transformerContext).reportProblem(any()); + } + + private JsonObjectBuilder createDataAddress() { + return createObjectBuilder() + .add(CONTEXT, createContextBuilder().build()) + .add(TYPE, EDC_NAMESPACE + "DataAddress") + .add(EDC_NAMESPACE + DataAddress.TYPE, TEST_TYPE) + .add(EDC_NAMESPACE + DataAddress.KEY_NAME, TEST_KEY_NAME); + } + + private JsonObjectBuilder createContextBuilder() { + return createObjectBuilder() + .add(VOCAB, EDC_NAMESPACE) + .add("edc", EDC_NAMESPACE); + } + + private JsonObjectBuilder createPayloadBuilder() { + return createObjectBuilder() + .add(TYPE, "customPayload") + .add("name", CUSTOM_PAYLOAD_NAME) + .add("age", CUSTOM_PAYLOAD_AGE); + } + +} \ No newline at end of file diff --git a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/CoreConstants.java b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/CoreConstants.java new file mode 100644 index 00000000000..c303da9a7b3 --- /dev/null +++ b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/CoreConstants.java @@ -0,0 +1,20 @@ +/* + * 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.spi; + +public interface CoreConstants { + //todo: this must be replaced once we have a default EDC schema! + String EDC_NAMESPACE = "https://foo.bar.org/ds/schema/"; +} diff --git a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/types/domain/DataAddress.java b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/types/domain/DataAddress.java index 33211e526da..d6ce40cd179 100644 --- a/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/types/domain/DataAddress.java +++ b/spi/common/core-spi/src/main/java/org/eclipse/edc/spi/types/domain/DataAddress.java @@ -24,6 +24,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Optional; + +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; /** * An address that can be used resolve a data location. Data addresses are used throughout the system. For example, an asset has a data address used to resolve its contents, @@ -44,7 +47,7 @@ protected DataAddress() { @NotNull public String getType() { - return properties.get(TYPE); + return Optional.ofNullable(properties.get(EDC_NAMESPACE + TYPE)).orElseGet(() -> properties.get(TYPE)); } @JsonIgnore @@ -70,7 +73,13 @@ public Map getProperties() { } public String getKeyName() { - return properties.get(KEY_NAME); + return Optional.ofNullable(properties.get(EDC_NAMESPACE + KEY_NAME)).orElseGet(() -> properties.get(KEY_NAME)); + } + + @JsonIgnore + public void setKeyName(String keyName) { + Objects.requireNonNull(keyName); + properties.put(KEY_NAME, keyName); } /** @@ -84,12 +93,6 @@ public boolean hasProperty(String key) { return properties.containsKey(key); } - @JsonIgnore - public void setKeyName(String keyName) { - Objects.requireNonNull(keyName); - properties.put(KEY_NAME, keyName); - } - @JsonPOJOBuilder(withPrefix = "") public static class Builder> { protected final DA address; diff --git a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/Namespaces.java b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/Namespaces.java index 11225a3b01f..5ca9c07f312 100644 --- a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/Namespaces.java +++ b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/Namespaces.java @@ -28,7 +28,4 @@ public interface Namespaces { String DCT_PREFIX = "dct"; String DCT_SCHEMA = "https://purl.org/dc/terms/"; - //todo: this must be replaced once we have a default EDC schema! - String EDC_SCHEMA = "https://foo.bar.org/ds/schema/"; - } diff --git a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java index 0a372375cba..19b10c57f6f 100644 --- a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java +++ b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java @@ -16,8 +16,8 @@ import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_SCHEMA; import static org.eclipse.edc.jsonld.spi.Namespaces.DCT_SCHEMA; -import static org.eclipse.edc.jsonld.spi.Namespaces.EDC_SCHEMA; import static org.eclipse.edc.jsonld.spi.Namespaces.ODRL_SCHEMA; +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; /** * Collection of DCAT, DCT and ODRL type and attribute names. @@ -29,12 +29,12 @@ public interface PropertyAndTypeNames { String DCAT_DISTRIBUTION_TYPE = DCAT_SCHEMA + "Distribution"; String DCAT_DATA_SERVICE_TYPE = DCAT_SCHEMA + "DataService"; - String EDC_ASSET_TYPE = EDC_SCHEMA + "Asset"; - String EDC_ASSET_PROPERTIES = EDC_SCHEMA + "properties"; - String EDC_ASSET_NAME = EDC_SCHEMA + "name"; - String EDC_ASSET_DESCRIPTION = EDC_SCHEMA + "description"; - String EDC_ASSET_VERSION = EDC_SCHEMA + "version"; - String EDC_ASSET_CONTENTTYPE = EDC_SCHEMA + "contenttype"; + String EDC_ASSET_TYPE = EDC_NAMESPACE + "Asset"; + String EDC_ASSET_PROPERTIES = EDC_NAMESPACE + "properties"; + String EDC_ASSET_NAME = EDC_NAMESPACE + "name"; + String EDC_ASSET_DESCRIPTION = EDC_NAMESPACE + "description"; + String EDC_ASSET_VERSION = EDC_NAMESPACE + "version"; + String EDC_ASSET_CONTENTTYPE = EDC_NAMESPACE + "contenttype"; String DCAT_DATA_SERVICE_ATTRIBUTE = DCAT_SCHEMA + "service"; String DCAT_DATASET_ATTRIBUTE = DCAT_SCHEMA + "dataset";