Skip to content

Commit

Permalink
chore: refactor CreateAsset Endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
SaadEGI committed Sep 13, 2023
1 parent ef56352 commit 1292bb7
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
package de.sovity.edc.client;


import de.sovity.edc.client.gen.model.AssetCreateRequest;
import de.sovity.edc.client.gen.model.UiAssetCreateRequest;
import de.sovity.edc.ext.wrapper.utils.EdcPropertyUtils;
import lombok.SneakyThrows;
import org.eclipse.edc.connector.spi.asset.AssetService;
Expand All @@ -28,6 +28,7 @@
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;
Expand Down Expand Up @@ -92,31 +93,27 @@ void assetPageSorting(AssetService assetService) {
void testAssetCreation(AssetService assetService) {
// arrange
var client = TestUtils.edcClient();
var properties = Map.of(
Asset.PROPERTY_ID, "asset-1",
"random-prop", "123"
);
var privateProperties = Map.of("random-private-prop", "456");
var dataAddressProperties = Map.of(
EDC_DATA_ADDRESS_TYPE_PROPERTY, DATA_ADDRESS_TYPE,
"baseUrl", DATA_SINK
);
var assetRequest = AssetCreateRequest.builder()
.properties(properties)
.privateProperties(privateProperties)
var uiAssetRequest = UiAssetCreateRequest.builder()
.id("asset-1")
.name("AssetName")
.keywords(List.of("keyword1", "keyword2"))
.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));
assertThat(response.getId()).isEqualTo("asset-1");
var assets = assetService.query(QuerySpec.max()).getContent().toList();
assertThat(assets).hasSize(1);
var asset = assets.get(0);
assertThat(asset.getProperties()).isEqualTo(properties);
assertThat(asset.getPrivateProperties()).isEqualTo(privateProperties);
assertThat(asset.getName()).isEqualTo("AssetName");
assertThat(asset.getProperties().get("keywords")).isEqualTo(List.of("keyword1", "keyword2"));
assertThat(asset.getDataAddress().getProperties()).isEqualTo(dataAddressProperties);
}

Expand Down Expand Up @@ -162,6 +159,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 @@ -20,6 +20,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;
import java.util.Map;

@Getter
Expand All @@ -28,12 +29,69 @@
@AllArgsConstructor
@Schema(description = "Type-Safe OpenAPI generator friendly Asset Create DTO that supports an opinionated subset of the original EDC Asset Entity.")
public class UiAssetCreateRequest {
@Schema(description = "Asset Id", requiredMode = Schema.RequiredMode.REQUIRED)
private String id;

@Schema(description = "Asset Name", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String name;

@Schema(description = "Asset Title", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String title;

@Schema(description = "Asset Language", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String language;

@Schema(description = "Asset Description", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String description;

@Schema(description = "Asset Organization Name", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String creator;

@Schema(description = "Asset Homepage", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String publisher;

@Schema(description = "License URL", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String licenseUrl;

@Schema(description = "Version", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String version;

@Schema(description = "Asset Keywords", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private List<String> keywords;

@Schema(description = "Asset MediaType", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String distribution;

@Schema(description = "Landing Page URL", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String landingPageUrl;

@Schema(description = "Data Category", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String dataCategory;

@Schema(description = "Data Subcategory", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String dataSubcategory;

@Schema(description = "Data Model", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String dataModel;

@Schema(description = "Geo-Reference Method", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String geoReferenceMethod;

@Schema(description = "Transport Mode", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String transportMode;

@Schema(description = "Data Address", requiredMode = Schema.RequiredMode.REQUIRED)
private Map<String, String> dataAddressProperties;

@Schema(description = "Properties of the Data Address", requiredMode = Schema.RequiredMode.REQUIRED)
private Map<String, String> properties;
@Schema(description = "Asset additional Properties", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Map<String, String> additionalProperties;

@Schema(description = "Asset Private Properties", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Map<String, Object> privateProperties;

@Schema(description = "Asset Json Properties", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Map<String, String> additionalJsonProperties;

@Schema(description = "Private Asset Properties", requiredMode = Schema.RequiredMode.REQUIRED)
private Map<String, String> privateProperties;
@Schema(description = "Contains the entire asset in its original expanded JSON-LD format", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private String assetJsonLd;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.AssetHelperDto;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.EdcPropertyMapperUtils;
import de.sovity.edc.ext.wrapper.api.common.model.UiAsset;
import de.sovity.edc.ext.wrapper.api.common.model.UiAssetCreateRequest;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.eclipse.edc.spi.types.domain.asset.Asset;
Expand All @@ -17,6 +19,7 @@ public class AssetMapper {
* This Object Mapper must be able to handle JSON-LD serialization / deserialization.
*/
private final ObjectMapper jsonLdObjectMapper;
private final EdcPropertyMapperUtils edcPropertyMapperUtils;

@SneakyThrows
public UiAsset buildUiAssetFromAssetJsonLd(String assetJsonLd) {
Expand Down Expand Up @@ -55,6 +58,7 @@ public AssetHelperDto buildHelperDto(String assetJsonLd) {
return mapper.readValue(assetJsonLd, AssetHelperDto.class);
}


@SneakyThrows
private UiAsset buildUiAsset(Asset asset) {
var assetJsonLd = jsonLdObjectMapper.writeValueAsString(asset);
Expand All @@ -63,46 +67,42 @@ private UiAsset buildUiAsset(Asset asset) {
}

@SneakyThrows
private Asset buildAssetFromAssetJsonLd(String assetPropertiesJsonLd) {

UiAsset uiAsset = buildUiAssetFromAssetJsonLd(assetPropertiesJsonLd);
public Asset buildAssetFromUiAssetCreateRequest(UiAssetCreateRequest uiAssetCreateRequest) {

Asset.Builder assetBuilder = Asset.Builder
.newInstance()
.id(uiAsset.getId())
.name(uiAsset.getName())
.description(uiAsset.getDescription())
.version(uiAsset.getVersion());
.id(uiAssetCreateRequest.getId())
.name(uiAssetCreateRequest.getName())
.description(uiAssetCreateRequest.getDescription())
.version(uiAssetCreateRequest.getVersion())
.dataAddress(edcPropertyMapperUtils.buildDataAddress(uiAssetCreateRequest.getDataAddressProperties()));


Map<String, Object> additionalProps = new HashMap<>();
additionalProps.put("title", uiAsset.getTitle());
additionalProps.put("language", uiAsset.getLanguage());
additionalProps.put("creator", uiAsset.getCreator());
additionalProps.put("publisher", uiAsset.getPublisher());
additionalProps.put("licenseUrl", uiAsset.getLicenseUrl());
additionalProps.put("keywords", uiAsset.getKeywords());
additionalProps.put("distribution", uiAsset.getDistribution());
additionalProps.put("landingPageUrl", uiAsset.getLandingPageUrl());
additionalProps.put("httpDatasourceHintsProxyMethod", uiAsset.getHttpDatasourceHintsProxyMethod());
additionalProps.put("httpDatasourceHintsProxyPath", uiAsset.getHttpDatasourceHintsProxyPath());
additionalProps.put("httpDatasourceHintsProxyQueryParams", uiAsset.getHttpDatasourceHintsProxyQueryParams());
additionalProps.put("httpDatasourceHintsProxyBody", uiAsset.getHttpDatasourceHintsProxyBody());
additionalProps.put("dataCategory", uiAsset.getDataCategory());
additionalProps.put("dataSubcategory", uiAsset.getDataSubcategory());
additionalProps.put("dataModel", uiAsset.getDataModel());
additionalProps.put("geoReferenceMethod", uiAsset.getGeoReferenceMethod());
additionalProps.put("transportMode", uiAsset.getTransportMode());

if(uiAsset.getAdditionalProperties() != null) {
additionalProps.putAll(uiAsset.getAdditionalProperties());
additionalProps.put("title", uiAssetCreateRequest.getTitle());
additionalProps.put("language", uiAssetCreateRequest.getLanguage());
additionalProps.put("creator", uiAssetCreateRequest.getCreator());
additionalProps.put("publisher", uiAssetCreateRequest.getPublisher());
additionalProps.put("licenseUrl", uiAssetCreateRequest.getLicenseUrl());
additionalProps.put("keywords", uiAssetCreateRequest.getKeywords());
additionalProps.put("distribution", uiAssetCreateRequest.getDistribution());
additionalProps.put("landingPageUrl", uiAssetCreateRequest.getLandingPageUrl());
additionalProps.put("dataCategory", uiAssetCreateRequest.getDataCategory());
additionalProps.put("dataSubcategory", uiAssetCreateRequest.getDataSubcategory());
additionalProps.put("dataModel", uiAssetCreateRequest.getDataModel());
additionalProps.put("geoReferenceMethod", uiAssetCreateRequest.getGeoReferenceMethod());
additionalProps.put("transportMode", uiAssetCreateRequest.getTransportMode());

if(uiAssetCreateRequest.getAdditionalProperties() != null) {
additionalProps.putAll(uiAssetCreateRequest.getAdditionalProperties());
}

if(uiAsset.getPrivateProperties() != null) {
assetBuilder.privateProperties(new HashMap<>(uiAsset.getPrivateProperties()));
if(uiAssetCreateRequest.getPrivateProperties() != null) {
assetBuilder.privateProperties(new HashMap<>(uiAssetCreateRequest.getPrivateProperties()));
}

if(uiAsset.getAdditionalJsonProperties() != null) {
additionalProps.putAll(uiAsset.getAdditionalJsonProperties());
if(uiAssetCreateRequest.getAdditionalJsonProperties() != null) {
additionalProps.putAll(uiAssetCreateRequest.getAdditionalJsonProperties());
}

assetBuilder.properties(additionalProps);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2023 sovity GmbH
*
* 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:
* sovity GmbH - init
*/

package de.sovity.edc.ext.wrapper.api.common.mappers.utils;

import lombok.RequiredArgsConstructor;
import org.eclipse.edc.spi.types.domain.DataAddress;

import java.util.HashMap;
import java.util.Map;

@RequiredArgsConstructor
public class EdcPropertyMapperUtils {

/**
* Converts a {@code Map<String, Object>} to {@code Map<String, String>}.
* <p>
* Our API forsakes asset properties that are complex objects / JSON and only keeps string
* properties.
*
* @param map all properties
* @return string properties
*/
public Map<String, String> truncateToMapOfString(Map<String, Object> map) {
Map<String, String> result = new HashMap<>();

for (Map.Entry<String, Object> entry : map.entrySet()) {
Object value = entry.getValue();

String valueString;
if (value == null) {
valueString = null;
} else if (value instanceof String str) {
valueString = str;
} else if (value instanceof Double) {
valueString = String.valueOf(value);
} else if (value instanceof Integer) {
valueString = String.valueOf(value);
} else {
continue;
}

result.put(entry.getKey(), valueString);
}
return result;
}

@SuppressWarnings({"unchecked", "rawtypes", "java:S1905"})
public Map<String, Object> toMapOfObject(Map<String, String> map) {
return new HashMap<>((Map<String, Object>) (Map) map);
}

public DataAddress buildDataAddress(Map<String, String> properties) {
return DataAddress.Builder.newInstance()
.properties(toMapOfObject(properties))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@
package de.sovity.edc.ext.wrapper;

import com.fasterxml.jackson.databind.ObjectMapper;
import de.sovity.edc.ext.wrapper.api.common.mappers.AssetMapper;
import de.sovity.edc.ext.wrapper.api.common.mappers.OperatorMapper;
import de.sovity.edc.ext.wrapper.api.common.mappers.PolicyMapper;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.AtomicConstraintMapper;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.ConstraintExtractor;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.EdcPropertyMapperUtils;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.LiteralMapper;
import de.sovity.edc.ext.wrapper.api.common.mappers.utils.PolicyValidator;
import de.sovity.edc.ext.wrapper.api.ee.EnterpriseEditionResourceImpl;
import de.sovity.edc.ext.wrapper.api.ui.UiResource;
import de.sovity.edc.ext.wrapper.api.ui.pages.asset.AssetApiService;
import de.sovity.edc.ext.wrapper.api.ui.pages.asset.services.AssetBuilder;
import de.sovity.edc.ext.wrapper.api.ui.pages.contracts.ContractAgreementPageApiService;
import de.sovity.edc.ext.wrapper.api.ui.pages.contracts.ContractAgreementTransferApiService;
import de.sovity.edc.ext.wrapper.api.ui.pages.contracts.ContractDefinitionApiService;
Expand Down Expand Up @@ -134,8 +135,9 @@ public static WrapperExtensionContext buildContext(
var contractNegotiationUtils = new ContractNegotiationUtils(contractNegotiationService);
var contractAgreementUtils = new ContractAgreementUtils(contractAgreementService);
var edcPropertyUtils = new EdcPropertyUtils();
var assetBuilder = new AssetBuilder(edcPropertyUtils);
var assetApiService = new AssetApiService(assetBuilder, assetService, edcPropertyUtils);
var edcPropertyMapperUtils = new EdcPropertyMapperUtils();
var assetMapper = new AssetMapper(objectMapper, edcPropertyMapperUtils);
var assetApiService = new AssetApiService(assetService, assetMapper);
var transferRequestBuilder = new TransferRequestBuilder(
objectMapper,
contractAgreementUtils,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import de.sovity.edc.ext.wrapper.api.common.model.PolicyDefinitionCreateRequest;
import de.sovity.edc.ext.wrapper.api.common.model.UiAssetCreateRequest;
import de.sovity.edc.ext.wrapper.api.ui.model.AssetPage;
import de.sovity.edc.ext.wrapper.api.ui.model.AssetCreateRequest;
import de.sovity.edc.ext.wrapper.api.ui.model.ContractAgreementPage;
import de.sovity.edc.ext.wrapper.api.ui.model.ContractAgreementTransferRequest;
import de.sovity.edc.ext.wrapper.api.ui.model.ContractDefinitionRequest;
Expand Down Expand Up @@ -107,8 +106,8 @@ public AssetPage assetPage() {
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Operation(description = "Create a new Asset")
public IdResponseDto createAsset(AssetCreateRequest assetCreateRequest) {
return assetApiService.createAsset(assetCreateRequest);
public IdResponseDto createAsset(UiAssetCreateRequest uiAssetCreateRequest) {
return assetApiService.createAsset(uiAssetCreateRequest);
}

@DELETE
Expand Down
Loading

0 comments on commit 1292bb7

Please sign in to comment.