Skip to content

Commit

Permalink
fix: sub-catalogs serialization (eclipse-edc#4588)
Browse files Browse the repository at this point in the history
* fix: sub-catalogs serialization

* chore: fixes tests
  • Loading branch information
wolf4ood authored Nov 12, 2024
1 parent c6bb542 commit fab363c
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@
import jakarta.json.JsonBuilderFactory;
import jakarta.json.JsonObject;
import org.eclipse.edc.connector.controlplane.catalog.spi.Catalog;
import org.eclipse.edc.connector.controlplane.catalog.spi.Dataset;
import org.eclipse.edc.jsonld.spi.JsonLdNamespace;
import org.eclipse.edc.jsonld.spi.transformer.AbstractNamespaceAwareJsonLdTransformer;
import org.eclipse.edc.participant.spi.ParticipantIdMapper;
import org.eclipse.edc.transform.spi.TransformerContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.stream.Collectors;

import static jakarta.json.stream.JsonCollectors.toJsonArray;
import static java.util.Optional.ofNullable;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_CATALOG_ATTRIBUTE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_CATALOG_TYPE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATASET_ATTRIBUTE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATA_SERVICE_ATTRIBUTE;
Expand Down Expand Up @@ -57,7 +62,15 @@ public JsonObjectFromCatalogTransformer(JsonBuilderFactory jsonFactory, ObjectMa

@Override
public @Nullable JsonObject transform(@NotNull Catalog catalog, @NotNull TransformerContext context) {
var datasets = catalog.getDatasets().stream()
var partitions = catalog.getDatasets().stream().collect(Collectors.groupingBy(Dataset::getClass));

var datasets = ofNullable(partitions.get(Dataset.class)).orElseGet(ArrayList::new)
.stream()
.map(offer -> context.transform(offer, JsonObject.class))
.collect(toJsonArray());

var subCatalogs = ofNullable(partitions.get(Catalog.class)).orElseGet(ArrayList::new)
.stream()
.map(offer -> context.transform(offer, JsonObject.class))
.collect(toJsonArray());

Expand All @@ -73,6 +86,7 @@ public JsonObjectFromCatalogTransformer(JsonBuilderFactory jsonFactory, ObjectMa
.add(ID, catalog.getId())
.add(TYPE, DCAT_CATALOG_TYPE)
.add(DCAT_DATASET_ATTRIBUTE, datasets)
.add(DCAT_CATALOG_ATTRIBUTE, subCatalogs)
.add(DCAT_DISTRIBUTION_ATTRIBUTE, distributions)
.add(DCAT_DATA_SERVICE_ATTRIBUTE, dataServices);

Expand All @@ -82,4 +96,5 @@ public JsonObjectFromCatalogTransformer(JsonBuilderFactory jsonFactory, ObjectMa

return objectBuilder.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@
import jakarta.json.JsonBuilderFactory;
import jakarta.json.JsonObject;
import org.eclipse.edc.connector.controlplane.catalog.spi.Catalog;
import org.eclipse.edc.connector.controlplane.catalog.spi.Dataset;
import org.eclipse.edc.jsonld.spi.JsonLdNamespace;
import org.eclipse.edc.jsonld.spi.transformer.AbstractNamespaceAwareJsonLdTransformer;
import org.eclipse.edc.participant.spi.ParticipantIdMapper;
import org.eclipse.edc.transform.spi.TransformerContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.stream.Collectors;

import static jakarta.json.stream.JsonCollectors.toJsonArray;
import static java.util.Optional.ofNullable;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_CATALOG_ATTRIBUTE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_CATALOG_TYPE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATASET_ATTRIBUTE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATA_SERVICE_ATTRIBUTE;
Expand Down Expand Up @@ -57,7 +62,15 @@ public JsonObjectFromCatalogV2024Transformer(JsonBuilderFactory jsonFactory, Obj

@Override
public @Nullable JsonObject transform(@NotNull Catalog catalog, @NotNull TransformerContext context) {
var datasets = catalog.getDatasets().stream()
var partitions = catalog.getDatasets().stream().collect(Collectors.groupingBy(Dataset::getClass));

var datasets = ofNullable(partitions.get(Dataset.class)).orElseGet(ArrayList::new)
.stream()
.map(offer -> context.transform(offer, JsonObject.class))
.collect(toJsonArray());

var subCatalogs = ofNullable(partitions.get(Catalog.class)).orElseGet(ArrayList::new)
.stream()
.map(offer -> context.transform(offer, JsonObject.class))
.collect(toJsonArray());

Expand All @@ -73,6 +86,7 @@ public JsonObjectFromCatalogV2024Transformer(JsonBuilderFactory jsonFactory, Obj
.add(ID, catalog.getId())
.add(TYPE, DCAT_CATALOG_TYPE)
.add(DCAT_DATASET_ATTRIBUTE, datasets)
.add(DCAT_CATALOG_ATTRIBUTE, subCatalogs)
.add(DCAT_DISTRIBUTION_ATTRIBUTE, distributions)
.add(DCAT_DATA_SERVICE_ATTRIBUTE, dataServices);

Expand All @@ -82,4 +96,5 @@ public JsonObjectFromCatalogV2024Transformer(JsonBuilderFactory jsonFactory, Obj

return objectBuilder.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_CATALOG_ATTRIBUTE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_CATALOG_TYPE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATASET_ATTRIBUTE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATA_SERVICE_ATTRIBUTE;
Expand All @@ -61,15 +62,18 @@ class JsonObjectFromCatalogTransformerTest {
private final JsonObjectFromCatalogTransformer transformer = new JsonObjectFromCatalogTransformer(jsonFactory, mapper, participantIdMapper);

private JsonObject datasetJson;
private JsonObject catalogJson;
private JsonObject dataServiceJson;

@BeforeEach
void setUp() {

datasetJson = getJsonObject("dataset");
catalogJson = getJsonObject("Catalog");
dataServiceJson = getJsonObject("dataService");

when(context.transform(isA(Dataset.class), eq(JsonObject.class))).thenReturn(datasetJson);
when(context.transform(isA(Catalog.class), eq(JsonObject.class))).thenReturn(catalogJson);
when(context.transform(isA(DataService.class), eq(JsonObject.class))).thenReturn(dataServiceJson);
when(context.problem()).thenReturn(new ProblemBuilder(context));
when(participantIdMapper.toIri(any())).thenReturn("urn:namespace:participantId");
Expand Down Expand Up @@ -104,6 +108,41 @@ void transform_returnJsonObject() {
verify(context, times(1)).transform(catalog.getDataServices().get(0), JsonObject.class);
}

@Test
void transform_SubCatalogs_returnJsonObject() {
when(mapper.convertValue(any(), eq(JsonValue.class))).thenReturn(Json.createValue("value"));
var catalog = getCatalogWithSubCatalog();

var result = transformer.transform(catalog, context);

assertThat(result).isNotNull();
assertThat(result.getJsonString(ID).getString()).isEqualTo(catalog.getId());
assertThat(result.getJsonString(TYPE).getString()).isEqualTo(DCAT_CATALOG_TYPE);

assertThat(result.get(DCAT_DATASET_ATTRIBUTE))
.isNotNull()
.isInstanceOf(JsonArray.class)
.matches(v -> v.asJsonArray().size() == 1)
.matches(v -> v.asJsonArray().get(0).equals(datasetJson));

assertThat(result.get(DCAT_CATALOG_ATTRIBUTE))
.isNotNull()
.isInstanceOf(JsonArray.class)
.matches(v -> v.asJsonArray().size() == 1)
.matches(v -> v.asJsonArray().get(0).equals(catalogJson));

assertThat(result.get(DCAT_DATA_SERVICE_ATTRIBUTE))
.isNotNull()
.isInstanceOf(JsonArray.class)
.matches(v -> v.asJsonArray().size() == 1)
.matches(v -> v.asJsonArray().get(0).equals(dataServiceJson));
assertThat(result.getString(DSPACE_PROPERTY_PARTICIPANT_ID_IRI)).isEqualTo("urn:namespace:participantId");
assertThat(result.get(CATALOG_PROPERTY)).isNotNull();

verify(context, times(1)).transform(catalog.getDatasets().get(0), JsonObject.class);
verify(context, times(1)).transform(catalog.getDataServices().get(0), JsonObject.class);
}

@Test
void transform_mappingPropertyFails_reportProblem() {
when(mapper.convertValue(any(), eq(JsonValue.class))).thenThrow(IllegalArgumentException.class);
Expand All @@ -118,6 +157,15 @@ void transform_mappingPropertyFails_reportProblem() {
}

private Catalog getCatalog() {
return getCatalogBuilder().build();
}

private Catalog getCatalogWithSubCatalog() {
return getCatalogBuilder()
.dataset(Catalog.Builder.newInstance().build()).build();
}

private Catalog.Builder getCatalogBuilder() {
return Catalog.Builder.newInstance()
.id("catalog")
.dataset(Dataset.Builder.newInstance()
Expand All @@ -129,8 +177,7 @@ private Catalog getCatalog() {
.build())
.dataService(DataService.Builder.newInstance().build())
.participantId("participantId")
.property(CATALOG_PROPERTY, "value")
.build();
.property(CATALOG_PROPERTY, "value");
}

private JsonObject getJsonObject(String type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_CATALOG_ATTRIBUTE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_CATALOG_TYPE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATASET_ATTRIBUTE;
import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATA_SERVICE_ATTRIBUTE;
Expand All @@ -62,15 +63,18 @@ class JsonObjectFromCatalogV2024TransformerTest {
private final JsonObjectFromCatalogV2024Transformer transformer = new JsonObjectFromCatalogV2024Transformer(jsonFactory, mapper, participantIdMapper);

private JsonObject datasetJson;
private JsonObject catalogJson;
private JsonObject dataServiceJson;

@BeforeEach
void setUp() {

datasetJson = getJsonObject("dataset");
catalogJson = getJsonObject("Catalog");
dataServiceJson = getJsonObject("dataService");

when(context.transform(isA(Dataset.class), eq(JsonObject.class))).thenReturn(datasetJson);
when(context.transform(isA(Catalog.class), eq(JsonObject.class))).thenReturn(catalogJson);
when(context.transform(isA(DataService.class), eq(JsonObject.class))).thenReturn(dataServiceJson);
when(context.problem()).thenReturn(new ProblemBuilder(context));
when(participantIdMapper.toIri(any())).thenReturn("urn:namespace:participantId");
Expand Down Expand Up @@ -105,6 +109,41 @@ void transform_returnJsonObject() {
verify(context, times(1)).transform(catalog.getDataServices().get(0), JsonObject.class);
}

@Test
void transform_SubCatalogs_returnJsonObject() {
when(mapper.convertValue(any(), eq(JsonValue.class))).thenReturn(Json.createValue("value"));
var catalog = getCatalogWithSubCatalog();

var result = transformer.transform(catalog, context);

assertThat(result).isNotNull();
assertThat(result.getJsonString(ID).getString()).isEqualTo(catalog.getId());
assertThat(result.getJsonString(TYPE).getString()).isEqualTo(DCAT_CATALOG_TYPE);

assertThat(result.get(DCAT_DATASET_ATTRIBUTE))
.isNotNull()
.isInstanceOf(JsonArray.class)
.matches(v -> v.asJsonArray().size() == 1)
.matches(v -> v.asJsonArray().get(0).equals(datasetJson));

assertThat(result.get(DCAT_CATALOG_ATTRIBUTE))
.isNotNull()
.isInstanceOf(JsonArray.class)
.matches(v -> v.asJsonArray().size() == 1)
.matches(v -> v.asJsonArray().get(0).equals(catalogJson));

assertThat(result.get(DCAT_DATA_SERVICE_ATTRIBUTE))
.isNotNull()
.isInstanceOf(JsonArray.class)
.matches(v -> v.asJsonArray().size() == 1)
.matches(v -> v.asJsonArray().get(0).equals(dataServiceJson));
assertThat(result.getJsonObject(DSP_NAMESPACE_V_2024_1.toIri(DSPACE_PROPERTY_PARTICIPANT_ID_TERM)).getString(ID)).isEqualTo("urn:namespace:participantId");
assertThat(result.get(CATALOG_PROPERTY)).isNotNull();

verify(context, times(1)).transform(catalog.getDatasets().get(0), JsonObject.class);
verify(context, times(1)).transform(catalog.getDataServices().get(0), JsonObject.class);
}

@Test
void transform_mappingPropertyFails_reportProblem() {
when(mapper.convertValue(any(), eq(JsonValue.class))).thenThrow(IllegalArgumentException.class);
Expand All @@ -119,6 +158,15 @@ void transform_mappingPropertyFails_reportProblem() {
}

private Catalog getCatalog() {
return getCatalogBuilder().build();
}

private Catalog getCatalogWithSubCatalog() {
return getCatalogBuilder()
.dataset(Catalog.Builder.newInstance().build()).build();
}

private Catalog.Builder getCatalogBuilder() {
return Catalog.Builder.newInstance()
.id("catalog")
.dataset(Dataset.Builder.newInstance()
Expand All @@ -130,8 +178,7 @@ private Catalog getCatalog() {
.build())
.dataService(DataService.Builder.newInstance().build())
.participantId("participantId")
.property(CATALOG_PROPERTY, "value")
.build();
.property(CATALOG_PROPERTY, "value");
}

private JsonObject getJsonObject(String type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public interface PropertyAndTypeNames {
String DCAT_DATA_SERVICE_TYPE = DCAT_SCHEMA + "DataService";
String DCAT_DATA_SERVICE_ATTRIBUTE = DCAT_SCHEMA + "service";
String DCAT_DATASET_ATTRIBUTE = DCAT_SCHEMA + "dataset";
String DCAT_CATALOG_ATTRIBUTE = DCAT_SCHEMA + "catalog";
String DCAT_DISTRIBUTION_ATTRIBUTE = DCAT_SCHEMA + "distribution";
String DCAT_ACCESS_SERVICE_ATTRIBUTE = DCAT_SCHEMA + "accessService";
@Deprecated(since = "0.10.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE;
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

public class CatalogApiEndToEndTest {
Expand Down Expand Up @@ -175,11 +174,11 @@ void requestCatalog_whenAssetIsCatalogAsset_shouldReturnCatalogOfCatalogs(Manage
.body(TYPE, is("dcat:Catalog"))
.body("'dcat:service'", notNullValue())
// findAll is the restAssured way to express JSON Path filters
.body("'dcat:dataset'", hasSize(2))
.body("'dcat:dataset'.findAll { it -> it.'@type' == 'dcat:Catalog' }.isCatalog", contains(true))
.body("'dcat:dataset'.findAll { it -> it.'@type' == 'dcat:Catalog' }.'@id'", contains(catalogAssetId))
.body("'dcat:dataset'.findAll { it -> it.'@type' == 'dcat:Catalog' }.'dcat:service'.'dcat:endpointUrl'", contains("http://quizzqua.zz/buzz"))
.body("'dcat:dataset'.findAll { it -> it.'@type' == 'dcat:Catalog' }.'dcat:distribution'.'dcat:accessService'.'@id'", contains(Base64.getUrlEncoder().encodeToString(catalogAssetId.getBytes())));
.body("'dcat:catalog'.'@type'", equalTo("dcat:Catalog"))
.body("'dcat:catalog'.isCatalog", equalTo(true))
.body("'dcat:catalog'.'@id'", equalTo(catalogAssetId))
.body("'dcat:catalog'.'dcat:service'.'dcat:endpointUrl'", equalTo("http://quizzqua.zz/buzz"))
.body("'dcat:catalog'.'dcat:distribution'.'dcat:accessService'.'@id'", equalTo(Base64.getUrlEncoder().encodeToString(catalogAssetId.getBytes())));
}

@Test
Expand Down

0 comments on commit fab363c

Please sign in to comment.