Skip to content

Commit

Permalink
add business test for http proxy transfer
Browse files Browse the repository at this point in the history
Signed-off-by: Dominik Pinsel <dominik.pinsel@daimler.com>
  • Loading branch information
DominikPinsel committed Dec 2, 2022
1 parent d46894f commit 32c04be
Show file tree
Hide file tree
Showing 21 changed files with 343 additions and 144 deletions.
11 changes: 5 additions & 6 deletions .github/workflows/business-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ jobs:
sleep 5s
# Wait for supporting infrastructure to become ready (control-/data-plane, backend service)
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=backend --timeout=120s || ( kubectl logs -l app.kubernetes.io/name=backend --tail 500 && exit 1 )
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=idsdaps --timeout=120s || ( kubectl logs -l app.kubernetes.io/name=idsdaps --tail 500 && exit 1 )
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=vault --timeout=120s || ( kubectl logs -l app.kubernetes.io/name=vault --tail 500 && exit 1 )
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=sokrates-postgresql --timeout=120s || ( kubectl logs -l app.kubernetes.io/name=sokrates-postgresql --tail 500 && exit 1 )
Expand Down Expand Up @@ -165,7 +166,7 @@ jobs:
--set dataplane.aws.endpointOverride=http://minio:9000 \
--set dataplane.aws.secretAccessKey=platoqwerty123 \
--set dataplane.aws.accessKeyId=platoqwerty123 \
--set backendService.httpProxyTokenReceiverUrl=http://example.com \
--set backendService.httpProxyTokenReceiverUrl=http://backend:80 \
--wait-for-jobs --timeout=120s
# Install Sokrates
Expand Down Expand Up @@ -197,15 +198,13 @@ jobs:
--set dataplane.aws.endpointOverride=http://minio:9000 \
--set dataplane.aws.secretAccessKey=sokratesqwerty123 \
--set dataplane.aws.accessKeyId=sokratesqwerty123 \
--set backendService.httpProxyTokenReceiverUrl=http://example.com \
--set backendService.httpProxyTokenReceiverUrl=http://backend:80 \
--wait-for-jobs --timeout=120s
# GH pipelines constrained by cpu, so give helm some time to register all resources \w k8s
sleep 5s
# Wait for Control-/DataPlane and backend-service to become ready
#kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=sokratesbackendapplication --timeout=120s || ( kubectl logs -l app.kubernetes.io/instance=sokratesbackendapplication --tail 500 && exit 1 )
#kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=platobackendapplication --timeout=120s || ( kubectl logs -l app.kubernetes.io/instance=platobackendapplication --tail 500 && exit 1 )
kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=sokrates-controlplane --timeout=120s || ( kubectl logs -l app.kubernetes.io/instance=sokrates-controlplane --tail 500 && exit 1 )
kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=sokrates-dataplane --timeout=120s || ( kubectl logs -l app.kubernetes.io/instance=sokrates-dataplane --tail 500 && exit 1 )
kubectl wait --for=condition=ready pod -l app.kubernetes.io/instance=plato-controlplane --timeout=600s || ( kubectl logs -l app.kubernetes.io/instance=plato-controlplane --tail 500 && exit 1 )
Expand Down Expand Up @@ -241,14 +240,14 @@ jobs:
{"name": "SOKRATES_DATA_MANAGEMENT_URL", "value": "${SOKRATES_DATA_MANAGEMENT_URL}"},
{"name": "SOKRATES_IDS_URL", "value": "${SOKRATES_IDS_URL}"},
{"name": "SOKRATES_DATA_PLANE_URL", "value": "${SOKRATES_DATA_PLANE_URL}"},
{"name": "SOKRATES_BACKEND_SERVICE_BACKEND_API_URL", "value": "http://sokrates-backend-application:8081" },
{"name": "SOKRATES_BACKEND_SERVICE_BACKEND_API_URL", "value": "http://backend:8081" },
{"name": "SOKRATES_DATABASE_URL", "value": "${SOKRATES_DATABASE_URL}"},
{"name": "SOKRATES_DATABASE_USER", "value": "${SOKRATES_DATABASE_USER}"},
{"name": "SOKRATES_DATABASE_PASSWORD", "value": "${SOKRATES_DATABASE_PASSWORD}"},
{"name": "PLATO_DATA_MANAGEMENT_URL", "value": "${PLATO_DATA_MANAGEMENT_URL}"},
{"name": "PLATO_IDS_URL", "value": "${PLATO_IDS_URL}"},
{"name": "PLATO_DATA_PLANE_URL", "value": "${PLATO_DATA_PLANE_URL}"},
{"name": "PLATO_BACKEND_SERVICE_BACKEND_API_URL", "value": "http://plato-backend-application:8081"},
{"name": "PLATO_BACKEND_SERVICE_BACKEND_API_URL", "value": "http://backend:8081"},
{"name": "PLATO_DATABASE_URL", "value": "${PLATO_DATABASE_URL}"},
{"name": "PLATO_DATABASE_USER", "value": "${PLATO_DATABASE_USER}"},
{"name": "PLATO_DATABASE_PASSWORD", "value": "${PLATO_DATABASE_PASSWORD}"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class ProcessData {
// contract data
@Setter private String contractNegotiationId;
@Setter private String contractAgreementId;
@Setter private boolean isContractConfirmed = false;
@Builder.Default @Setter private boolean isContractConfirmed = false;

// result/response data
@Setter private EndpointDataReference endpointDataReference;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---

###########
# INSTALL #
# Install #
###########
install:
daps: true
Expand All @@ -16,6 +16,7 @@ install:
backend:
fullnameOverride: "backend"
service:
type: NodePort
frontend:
port: 80

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Map;
import java.util.UUID;
import org.eclipse.tractusx.edc.tests.data.Asset;
import org.eclipse.tractusx.edc.tests.data.NullDataAddress;

public class AssetStepDefs {

Expand All @@ -43,7 +44,9 @@ public void hasAssets(Connector connector, int assetCount) throws Exception {
final DataManagementAPI api = connector.getDataManagementAPI();

for (var i = 0; i < assetCount; i++)
api.createAsset(new Asset(UUID.randomUUID().toString(), i + 1 + " / " + assetCount));
api.createAsset(
new Asset(
UUID.randomUUID().toString(), i + 1 + " / " + assetCount, NullDataAddress.INSTANCE));
}

private List<Asset> parseDataTable(DataTable table) {
Expand All @@ -52,7 +55,7 @@ private List<Asset> parseDataTable(DataTable table) {
for (Map<String, String> map : table.asMaps()) {
String id = map.get("id");
String description = map.get("description");
assets.add(new Asset(id, description));
assets.add(new Asset(id, description, NullDataAddress.INSTANCE));
}

return assets;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
Expand All @@ -54,6 +55,7 @@
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

@Slf4j
public class BackendServiceBackendAPI {
private static final String HTTP_HEADER_ACCEPT = "Accept";
private static final String HTTP_HEADER_CONTENT_TYPE = "Content-Type";
Expand All @@ -76,6 +78,8 @@ public List<String> list(/* @Nullable */ final String path) {
final HttpGet get = new HttpGet(uri);
get.setHeader(HTTP_HEADER_ACCEPT, ContentType.APPLICATION_JSON.getMimeType());

log.debug(String.format("Send %-6s %s", get.getMethod(), get.getURI()));

return httpClient.execute(get, ListResponseHandler.INSTANCE);
}

Expand All @@ -85,6 +89,8 @@ public boolean exists(@NonNull final String path) {
final URI uri = new URIBuilder(backendServiceBackendApiUrl).setPath(path).build();
final HttpHead head = new HttpHead(uri);

log.debug(String.format("Send %-6s %s", head.getMethod(), head.getURI()));

return httpClient.execute(head, ExistsResponseHandler.INSTANCE);
}

Expand All @@ -95,6 +101,8 @@ public byte[] get(@NonNull final String path) {
final HttpGet get = new HttpGet(uri);
get.setHeader(HTTP_HEADER_ACCEPT, ContentType.APPLICATION_OCTET_STREAM.getMimeType());

log.debug(String.format("Send %-6s %s", get.getMethod(), get.getURI()));

return httpClient.execute(get, GetResponseHandler.INSTANCE);
}

Expand All @@ -114,6 +122,8 @@ public void post(

post.setEntity(entity);

log.debug(String.format("Send %-6s %s", post.getMethod(), post.getURI()));

httpClient.execute(post, PostResponseHandler.INSTANCE);
}

Expand Down Expand Up @@ -240,7 +250,7 @@ private static class ListResponseHandler extends GsonResponseHandler<List<String
public static final ListResponseHandler INSTANCE = new ListResponseHandler();

private ListResponseHandler() {
super(new TypeToken<List<String>>() {}); // JVM type erasure: Keep generic args!
super(new TypeToken<>() {}); // JVM type erasure: Keep generic args!
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,22 @@
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.eclipse.tractusx.edc.tests.data.Asset;
import org.eclipse.tractusx.edc.tests.data.AssetWithDataAddress;
import org.eclipse.tractusx.edc.tests.data.BusinessPartnerNumberConstraint;
import org.eclipse.tractusx.edc.tests.data.Constraint;
import org.eclipse.tractusx.edc.tests.data.ContractDefinition;
import org.eclipse.tractusx.edc.tests.data.ContractNegotiation;
import org.eclipse.tractusx.edc.tests.data.ContractNegotiationState;
import org.eclipse.tractusx.edc.tests.data.ContractOffer;
import org.eclipse.tractusx.edc.tests.data.DataAddress;
import org.eclipse.tractusx.edc.tests.data.HttpProxySinkDataAddress;
import org.eclipse.tractusx.edc.tests.data.HttpProxySourceDataAddress;
import org.eclipse.tractusx.edc.tests.data.Negotiation;
import org.eclipse.tractusx.edc.tests.data.NullDataAddress;
import org.eclipse.tractusx.edc.tests.data.PayMeConstraint;
import org.eclipse.tractusx.edc.tests.data.Permission;
import org.eclipse.tractusx.edc.tests.data.Policy;
import org.eclipse.tractusx.edc.tests.data.S3DataAddress;
import org.eclipse.tractusx.edc.tests.data.Transfer;
import org.eclipse.tractusx.edc.tests.data.TransferProcess;
import org.eclipse.tractusx.edc.tests.data.TransferProcessState;

Expand Down Expand Up @@ -88,7 +93,7 @@ public List<ContractOffer> requestCatalogFrom(String receivingConnectorUrl) thro
return catalog.contractOffers.stream().map(this::mapOffer).collect(Collectors.toList());
}

public String initiateNegotiation(
public Negotiation initiateNegotiation(
String receivingConnectorUrl, String definitionId, String assetId, Policy policy)
throws IOException {
final DataManagementApiOffer offer = new DataManagementApiOffer();
Expand All @@ -112,12 +117,13 @@ public String initiateNegotiation(
throw new RuntimeException(
"Initiated negotiation. Connector did not answer with negotiation ID.");

log.debug("Initiated negotiation ( id= " + response.getId() + " )");
log.info(String.format("Initiated negotiation (id=%s)", response.getId()));

return response.getId();
final String negotiationId = response.getId();
return new Negotiation(negotiationId);
}

public String initiateTransferProcess(
public Transfer initiateTransferProcess(
String receivingConnectorUrl,
String contractAgreementId,
String assetId,
Expand All @@ -140,9 +146,10 @@ public String initiateTransferProcess(
throw new RuntimeException(
"Initiated transfer process. Connector did not answer with transfer process ID.");

log.info("Initiated transfer process ( id= " + response.getId() + " )");
log.info(String.format("Initiated transfer process (id=%s)", response.getId()));

return response.getId();
final String transferId = response.getId();
return new Transfer(transferId);
}

public TransferProcess getTransferProcess(String id) throws IOException {
Expand All @@ -157,26 +164,16 @@ public ContractNegotiation getNegotiation(String id) throws IOException {
return mapNegotiation(negotiation);
}

public void createAsset(Asset asset) throws IOException {
final DataManagementApiDataAddress dataAddress = new DataManagementApiDataAddress();
dataAddress.properties =
Map.of(
DataManagementApiDataAddress.TYPE,
"HttpData",
"baseUrl",
"https://jsonplaceholder.typicode.com/todos/1");

final DataManagementApiAssetCreate assetCreate = new DataManagementApiAssetCreate();
assetCreate.asset = mapAsset(asset);
assetCreate.dataAddress = dataAddress;

post(ASSET_PATH, assetCreate);
public List<ContractNegotiation> getNegotiations() throws IOException {
final List<DataManagementApiNegotiation> negotiations =
get(NEGOTIATIONS_PATH + "/", new TypeToken<List<DataManagementApiNegotiation>>() {});
return negotiations.stream().map(this::mapNegotiation).collect(Collectors.toList());
}

public void createAsset(AssetWithDataAddress assetWithDataAddress) throws IOException {
public void createAsset(Asset asset) throws IOException {
final DataManagementApiAssetCreate assetCreate = new DataManagementApiAssetCreate();
assetCreate.asset = mapAsset(assetWithDataAddress.getAsset());
assetCreate.dataAddress = mapDataAddress(assetWithDataAddress.getDataAddress());
assetCreate.asset = mapAsset(asset);
assetCreate.dataAddress = mapDataAddress(asset.getDataAddress());

post(ASSET_PATH, assetCreate);
}
Expand Down Expand Up @@ -279,6 +276,9 @@ private TransferProcess mapTransferProcess(DataManagementApiTransferProcess tran
case "COMPLETED":
state = TransferProcessState.COMPLETED;
break;
case "ERROR":
state = TransferProcessState.ERROR;
break;
default:
state = TransferProcessState.UNKNOWN;
}
Expand All @@ -288,7 +288,33 @@ private TransferProcess mapTransferProcess(DataManagementApiTransferProcess tran

private DataManagementApiDataAddress mapDataAddress(@NonNull DataAddress dataAddress) {
final DataManagementApiDataAddress apiObject = new DataManagementApiDataAddress();
apiObject.setProperties(dataAddress.getProperties());

if (dataAddress instanceof HttpProxySourceDataAddress) {
final HttpProxySourceDataAddress a = (HttpProxySourceDataAddress) dataAddress;
apiObject.setProperties(Map.of("type", "HttpData", "baseUrl", a.getBaseUrl()));
} else if (dataAddress instanceof HttpProxySinkDataAddress) {
apiObject.setProperties(Map.of("type", "HttpProxy"));
} else if (dataAddress instanceof S3DataAddress) {
final S3DataAddress a = (S3DataAddress) dataAddress;
apiObject.setProperties(
Map.of(
"type",
"AmazonS3",
"bucketName",
a.getBucketName(),
"region",
a.getRegion(),
"keyName",
a.getKeyName()));
} else if (dataAddress instanceof NullDataAddress) {
// set something that passes validation
apiObject.setProperties(Map.of("type", "HttpData", "baseUrl", "http://localhost"));
} else {
throw new UnsupportedOperationException(
String.format(
"Cannot map data address of type %s to EDC domain", dataAddress.getClass()));
}

return apiObject;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.eclipse.tractusx.edc.tests;

import io.cucumber.datatable.DataTable;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import java.io.IOException;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.edc.tests.data.Asset;
import org.eclipse.tractusx.edc.tests.data.ContractNegotiation;
import org.eclipse.tractusx.edc.tests.data.DataAddress;
import org.eclipse.tractusx.edc.tests.data.HttpProxySinkDataAddress;
import org.eclipse.tractusx.edc.tests.data.HttpProxySourceDataAddress;
import org.eclipse.tractusx.edc.tests.data.Transfer;
import org.junit.jupiter.api.Assertions;

@Slf4j
public class HttpProxyTransferSteps {

private static final String ID = "id";
private static final String DESCRIPTION = "description";
private static final String BASE_URL = "baseUrl";
private static final String DEFINITION_ID = "definition id";
private static final String ASSET_ID = "asset id";

@Given("'{connector}' has a http proxy assets")
public void hasAssets(Connector connector, DataTable table) throws Exception {
final DataManagementAPI api = connector.getDataManagementAPI();

for (var map : table.asMaps()) {
final String id = map.get(ID);
final String description = map.get(DESCRIPTION);
final String baseUrl = map.get(BASE_URL);

final DataAddress address = new HttpProxySourceDataAddress(baseUrl);
final Asset asset = new Asset(id, description, address);

api.createAsset(asset);
}
}

@When("'{connector}' initiates HttpProxy transfer from '{connector}'")
public void sokratesInitiateHttpProxyTransferProcessFromPlato(
Connector consumer, Connector provider, DataTable dataTable) throws IOException {
final DataManagementAPI api = consumer.getDataManagementAPI();
final String receiverUrl = provider.getEnvironment().getIdsUrl() + "/data";

final List<ContractNegotiation> negotiation = api.getNegotiations();
final String agreementId = negotiation.get(0).getAgreementId();
final DataAddress dataAddress = new HttpProxySinkDataAddress();

for (var map : dataTable.asMaps()) {
final String assetId = map.get(ASSET_ID);
final Transfer transfer =
api.initiateTransferProcess(receiverUrl, agreementId, assetId, dataAddress);

transfer.waitUntilComplete(api);
}
}

@Then("the backend application of '{connector}' has received data")
public void theBackendApplicationOfSocratesHasReceivedData(Connector consumer) {
final BackendServiceBackendAPI api = consumer.getBackendServiceBackendAPI();
final List<String> transferredData = api.list("/");
Assertions.assertNotEquals(0, transferredData.size());
}
}
Loading

0 comments on commit 32c04be

Please sign in to comment.