Skip to content

Commit

Permalink
Merge pull request #829 from catenax-ng/feature/359-registry-update-i…
Browse files Browse the repository at this point in the history
…mpl-for-lookup

feat(impl):[#359] update registry impl for lookup
  • Loading branch information
dsmf authored Mar 27, 2024
2 parents 1d9952d + 7a990b2 commit 338fce3
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 18 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
_**For better traceability add the corresponding GitHub issue number in each changelog entry, please.**_

## [Unreleased]
### Changed
- IRS now supports Asset Administration Shell v3.1 - adjusted lookup shells endpoint changes (assetIds query param is encoded). #359
-
### Added
- Extended EdcPolicyDefinitionService to check if a policy in the edc exists

## [4.8.0] - 2024-03-18
### Changed
- Improved maintainability in EdcSubmodelClientImpl by reduced method visibility and better naming (in context of #448).
- EdcPolicyDefinitionService, EdcContractDefinitionService and EdcAssetService return throw AlreadyExist exceptions when Conflict is returned from
EDC
- EdcPolicyDefinitionService, EdcContractDefinitionService and EdcAssetService throw AlreadyExist exceptions when
conflict is returned from EDC
- Added AssetAdministrationShellDescriptor specificAssetIds support for externalSubjectId required for data provisioning
- Registering a job - aspects array is now accepting full urn of aspect model instead of name only, eg. 'urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt' instead 'SingleLevelBomAsBuilt'. #439
- Changed the version of irs-registry-client from 1.6.0-SNAPSHOT to 1.6.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
package org.eclipse.tractusx.irs;

import static com.github.tomakehurst.wiremock.client.WireMock.containing;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.tractusx.irs.WiremockSupport.createEndpointDataReference;
import static org.eclipse.tractusx.irs.WiremockSupport.encodedAssetIds;
import static org.eclipse.tractusx.irs.WiremockSupport.randomUUID;
import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockSupport.DISCOVERY_FINDER_PATH;
import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockSupport.DISCOVERY_FINDER_URL;
Expand Down Expand Up @@ -158,7 +160,7 @@ void shouldStartApplicationAndCollectSemanticModels() throws SchemaNotFoundExcep
void shouldStopJobAfterDepthIsReached() {
// Arrange
final String globalAssetIdLevel1 = "globalAssetId";
final String globalAssetIdLevel2 = "urn:uuid:6d505432-8b31-4966-9514-4b753372683f";
final String globalAssetIdLevel2 = "urn:uuid:7e4541ea-bb0f-464c-8cb3-021abccbfaf5";

WiremockSupport.successfulSemanticModelRequest();
WiremockSupport.successfulSemanticHubRequests();
Expand Down Expand Up @@ -297,7 +299,7 @@ private void successfulRegistryAndDataRequest(final String globalAssetId, final
final String registryEdcAssetId = "registry-asset";
successfulNegotiation(registryEdcAssetId);
stubFor(getLookupShells200(PUBLIC_LOOKUP_SHELLS_PATH, List.of(shellId)).withQueryParam("assetIds",
containing(globalAssetId)));
equalTo(encodedAssetIds(globalAssetId))));
stubFor(getShellDescriptor200(PUBLIC_SHELL_DESCRIPTORS_PATH + WiremockSupport.encodedId(shellId), bpn,
submodelDescriptors, globalAssetId, shellId, idShort));
successfulNegotiation(edcAssetId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@
import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference;
import org.eclipse.tractusx.irs.component.PartChainIdentificationKey;
import org.eclipse.tractusx.irs.component.RegisterJob;
import org.eclipse.tractusx.irs.component.assetadministrationshell.IdentifierKeyValuePair;
import org.eclipse.tractusx.irs.component.enums.Direction;
import org.eclipse.tractusx.irs.data.StringMapper;
import org.eclipse.tractusx.irs.edc.client.configuration.JsonLdConfiguration;
import org.eclipse.tractusx.irs.edc.client.model.EDRAuthCode;
import org.eclipse.tractusx.irs.registryclient.util.SerializationHelper;
import org.eclipse.tractusx.irs.semanticshub.SemanticHubWireMockSupport;
import org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockSupport;
import org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockSupport;
Expand Down Expand Up @@ -97,6 +99,14 @@ static String encodedId(final String shellId) {
return encodeBase64String(shellId.getBytes(StandardCharsets.UTF_8));
}

static String encodedAssetIds(final String assetIds) {
final IdentifierKeyValuePair globalAssetId = IdentifierKeyValuePair.builder()
.name("globalAssetId")
.value(assetIds)
.build();
return Base64.getEncoder().encodeToString(new SerializationHelper().serialize(globalAssetId));
}

static void verifyDiscoveryCalls(final int times) {
verify(times, postRequestedFor(urlPathEqualTo(DiscoveryServiceWiremockSupport.DISCOVERY_FINDER_PATH)));
verify(times, postRequestedFor(urlPathEqualTo(DiscoveryServiceWiremockSupport.EDC_DISCOVERY_PATH)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference;
import org.eclipse.tractusx.irs.component.assetadministrationshell.AssetAdministrationShellDescriptor;
import org.eclipse.tractusx.irs.component.assetadministrationshell.IdentifierKeyValuePair;
import org.eclipse.tractusx.irs.data.StringMapper;
import org.eclipse.tractusx.irs.registryclient.util.SerializationHelper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
Expand All @@ -53,6 +53,8 @@ public class DecentralDigitalTwinRegistryClient {
private final String shellDescriptorTemplate;
private final String lookupShellsTemplate;

private final SerializationHelper serializationHelper = new SerializationHelper();

public DecentralDigitalTwinRegistryClient(final RestTemplate edcRestTemplate,
@Value("${digitalTwinRegistry.shellDescriptorTemplate:}") final String shellDescriptorTemplate,
@Value("${digitalTwinRegistry.lookupShellsTemplate:}") final String lookupShellsTemplate) {
Expand All @@ -61,10 +63,6 @@ public DecentralDigitalTwinRegistryClient(final RestTemplate edcRestTemplate,
this.lookupShellsTemplate = lookupShellsTemplate;
}

private static String encodeWithBase64(final String aasIdentifier) {
return Base64.getEncoder().encodeToString(aasIdentifier.getBytes(StandardCharsets.UTF_8));
}

@Retry(name = "registry")
public AssetAdministrationShellDescriptor getAssetAdministrationShellDescriptor(
final EndpointDataReference endpointDataReference, final String aasIdentifier) {
Expand All @@ -78,14 +76,22 @@ public AssetAdministrationShellDescriptor getAssetAdministrationShellDescriptor(

@Retry(name = "registry")
public LookupShellsResponse getAllAssetAdministrationShellIdsByAssetLink(
final EndpointDataReference endpointDataReference, final List<IdentifierKeyValuePair> assetIds) {
final EndpointDataReference endpointDataReference, final IdentifierKeyValuePair assetIds) {
final String shellLookupEndpoint = endpointDataReference.getEndpoint() + lookupShellsTemplate;
final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(shellLookupEndpoint);
uriBuilder.uriVariables(Map.of(PLACEHOLDER_ASSET_IDS, StringMapper.mapToString(assetIds)));
uriBuilder.uriVariables(Map.of(PLACEHOLDER_ASSET_IDS, encodeWithBase64(assetIds)));
return edcRestTemplate.exchange(uriBuilder.build().toUri(), HttpMethod.GET,
new HttpEntity<>(null, headers(endpointDataReference)), LookupShellsResponse.class).getBody();
}

private String encodeWithBase64(final String aasIdentifier) {
return Base64.getEncoder().encodeToString(aasIdentifier.getBytes(StandardCharsets.UTF_8));
}

private String encodeWithBase64(final IdentifierKeyValuePair assetIds) {
return Base64.getEncoder().encodeToString(serializationHelper.serialize(assetIds));
}

private HttpHeaders headers(final EndpointDataReference dataReference) {
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(List.of(MediaType.APPLICATION_JSON));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ private String mapToShellId(final EndpointDataReference endpointDataReference, f

// Try to map the provided ID to the corresponding asset administration shell ID
final var mappingResultStream = decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(
endpointDataReference, List.of(identifierKeyValuePair)).getResult().stream();
endpointDataReference, identifierKeyValuePair).getResult().stream();

// Special scenario: Multiple DTs with the same globalAssetId in one DTR, see:
// docs/arc42/cross-cutting/discovery-DTR--multiple-DTs-with-the-same-globalAssedId-in-one-DTR.puml
Expand Down Expand Up @@ -340,7 +340,7 @@ private Collection<String> lookupShellIds(final String bpn, final EndpointDataRe
try {
return decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(
endpointDataReference,
List.of(IdentifierKeyValuePair.builder().name("manufacturerId").value(bpn).build())).getResult();
IdentifierKeyValuePair.builder().name("manufacturerId").value(bpn).build()).getResult();
} finally {
watch.stop();
log.info(TOOK_MS, watch.getLastTaskName(), watch.getLastTaskTimeMillis());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/********************************************************************************
* Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
* Copyright (c) 2021,2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
package org.eclipse.tractusx.irs.registryclient.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
* Serializer helper
*/
public class SerializationHelper {

private static final ObjectWriter WRITER;
static {
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
WRITER = mapper.writer();
}

public byte[] serialize(final Object object) {
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
WRITER.writeValue(stream, object);
return stream.toByteArray();
} catch (final IOException e) {
return new byte[0];
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference;
import org.eclipse.tractusx.irs.component.assetadministrationshell.AssetAdministrationShellDescriptor;
import org.eclipse.tractusx.irs.component.assetadministrationshell.IdentifierKeyValuePair;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpMethod;
Expand Down Expand Up @@ -59,7 +60,7 @@ void shouldCallForAllAssetAdministrationShellIdsByAssetLink() {
ResponseEntity.of(Optional.of(LookupShellsResponse.builder().result(Collections.emptyList()).build())));

// when
client.getAllAssetAdministrationShellIdsByAssetLink(endpointDataReference, new ArrayList<>());
client.getAllAssetAdministrationShellIdsByAssetLink(endpointDataReference, IdentifierKeyValuePair.builder().build());

// then
verify(restTemplate).exchange(any(), eq(HttpMethod.GET), any(), eq(LookupShellsResponse.class));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void shouldReturnExpectedShell() throws RegistryServiceException {
endpointDataRefFutures);

when(decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(any(),
anyList())).thenReturn(lookupShellsResponse);
any(IdentifierKeyValuePair.class))).thenReturn(lookupShellsResponse);
when(decentralDigitalTwinRegistryClient.getAssetAdministrationShellDescriptor(any(), any())).thenReturn(
expectedShell);

Expand Down Expand Up @@ -132,7 +132,7 @@ void whenInterruptedExceptionOccurs() throws ExecutionException, InterruptedExce
connectorEndpoints, "bpn")).thenReturn(dataRefFutures);

when(decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(any(),
anyList())).thenReturn(lookupShellsResponse);
any(IdentifierKeyValuePair.class))).thenReturn(lookupShellsResponse);
when(decentralDigitalTwinRegistryClient.getAssetAdministrationShellDescriptor(any(), any())).thenReturn(
shellDescriptor(emptyList()));

Expand Down Expand Up @@ -166,7 +166,7 @@ void whenExecutionExceptionOccurs() {
connectorEndpoints, "bpn")).thenReturn(dataRefFutures);

when(decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(any(),
anyList())).thenReturn(lookupShellsResponse);
any(IdentifierKeyValuePair.class))).thenReturn(lookupShellsResponse);
when(decentralDigitalTwinRegistryClient.getAssetAdministrationShellDescriptor(any(), any())).thenReturn(
shellDescriptor(emptyList()));

Expand Down Expand Up @@ -230,7 +230,7 @@ void shouldReturnTheExpectedGlobalAssetId() throws RegistryServiceException {
when(endpointDataForConnectorsService.createFindEndpointDataForConnectorsFutures(anyList(), any())).thenReturn(
dataRefFutures);
when(decentralDigitalTwinRegistryClient.getAllAssetAdministrationShellIdsByAssetLink(any(),
anyList())).thenReturn(lookupShellsResponse);
any(IdentifierKeyValuePair.class))).thenReturn(lookupShellsResponse);
when(decentralDigitalTwinRegistryClient.getAssetAdministrationShellDescriptor(any(), any())).thenReturn(
expectedShell);

Expand Down

0 comments on commit 338fce3

Please sign in to comment.