Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/tri 1540 fix registry dataplane usage #477

Merged
merged 3 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Changed
- IRS now calls the entire dataplane URL retrieved from the registry href instead of building it from the URL of the EDC token and the path

### Fixed
- Switched to POST for DTR lookup request
- Added Base64 encoding to identifier for DTR shell-descriptor request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
********************************************************************************/
package org.eclipse.tractusx.irs.aaswrapper.job;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -40,14 +38,16 @@ public class ExtractDataFromProtocolInformation {

public static String extractAssetId(final String subprotocolBody) {
final Map<String, String> parametersFromPath = Stream.of(subprotocolBody.split(ASSET_ID_SEPARATOR))
.map(str -> str.split("="))
.collect(Collectors.toMap(e -> e[0], e -> e[1]));
.map(str -> str.split("="))
.collect(Collectors.toMap(e -> e[0], e -> e[1]));
return parametersFromPath.get("id");
}

public static String extractSuffix(final String href) throws URISyntaxException {
final URI uri = new URI(href);
return uri.getPath();
public static String extractDspEndpoint(final String subprotocolBody) {
final Map<String, String> parametersFromPath = Stream.of(subprotocolBody.split(ASSET_ID_SEPARATOR))
.map(str -> str.split("="))
.collect(Collectors.toMap(e -> e[0], e -> e[1]));
return parametersFromPath.get("dspEndpoint");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
package org.eclipse.tractusx.irs.aaswrapper.job.delegate;

import static org.eclipse.tractusx.irs.aaswrapper.job.ExtractDataFromProtocolInformation.extractAssetId;
import static org.eclipse.tractusx.irs.aaswrapper.job.ExtractDataFromProtocolInformation.extractSuffix;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -103,11 +101,9 @@ protected String requestSubmodelAsString(final EdcSubmodelFacade submodelFacade,
private void addSubmodelToList(final EdcSubmodelFacade submodelFacade, final Endpoint endpoint,
final List<String> submodelPayload, final String connectorEndpoint) throws EdcClientException {
try {
submodelPayload.add(submodelFacade.getSubmodelRawPayload(connectorEndpoint,
extractSuffix(endpoint.getProtocolInformation().getHref()),
extractAssetId(endpoint.getProtocolInformation().getSubprotocolBody())));
} catch (URISyntaxException e) {
throw new EdcClientException(e);
submodelPayload.add(
submodelFacade.getSubmodelRawPayload(connectorEndpoint, endpoint.getProtocolInformation().getHref(),
extractAssetId(endpoint.getProtocolInformation().getSubprotocolBody())));
} catch (ItemNotFoundInCatalogException e) {
log.info("Could not find asset in catalog. Requesting next endpoint.", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@

import static org.assertj.core.api.Assertions.assertThat;

import java.net.URISyntaxException;

import org.junit.jupiter.api.Test;

class ExtractDataFromProtocolInformationTest {

@Test
void shouldExtractIdFromSubprotocol() {
// given
final String exampleSubprotocol = "other_id=fake-id;id=12345;idsEndpoint=http://edc.control.plane/";
final String exampleSubprotocol = "other_id=fake-id;id=12345;dspEndpoint=http://edc.control.plane/";

// when
final String actual = ExtractDataFromProtocolInformation.extractAssetId(exampleSubprotocol);
Expand All @@ -21,15 +19,15 @@ void shouldExtractIdFromSubprotocol() {
}

@Test
void shouldExtractSufixPathFromHref() throws URISyntaxException {
void shouldExtractDspEndpointFromSubprotocol() {
// given
final String href = "https://edc.data.plane/shells/123/submodels/456/submodel";
final String exampleSubprotocol = "other_id=fake-id;id=12345;dspEndpoint=http://edc.control.plane/";

// when
final String actual = ExtractDataFromProtocolInformation.extractSuffix(href);
final String actual = ExtractDataFromProtocolInformation.extractDspEndpoint(exampleSubprotocol);

// then
assertThat(actual).isEqualTo("/shells/123/submodels/456/submodel");
assertThat(actual).isEqualTo("http://edc.control.plane/");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,9 @@ public EdcDataPlaneClient(@Qualifier("edcClientRestTemplate") final RestTemplate
this.edcRestTemplate = edcRestTemplate;
}

public String getData(final EndpointDataReference dataReference, final String subUrl) {
public String getData(final EndpointDataReference dataReference, final String submodelDataplaneUrl) {

final String url = getUrl(dataReference.getEndpoint(), subUrl);

final String response = edcRestTemplate.exchange(url, HttpMethod.GET,
final String response = edcRestTemplate.exchange(submodelDataplaneUrl, HttpMethod.GET,
new HttpEntity<>(null, headers(dataReference)), String.class).getBody();

log.info("Extracting raw embeddedData from EDC data plane response");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
@SuppressWarnings("PMD.ExcessiveImports")
public interface EdcSubmodelClient {

CompletableFuture<String> getSubmodelRawPayload(String connectorEndpoint, String submodelSufix, String assetId)
CompletableFuture<String> getSubmodelRawPayload(String connectorEndpoint, String submodelDataplaneUrl, String assetId)
throws EdcClientException;

CompletableFuture<EdcNotificationResponse> sendNotification(String submodelEndpointAddress, String assetId,
Expand All @@ -84,12 +84,12 @@ class EdcSubmodelClientLocalStub implements EdcSubmodelClient {
}

@Override
public CompletableFuture<String> getSubmodelRawPayload(final String connectorEndpoint, final String submodelSuffix,
public CompletableFuture<String> getSubmodelRawPayload(final String connectorEndpoint, final String submodelDataplaneUrl,
final String assetId) throws EdcClientException {
if ("urn:uuid:c35ee875-5443-4a2d-bc14-fdacd64b9446".equals(assetId)) {
throw new EdcClientException("Dummy Exception");
}
final Map<String, Object> submodel = testdataCreator.createSubmodelForId(assetId + "_" + submodelSuffix);
final Map<String, Object> submodel = testdataCreator.createSubmodelForId(assetId + "_" + submodelDataplaneUrl);
return CompletableFuture.completedFuture(StringMapper.mapToString(submodel));
}

Expand Down Expand Up @@ -191,14 +191,14 @@ private CompletableFuture<EdcNotificationResponse> sendNotificationAsync(final S

}

private Optional<String> retrieveSubmodelData(final String submodel, final String contractAgreementId,
private Optional<String> retrieveSubmodelData(final String submodelDataplaneUrl, final String contractAgreementId,
final StopWatch stopWatch) {
final Optional<EndpointDataReference> dataReference = retrieveEndpointDataReference(contractAgreementId);

if (dataReference.isPresent()) {
final EndpointDataReference ref = dataReference.get();
log.info("Retrieving data from EDC data plane for dataReference with id {}", ref.getId());
final String data = edcDataPlaneClient.getData(ref, submodel);
final String data = edcDataPlaneClient.getData(ref, submodelDataplaneUrl);
stopWatchOnEdcTask(stopWatch);

return Optional.of(data);
Expand Down Expand Up @@ -239,7 +239,7 @@ private int findIndexOf(final String endpointAddress, final String str) {
}

@Override
public CompletableFuture<String> getSubmodelRawPayload(final String connectorEndpoint, final String submodelSuffix,
public CompletableFuture<String> getSubmodelRawPayload(final String connectorEndpoint, final String submodelDataplaneUrl,
final String assetId) throws EdcClientException {
return execute(connectorEndpoint, () -> {
final StopWatch stopWatch = new StopWatch();
Expand All @@ -250,7 +250,7 @@ public CompletableFuture<String> getSubmodelRawPayload(final String connectorEnd
final NegotiationResponse negotiationResponse = fetchNegotiationResponseWithFilter(negotiationEndpoint,
assetId);
return pollingService.<String>createJob()
.action(() -> retrieveSubmodelData(submodelSuffix,
.action(() -> retrieveSubmodelData(submodelDataplaneUrl,
negotiationResponse.getContractAgreementId(), stopWatch))
.timeToLive(config.getSubmodel().getRequestTtl())
.description("waiting for submodel retrieval")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ public class EdcSubmodelFacade {
private final EdcSubmodelClient client;

@SuppressWarnings("PMD.PreserveStackTrace")
public String getSubmodelRawPayload(final String connectorEndpoint, final String submodelSufix,
public String getSubmodelRawPayload(final String connectorEndpoint, final String submodelDataplaneUrl,
final String assetId) throws EdcClientException {
try {
return client.getSubmodelRawPayload(connectorEndpoint, submodelSufix, assetId).get();
return client.getSubmodelRawPayload(connectorEndpoint, submodelDataplaneUrl, assetId).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@

class SubmodelFacadeWiremockTest {
private final static String connectorEndpoint = "https://connector.endpoint.com";
private final static String submodelSuffix = "/shells/12345/submodels/5678/submodel";
private final static String submodelDataplanePath = "/api/public/shells/12345/submodels/5678/submodel";
private final static String assetId = "12345";
private final EdcConfiguration config = new EdcConfiguration();
private final EndpointDataReferenceStorage storage = new EndpointDataReferenceStorage(Duration.ofMinutes(1));
Expand Down Expand Up @@ -134,14 +134,14 @@ void shouldReturnAssemblyPartRelationshipAsString()
throws EdcClientException, ExecutionException, InterruptedException {
// Arrange
prepareNegotiation();
givenThat(get(urlPathEqualTo(submodelSuffix)).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type",
givenThat(get(urlPathEqualTo(submodelDataplanePath)).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type",
"application/json;charset=UTF-8")
.withBodyFile(
.withBodyFile(
"singleLevelBomAsBuilt.json")));

// Act
final String submodel = edcSubmodelClient.getSubmodelRawPayload(connectorEndpoint, submodelSuffix, assetId)
final String submodel = edcSubmodelClient.getSubmodelRawPayload(connectorEndpoint, buildWiremockDataplaneUrl(), assetId)
.get();

// Assert
Expand Down Expand Up @@ -196,7 +196,7 @@ private void prepareNegotiation() {
.authCode("testcode")
.properties(Map.of(NAMESPACE_EDC_CID,
contractAgreementId))
.endpoint(buildApiMethodUrl())
.endpoint("http://provider.dataplane/api/public")
.build();
storage.put(contractAgreementId, ref);
}
Expand All @@ -206,14 +206,14 @@ void shouldReturnMaterialForRecyclingAsString()
throws EdcClientException, ExecutionException, InterruptedException {
// Arrange
prepareNegotiation();
givenThat(get(urlPathEqualTo(submodelSuffix)).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type",
givenThat(get(urlPathEqualTo(submodelDataplanePath)).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type",
"application/json;charset=UTF-8")
.withBodyFile(
.withBodyFile(
"materialForRecycling.json")));

// Act
final String submodel = edcSubmodelClient.getSubmodelRawPayload(connectorEndpoint, submodelSuffix, assetId)
final String submodel = edcSubmodelClient.getSubmodelRawPayload(connectorEndpoint, buildWiremockDataplaneUrl(), assetId)
.get();

// Assert
Expand All @@ -225,13 +225,13 @@ void shouldReturnObjectAsStringWhenResponseNotJSON()
throws EdcClientException, ExecutionException, InterruptedException {
// Arrange
prepareNegotiation();
givenThat(get(urlPathEqualTo(submodelSuffix)).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type",
givenThat(get(urlPathEqualTo(submodelDataplanePath)).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type",
"application/json;charset=UTF-8")
.withBody("test")));
.withBody("test")));

// Act
final String submodel = edcSubmodelClient.getSubmodelRawPayload(connectorEndpoint, submodelSuffix, assetId)
final String submodel = edcSubmodelClient.getSubmodelRawPayload(connectorEndpoint, buildWiremockDataplaneUrl(), assetId)
.get();

// Assert
Expand All @@ -242,14 +242,14 @@ void shouldReturnObjectAsStringWhenResponseNotJSON()
void shouldThrowExceptionWhenResponse_400() {
// Arrange
prepareNegotiation();
givenThat(get(urlPathEqualTo(submodelSuffix)).willReturn(aResponse().withStatus(400)
.withHeader("Content-Type",
givenThat(get(urlPathEqualTo(submodelDataplanePath)).willReturn(aResponse().withStatus(400)
.withHeader("Content-Type",
"application/json;charset=UTF-8")
.withBody("{ error: '400'}")));
.withBody("{ error: '400'}")));

// Act
final ThrowableAssert.ThrowingCallable throwingCallable = () -> edcSubmodelClient.getSubmodelRawPayload(
connectorEndpoint, submodelSuffix, assetId).get(5, TimeUnit.SECONDS);
connectorEndpoint, buildWiremockDataplaneUrl(), assetId).get(5, TimeUnit.SECONDS);

// Assert
assertThatExceptionOfType(ExecutionException.class).isThrownBy(throwingCallable)
Expand All @@ -260,20 +260,23 @@ void shouldThrowExceptionWhenResponse_400() {
void shouldThrowExceptionWhenResponse_500() {
// Arrange
prepareNegotiation();
givenThat(get(urlPathEqualTo(submodelSuffix)).willReturn(aResponse().withStatus(500)
.withHeader("Content-Type",
givenThat(get(urlPathEqualTo(submodelDataplanePath)).willReturn(aResponse().withStatus(500)
.withHeader("Content-Type",
"application/json;charset=UTF-8")
.withBody("{ error: '500'}")));
.withBody("{ error: '500'}")));

// Act
final ThrowableAssert.ThrowingCallable throwingCallable = () -> edcSubmodelClient.getSubmodelRawPayload(
connectorEndpoint, submodelSuffix, assetId).get(5, TimeUnit.SECONDS);
connectorEndpoint, buildWiremockDataplaneUrl(), assetId).get(5, TimeUnit.SECONDS);

// Assert
assertThatExceptionOfType(ExecutionException.class).isThrownBy(throwingCallable)
.withCauseInstanceOf(RestClientException.class);
}

private String buildWiremockDataplaneUrl() {
return buildApiMethodUrl() + submodelDataplanePath;
}
private String buildApiMethodUrl() {
return String.format("http://localhost:%d", this.wireMockServer.port());
}
Expand Down
Loading