Skip to content

Commit

Permalink
feat: UiAsset + AssetMapper (#512)
Browse files Browse the repository at this point in the history
Co-authored-by: Richard Treier <richard.treier@sovity.de>
  • Loading branch information
SaadEGI and richardtreier authored Sep 19, 2023
1 parent 232555b commit 118ea19
Show file tree
Hide file tree
Showing 53 changed files with 1,348 additions and 368 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ All notable changes to this project will be documented in this file.
### Minor Changes

- UI API Wrapper Model:
- Opinionated Policy Model and Mappers for EDC UI and Broker Server Extension
- UiPolicy + PolicyMapper for EDC UI and Broker Server
- UiAsset + AssetMapper for EDC UI and Broker Server
- UI API Wrapper Endpoints:
- Asset Page
- Create Asset
Expand Down
2 changes: 1 addition & 1 deletion extensions/wrapper/client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ dependencies {
testImplementation("${jettyGroup}:jetty-util:${jettyVersion}")
testImplementation("${jettyGroup}:jetty-webapp:${jettyVersion}")

testImplementation("${edcGroup}:json-ld-spi:${edcVersion}")
testImplementation("${edcGroup}:json-ld:${edcVersion}")
testImplementation("${edcGroup}:dsp-http-spi:${edcVersion}")
testImplementation("${edcGroup}:dsp-api-configuration:${edcVersion}")
testImplementation(project(":extensions:wrapper:wrapper"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
package de.sovity.edc.client;


import de.sovity.edc.client.gen.model.AssetCreateRequest;
import de.sovity.edc.ext.wrapper.utils.EdcPropertyUtils;
import de.sovity.edc.client.gen.model.UiAsset;
import de.sovity.edc.client.gen.model.UiAssetCreateRequest;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.EdcPropertyUtils;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.FailedMappingException;
import de.sovity.edc.utils.jsonld.vocab.Prop;
import lombok.SneakyThrows;
import org.eclipse.edc.connector.spi.asset.AssetService;
import org.eclipse.edc.junit.annotations.ApiTest;
Expand All @@ -28,17 +31,16 @@
import org.junit.jupiter.api.extension.ExtendWith;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.edc.spi.types.domain.DataAddress.EDC_DATA_ADDRESS_TYPE_PROPERTY;

@ApiTest
@ExtendWith(EdcExtension.class)
public class AssetApiServiceTest {

public static final String DATA_SINK = "http://my-data-sink/api/stuff";
public static final String DATA_ADDRESS_TYPE = "HttpData";
EdcPropertyUtils edcPropertyUtils;

@BeforeEach
Expand All @@ -51,12 +53,11 @@ void setUp(EdcExtension extension) {
void assetPage(AssetService assetStore) {
// arrange
var client = TestUtils.edcClient();
var privateProperties = Map.of("random-private-prop", "456");
var properties = Map.of(
Asset.PROPERTY_ID, "asset-1",
"random-prop", "123"
Prop.Dcat.LANDING_PAGE, "https://data-source.my-org/docs"
);
createAsset(assetStore, "2023-06-01", properties, privateProperties);
createAsset(assetStore, "2023-06-01", properties);

// act
var result = client.uiApi().assetPage();
Expand All @@ -65,65 +66,149 @@ void assetPage(AssetService assetStore) {
var assets = result.getAssets();
assertThat(assets).hasSize(1);
var asset = assets.get(0);
assertThat(asset.getProperties()).isEqualTo(properties);
assertThat(asset.getPrivateProperties()).isEqualTo(privateProperties);
assertThat(asset.getAssetId()).isEqualTo(properties.get(Asset.PROPERTY_ID));
assertThat(asset.getLandingPageUrl()).isEqualTo(properties.get(Prop.Dcat.LANDING_PAGE));
}


@Test
void assetPageSorting(AssetService assetService) {
// arrange
var client = TestUtils.edcClient();
createAsset(assetService, "2023-06-01", Map.of(Asset.PROPERTY_ID, "asset-1"), Map.of());
createAsset(assetService, "2023-06-03", Map.of(Asset.PROPERTY_ID, "asset-3"), Map.of());
createAsset(assetService, "2023-06-02", Map.of(Asset.PROPERTY_ID, "asset-2"), Map.of());
createAsset(assetService, "2023-06-01", Map.of(Asset.PROPERTY_ID, "asset-1"));
createAsset(assetService, "2023-06-03", Map.of(Asset.PROPERTY_ID, "asset-3"));
createAsset(assetService, "2023-06-02", Map.of(Asset.PROPERTY_ID, "asset-2"));

// act
var result = client.uiApi().assetPage();

// assert
assertThat(result.getAssets())
.extracting(asset -> asset.getProperties().get(Asset.PROPERTY_ID))
.extracting(UiAsset::getAssetId)
.containsExactly("asset-3", "asset-2", "asset-1");
}

@Test
void testAssetCreation(AssetService assetService) {
// arrange
var client = TestUtils.edcClient();
var properties = Map.of(
Asset.PROPERTY_ID, "asset-1",
"random-prop", "123"
var dataAddressProperties = Map.of(
Prop.Edc.TYPE, "HttpData",
Prop.Edc.BASE_URL, DATA_SINK,
Prop.Edc.PROXY_METHOD, "true",
Prop.Edc.PROXY_PATH, "true",
Prop.Edc.PROXY_QUERY_PARAMS, "true",
Prop.Edc.PROXY_BODY, "true"
);
var uiAssetRequest = UiAssetCreateRequest.builder()
.id("asset-1")
.name("AssetName")
.description("AssetDescription")
.licenseUrl("https://license-url")
.version("1.0.0")
.language("en")
.mediaType("application/json")
.dataCategory("dataCategory")
.dataSubcategory("dataSubcategory")
.dataModel("dataModel")
.geoReferenceMethod("geoReferenceMethod")
.transportMode("transportMode")
.keywords(List.of("keyword1", "keyword2"))
.creatorOrganizationName("creatorOrganizationName")
.publisherHomepage("publisherHomepage")
.dataAddressProperties(dataAddressProperties)
.build();

// act
var response = client.uiApi().createAsset(uiAssetRequest);

// assert
assertThat(response.getId()).isEqualTo("asset-1");

var assets = client.uiApi().assetPage().getAssets();
assertThat(assets).hasSize(1);
var asset = assets.get(0);
assertThat(asset.getAssetId()).isEqualTo("asset-1");
assertThat(asset.getName()).isEqualTo("AssetName");
assertThat(asset.getDescription()).isEqualTo("AssetDescription");
assertThat(asset.getVersion()).isEqualTo("1.0.0");
assertThat(asset.getLanguage()).isEqualTo("en");
assertThat(asset.getMediaType()).isEqualTo("application/json");
assertThat(asset.getDataCategory()).isEqualTo("dataCategory");
assertThat(asset.getDataSubcategory()).isEqualTo("dataSubcategory");
assertThat(asset.getDataModel()).isEqualTo("dataModel");
assertThat(asset.getGeoReferenceMethod()).isEqualTo("geoReferenceMethod");
assertThat(asset.getTransportMode()).isEqualTo("transportMode");
assertThat(asset.getLicenseUrl()).isEqualTo("https://license-url");
assertThat(asset.getKeywords()).isEqualTo(List.of("keyword1", "keyword2"));
assertThat(asset.getCreatorOrganizationName()).isEqualTo("creatorOrganizationName");
assertThat(asset.getPublisherHomepage()).isEqualTo("publisherHomepage");
assertThat(asset.getHttpDatasourceHintsProxyMethod()).isTrue();
assertThat(asset.getHttpDatasourceHintsProxyPath()).isTrue();
assertThat(asset.getHttpDatasourceHintsProxyQueryParams()).isTrue();
assertThat(asset.getHttpDatasourceHintsProxyBody()).isTrue();

var assetWithDataAddress = assetService.query(QuerySpec.max()).orElseThrow(FailedMappingException::ofFailure).toList().get(0);
assertThat(assetWithDataAddress.getDataAddress().getProperties()).isEqualTo(dataAddressProperties);
}

@Test
void testAssetCreation_noProxying() {
// arrange
var client = TestUtils.edcClient();
var dataAddressProperties = Map.of(
Prop.Edc.TYPE, "HttpData",
Prop.Edc.BASE_URL, DATA_SINK
);
var privateProperties = Map.of("random-private-prop", "456");
var uiAssetRequest = UiAssetCreateRequest.builder()
.id("asset-1")
.dataAddressProperties(dataAddressProperties)
.build();

// act
var response = client.uiApi().createAsset(uiAssetRequest);

// assert
assertThat(response.getId()).isEqualTo("asset-1");
var assets = client.uiApi().assetPage().getAssets();
assertThat(assets).hasSize(1);
var asset = assets.get(0);
assertThat(asset.getHttpDatasourceHintsProxyMethod()).isFalse();
assertThat(asset.getHttpDatasourceHintsProxyPath()).isFalse();
assertThat(asset.getHttpDatasourceHintsProxyQueryParams()).isFalse();
assertThat(asset.getHttpDatasourceHintsProxyBody()).isFalse();
}

@Test
void testAssetCreation_differentDataAddressType() {
// arrange
var client = TestUtils.edcClient();
var dataAddressProperties = Map.of(
EDC_DATA_ADDRESS_TYPE_PROPERTY, DATA_ADDRESS_TYPE,
"baseUrl", DATA_SINK
Prop.Edc.TYPE, "Unknown"
);
var assetRequest = AssetCreateRequest.builder()
.properties(properties)
.privateProperties(privateProperties)
var uiAssetRequest = UiAssetCreateRequest.builder()
.id("asset-1")
.dataAddressProperties(dataAddressProperties)
.build();

// act
var response = client.uiApi().createAsset(assetRequest);
var response = client.uiApi().createAsset(uiAssetRequest);

// assert
assertThat(response.getId()).isEqualTo(properties.get(Asset.PROPERTY_ID));
var assets = assetService.query(QuerySpec.max()).getContent().toList();
assertThat(response.getId()).isEqualTo("asset-1");
var assets = client.uiApi().assetPage().getAssets();
assertThat(assets).hasSize(1);
var asset = assets.get(0);
assertThat(asset.getProperties()).isEqualTo(properties);
assertThat(asset.getPrivateProperties()).isEqualTo(privateProperties);
assertThat(asset.getDataAddress().getProperties()).isEqualTo(dataAddressProperties);
assertThat(asset.getHttpDatasourceHintsProxyMethod()).isNull();
assertThat(asset.getHttpDatasourceHintsProxyPath()).isNull();
assertThat(asset.getHttpDatasourceHintsProxyQueryParams()).isNull();
assertThat(asset.getHttpDatasourceHintsProxyBody()).isNull();
}

@Test
void testDeleteAsset(AssetService assetService) {
// arrange
var client = TestUtils.edcClient();
createAsset(assetService, "2023-06-01", Map.of(Asset.PROPERTY_ID, "asset-1"), Map.of());
createAsset(assetService, "2023-06-01", Map.of(Asset.PROPERTY_ID, "asset-1"));
assertThat(assetService.query(QuerySpec.max()).getContent()).isNotEmpty();

// act
Expand All @@ -137,20 +222,17 @@ void testDeleteAsset(AssetService assetService) {
private void createAsset(
AssetService assetService,
String date,
Map<String, String> properties,
Map<String, String> privateProperties
Map<String, String> properties
) {

DataAddress dataAddress = DataAddress.Builder.newInstance()
.type(DATA_ADDRESS_TYPE)
.property("baseUrl", DATA_SINK)
.type("HttpData")
.property(Prop.Edc.BASE_URL, DATA_SINK)
.build();

var asset = Asset.Builder.newInstance()
.id(properties.get(Asset.PROPERTY_ID))
.properties(edcPropertyUtils.toMapOfObject(properties))
.dataAddress(dataAddress)
.privateProperties(edcPropertyUtils.toMapOfObject(privateProperties))
.createdAt(dateFormatterToLong(date))
.build();
assetService.create(asset);
Expand All @@ -161,6 +243,5 @@ private static long dateFormatterToLong(String date) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
return formatter.parse(date).getTime();
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import de.sovity.edc.client.gen.model.ContractAgreementCard;
import de.sovity.edc.client.gen.model.TransferProcessState;
import de.sovity.edc.client.gen.model.UiPolicyConstraint;
import de.sovity.edc.utils.jsonld.vocab.Prop;
import org.eclipse.edc.connector.contract.spi.negotiation.store.ContractNegotiationStore;
import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement;
import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation;
Expand Down Expand Up @@ -93,8 +94,8 @@ void testContractAgreementPage(
assertThat(agreement.getCounterPartyAddress()).isEqualTo("http://other-connector");
assertThat(agreement.getCounterPartyId()).isEqualTo("urn:connector:other-connector");
assertThat(agreement.getContractSigningDate()).isEqualTo(todayPlusDays(0));
assertThat(agreement.getAsset().getProperties()).containsEntry("https://w3id.org/edc/v0.0.1/ns/id", ASSET_ID);
assertThat(agreement.getAsset().getProperties()).containsEntry("some-property", "X");
assertThat(agreement.getAsset().getAssetId()).isEqualTo(ASSET_ID);
assertThat(agreement.getAsset().getLandingPageUrl()).isEqualTo("X");
assertThat(agreement.getTransferProcesses()).hasSize(1);

var transfer = agreement.getTransferProcesses().get(0);
Expand Down Expand Up @@ -178,7 +179,7 @@ private ContractNegotiation contractDefinition(int contract) {
private Asset asset(String assetId) {
return Asset.Builder.newInstance()
.id(assetId)
.property("some-property", "X")
.property(Prop.Dcat.LANDING_PAGE, "X")
.createdAt(todayEpochMillis)
.dataAddress(dataAddress())
.build();
Expand Down
Loading

0 comments on commit 118ea19

Please sign in to comment.