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

feature: #586 bpdm lookup functionality #939

Merged
merged 38 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
1ffa057
feature: 586 add bpdm lookup functionality
ds-lcapellino Apr 12, 2024
ae973f2
feature: 586 add bpdm lookup functionality
ds-lcapellino Apr 12, 2024
7e78b87
chore: 586 add bpdm environment configuration
ds-lcapellino Apr 12, 2024
877da26
Merge branch 'main' into feature/586-bpdm-lookup
ds-lcapellino Apr 12, 2024
4616c63
feature: 586 update CHANGELOG.md
ds-lcapellino Apr 12, 2024
1291a01
helm: 586 add bpdm url to values.yaml
ds-lcapellino Apr 12, 2024
0fea627
Merge branch 'main' into feature/586-bpdm-lookup
ds-lcapellino Apr 12, 2024
e0b5699
feature: 586 refactor classes to have a clean architecture
ds-lcapellino Apr 12, 2024
f76978e
Merge remote-tracking branch 'origin/feature/586-bpdm-lookup' into fe…
ds-lcapellino Apr 12, 2024
f3e9903
feature: 586 fix deployment.yaml
ds-lcapellino Apr 12, 2024
d415ca9
feature: 586 fix deployment.yaml
ds-lcapellino Apr 12, 2024
84929c8
feature: 586 fix deployment.yaml
ds-lcapellino Apr 12, 2024
4db24c9
feature: 586 add oauth to bpdm request
ds-lcapellino Apr 12, 2024
4f5cb2d
feature: 586 fix integration tests
ds-lcapellino Apr 12, 2024
9a1fcda
feature: 586 fix BpdmProperties.java
ds-lcapellino Apr 12, 2024
56a4ba2
feature: #586 update Aspect.java
ds-lcapellino Apr 16, 2024
1a6c657
feature: #586 migate to new irs version to use localModels
ds-lcapellino Apr 17, 2024
83c995a
feature: #586 update irs client lib
ds-lcapellino Apr 17, 2024
5421616
feature: #586 update item-relationship-service chart
ds-lcapellino Apr 17, 2024
4de3589
Merge branch 'main' into feature/586-bpdm-lookup
ds-lcapellino Apr 17, 2024
1eaf015
feature: #586 add bpdm client id and secret
ds-lcapellino Apr 17, 2024
789b673
feature: #586 add bpdm client id and secret
ds-lcapellino Apr 17, 2024
96b9f7e
Revert "feature: #586 add bpdm client id and secret"
ds-lcapellino Apr 17, 2024
0d7becd
Revert "feature: #586 add bpdm client id and secret"
ds-lcapellino Apr 17, 2024
5edbec1
Merge branch 'main' into feature/586-bpdm-lookup
ds-lcapellino Apr 29, 2024
d6d9228
feature: #586 merge main and fix test
ds-lcapellino Apr 29, 2024
d9600a6
feature: 586 ignore http 401 from BPDM
ds-lcapellino May 2, 2024
e8bbd79
Revert "feature: #586 migate to new irs version to use localModels"
ds-lcapellino May 3, 2024
d51e6b3
Revert "feature: #586 update irs client lib"
ds-lcapellino May 3, 2024
ee227f7
Revert "feature: #586 update item-relationship-service chart"
ds-lcapellino May 3, 2024
2408d39
feature: #586 refactor
ds-lcapellino May 3, 2024
eac85a3
feature: #586 revert
ds-lcapellino May 3, 2024
dc6326c
feature: #586 revert
ds-lcapellino May 3, 2024
e398a20
feature: #586 revert
ds-lcapellino May 3, 2024
41c7d39
feature: #586 refactor
ds-lcapellino May 3, 2024
731569f
helm: #788 remove dev/edc/wallet#ssi.oauth.client.id usage
ds-lcapellino May 3, 2024
4e056de
feature: #586 fix tests
ds-lcapellino May 3, 2024
1279058
feature: #586 implement review feedback
ds-lcapellino May 6, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ _**For better traceability add the corresponding GitHub issue number in each cha
- #622 Notification Update API
- #774 Added initial concept for handling multiple BPNs
- #834 Added possiblity to exclude elements from the results of the asset api filter
- #586 BPDM lookup feature

## Changed
- XXX Updated insomnia collection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ spec:
value: {{ .Values.irsRegularApiKey | quote }}
- name: JAVA_TOOL_OPTIONS
value: {{ .Values.javaToolOptions | default "" | quote }}
- name: BPDM_URL
value: {{ .Values.bpdm.url | quote }}
{{- range $key, $val := .Values.env }}
- name: {{ $key }}
value: {{ $val | quote }}
Expand Down
3 changes: 3 additions & 0 deletions charts/traceability-foss/charts/backend/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,6 @@ dependencies:
enabled: false
irs: CHANGEME #<irs-helm.nameOverride>
edc: CHANGEME #<tractusx-connector.nameOverride>-controlplane

bpdm:
url: "https://replace.me"
3 changes: 3 additions & 0 deletions charts/traceability-foss/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,9 @@ backend:
irs: "CHANGEME" # <irs-helm.nameOverride>
edc: "CHANGEME" # <tractusx-connector.nameOverride

bpdm:
url: "https://replace.me"

#########################
# PG Admin configuration #
#########################
Expand Down
2 changes: 1 addition & 1 deletion docs/api/traceability-foss-backend.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tx-backend/openapi/traceability-foss-backend.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,26 @@
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.IRSResponse;
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.JobStatus;
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.factory.AssetMapperFactory;
import org.eclipse.tractusx.traceability.bpn.domain.service.BpnRepository;
import org.eclipse.tractusx.traceability.bpn.domain.service.BpnService;
import org.eclipse.tractusx.traceability.bpn.infrastructure.repository.BpnRepository;
import org.eclipse.tractusx.traceability.common.properties.TraceabilityProperties;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import static org.eclipse.tractusx.irs.component.enums.BomLifecycle.AS_BUILT;
import static org.eclipse.tractusx.irs.component.enums.BomLifecycle.AS_PLANNED;
import static org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.factory.AssetMapperFactory.extractBpnMap;

@Slf4j
@Service
public class JobRepositoryImpl implements JobRepository {

private final BpnRepository bpnRepository;

private final BpnService bpnService;
private final TraceabilityProperties traceabilityProperties;
private final AssetCallbackRepository assetAsBuiltCallbackRepository;
private final AssetCallbackRepository assetAsPlannedCallbackRepository;
Expand All @@ -66,12 +67,13 @@ public class JobRepositoryImpl implements JobRepository {
public JobRepositoryImpl(
IrsClient irsClient,
BpnRepository bpnRepository,
TraceabilityProperties traceabilityProperties,
BpnService bpnService, TraceabilityProperties traceabilityProperties,
@Qualifier("assetAsBuiltRepositoryImpl")
AssetCallbackRepository assetAsBuiltCallbackRepository,
@Qualifier("assetAsPlannedRepositoryImpl")
AssetCallbackRepository assetAsPlannedCallbackRepository, AssetMapperFactory assetMapperFactory) {
this.bpnRepository = bpnRepository;
this.bpnService = bpnService;
this.traceabilityProperties = traceabilityProperties;
this.assetAsBuiltCallbackRepository = assetAsBuiltCallbackRepository;
this.assetAsPlannedCallbackRepository = assetAsPlannedCallbackRepository;
Expand Down Expand Up @@ -102,13 +104,6 @@ public void handleJobFinishedCallback(String jobId, String state) {
log.info("IRS call for globalAssetId: {} finished with status: {}, runtime {} s.", jobResponseIRS.jobStatus().globalAssetId(), jobResponseIRS.jobStatus().state(), runtime);

if (jobCompleted(jobResponseIRS.jobStatus())) {
try {
Map<String, String> bpnMap = extractBpnMap(jobResponseIRS);
bpnRepository.updateManufacturers(bpnMap);
} catch (Exception e) {
log.warn("BPN Mapping Exception", e);
}

List<AssetBase> assets = assetMapperFactory.mapToAssetBaseList(jobResponseIRS);

assets.forEach(assetBase -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.irs.component.Bpn;
import org.eclipse.tractusx.irs.component.Relationship;
import org.eclipse.tractusx.irs.component.enums.Direction;
import org.eclipse.tractusx.traceability.assets.domain.base.model.AssetBase;
Expand All @@ -34,6 +33,7 @@
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.mapping.asplanned.AsPlannedDetailMapper;
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.mapping.relationship.RelationshipMapper;
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.mapping.submodel.SubmodelMapper;
import org.eclipse.tractusx.traceability.bpn.domain.service.BpnService;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

Expand All @@ -43,12 +43,10 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.apache.commons.collections4.ListUtils.emptyIfNull;
import static org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.mapping.submodel.MapperHelper.enrichAssetBase;
import static org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.mapping.submodel.MapperHelper.enrichManufacturingInformation;
import static org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.mapping.submodel.MapperHelper.getContractAgreementId;
import static org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.mapping.submodel.MapperHelper.getOwner;
import static org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.mapping.submodel.MapperHelper.getShortId;
Expand All @@ -63,12 +61,12 @@ public class AssetMapperFactory {
private final List<AsPlannedDetailMapper> asPlannedDetailMappers;
private final List<AsBuiltDetailMapper> asBuiltDetailMappers;
private final ObjectMapper objectMapper;
private final BpnService bpnService;

public List<AssetBase> mapToAssetBaseList(IRSResponse irsResponse) {

Map<String, List<Descriptions>> descriptionMap = extractRelationshipToDescriptionMap(irsResponse);

Map<String, String> bpnMap = extractBpnMap(irsResponse);

List<DetailAspectModel> tractionBatteryCode = extractTractionBatteryCode(irsResponse);

Expand All @@ -77,13 +75,12 @@ public List<AssetBase> mapToAssetBaseList(IRSResponse irsResponse) {
if (tombstones != null) {
log.info("Found {} tombstones", tombstones.size());
}
return toAssetBase(irsResponse, descriptionMap, bpnMap, tractionBatteryCode, partSiteInformationAsPlanned, tombstones);
return toAssetBase(irsResponse, descriptionMap, tractionBatteryCode, partSiteInformationAsPlanned, tombstones);
}

@NotNull
private List<AssetBase> toAssetBase(IRSResponse irsResponse,
Map<String, List<Descriptions>> descriptionMap,
Map<String, String> bpnMap, List<DetailAspectModel> tractionBatteryCode,
Map<String, List<Descriptions>> descriptionMap, List<DetailAspectModel> tractionBatteryCode,
List<DetailAspectModel> partSiteInformationAsPlanned,
List<AssetBase> tombstones) {
List<AssetBase> submodelAssets = new ArrayList<>(irsResponse
Expand All @@ -96,9 +93,10 @@ private List<AssetBase> toAssetBase(IRSResponse irsResponse,
assetBase.setOwner(getOwner(assetBase, irsResponse));
assetBase.setIdShort(getShortId(irsResponse.shells(), assetBase.getId()));
assetBase.setContractAgreementId(getContractAgreementId(irsResponse.shells(), assetBase.getId()));
assetBase.setManufacturerId(getManufacturerId(irsResponse, assetBase));
assetBase.setManufacturerName(bpnService.findByBpn(assetBase.getManufacturerId()));

enrichUpwardAndDownwardDescriptions(descriptionMap, assetBase);
enrichManufacturingInformation(irsResponse, bpnMap, assetBase);
enrichAssetBase(tractionBatteryCode, assetBase);
enrichAssetBase(partSiteInformationAsPlanned, assetBase);

Expand Down Expand Up @@ -140,20 +138,6 @@ private List<DetailAspectModel> extractTractionBatteryCode(IRSResponse irsRespon
.toList();
}

@NotNull
public static Map<String, String> extractBpnMap(IRSResponse irsResponse) {
return irsResponse
.bpns()
.stream()
.map(bpn -> {
Bpn bpn1 = Bpn.withManufacturerId(bpn.getManufacturerId());
bpn1.updateManufacturerName(bpn.getManufacturerName());
return bpn1;
}).filter(bpn -> bpn.getManufacturerName() != null)
.collect(Collectors.toMap(Bpn::getManufacturerId,
Bpn::getManufacturerName));
}

private static void enrichUpwardAndDownwardDescriptions(Map<String, List<Descriptions>> descriptionsMap, AssetBase assetBase) {
List<Descriptions> upwardDescriptions = new ArrayList<>();
List<Descriptions> downwardDescriptions = new ArrayList<>();
Expand Down Expand Up @@ -203,6 +187,13 @@ private Optional<AsBuiltDetailMapper> getAsBuiltDetailMapper(IrsSubmodel irsSubm
return asBuiltDetailMappers.stream().filter(asBuiltDetailMapper -> asBuiltDetailMapper.validMapper(irsSubmodel)).findFirst();
}

private String getManufacturerId(IRSResponse irsResponse, AssetBase assetBase){
if (assetBase.getManufacturerId() == null && assetBase.getId().equals(irsResponse.jobStatus().globalAssetId())) {
return irsResponse.jobStatus().parameter().bpn();
}
return assetBase.getManufacturerId();
}

}


Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,15 @@ public AssetBase extractSubmodel(IrsSubmodel irsSubmodel) {
JustInSequencePart300Schema justInSequencePart = (JustInSequencePart300Schema) irsSubmodel.getPayload();

String justInSequenceId = getValue(justInSequencePart.getLocalIdentifiers(), LocalIdKey.JIS_NUMBER.getValue());
String manufacturerName = getValue(justInSequencePart.getLocalIdentifiers(), LocalIdKey.MANUFACTURER_ID.getValue());
String manufacturerId = getValue(justInSequencePart.getLocalIdentifiers(), LocalIdKey.MANUFACTURER_ID.getValue());
String van = getValue(justInSequencePart.getLocalIdentifiers(), LocalIdKey.VAN.getValue());
DetailAspectModel detailAspectModel = extractDetailAspectModelsAsBuilt(justInSequencePart.getManufacturingInformation(), justInSequencePart.getPartTypeInformation());

return AssetBase.builder()
.id(justInSequencePart.getCatenaXId())
.semanticModelId(justInSequenceId)
.detailAspectModels(List.of(detailAspectModel))
.manufacturerId(manufacturerName)
.manufacturerName(manufacturerName)
.manufacturerId(manufacturerId)
.nameAtManufacturer(justInSequencePart.getPartTypeInformation().getNameAtManufacturer())
.manufacturerPartId(justInSequencePart.getPartTypeInformation().getManufacturerPartId())
// TODO extend data model to include all classification attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.Direction;
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.IRSResponse;
import org.eclipse.tractusx.traceability.assets.infrastructure.base.irs.model.response.Shell;
import org.eclipse.tractusx.traceability.bpn.domain.service.BpnService;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
Expand Down Expand Up @@ -71,16 +72,4 @@ public static void enrichAssetBase(List<DetailAspectModel> detailAspectModels, A
.ifPresent(detailAspectModel -> assetBase.setDetailAspectModels(List.of(detailAspectModel)));
}

public static void enrichManufacturingInformation(IRSResponse irsResponse, Map<String, String> bpnMap, AssetBase assetBase) {
if (assetBase.getManufacturerId() == null && assetBase.getId().equals(irsResponse.jobStatus().globalAssetId())) {
String bpn = irsResponse.jobStatus().parameter().bpn();
assetBase.setManufacturerId(bpn);
assetBase.setManufacturerName(bpnMap.get(bpn));
} else {
String bpnName = bpnMap.get(assetBase.getManufacturerId());
if (bpnName != null) {
assetBase.setManufacturerName(bpnName);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,15 @@ public AssetBase extractSubmodel(IrsSubmodel irsSubmodel) {
SerialPart300Schema serialPart = (SerialPart300Schema) irsSubmodel.getPayload();

String serialPartId = getValue(serialPart.getLocalIdentifiers(), LocalIdKey.PART_INSTANCE_ID.getValue());
String manufacturerName = getValue(serialPart.getLocalIdentifiers(), LocalIdKey.MANUFACTURER_ID.getValue());
String manufacturerId = getValue(serialPart.getLocalIdentifiers(), LocalIdKey.MANUFACTURER_ID.getValue());
String van = getValue(serialPart.getLocalIdentifiers(), LocalIdKey.VAN.getValue());
DetailAspectModel detailAspectModel = extractDetailAspectModelsAsBuilt(serialPart.getManufacturingInformation(), serialPart.getPartTypeInformation());

return AssetBase.builder()
.id(serialPart.getCatenaXId())
.semanticModelId(serialPartId)
.detailAspectModels(List.of(detailAspectModel))
.manufacturerId(manufacturerName)
.manufacturerName(manufacturerName)
.manufacturerId(manufacturerId)
.nameAtManufacturer(serialPart.getPartTypeInformation().getNameAtManufacturer())
.manufacturerPartId(serialPart.getPartTypeInformation().getManufacturerPartId())
// TODO change model to be able to save something here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.traceability.bpn.application.mapper.BpnMapper;
import org.eclipse.tractusx.traceability.bpn.domain.service.BpnServiceImpl;
import org.eclipse.tractusx.traceability.bpn.domain.service.BpnService;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
Expand All @@ -60,7 +60,7 @@
@RequiredArgsConstructor
public class BpnMappingController {

private final BpnServiceImpl service;
private final BpnService service;

@Operation(operationId = "getBpnEdcs",
summary = "Get BPN EDC URL mappings",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
package org.eclipse.tractusx.traceability.bpn.application.service;
package org.eclipse.tractusx.traceability.bpn.domain.service;

import bpn.request.BpnMappingRequest;
import org.eclipse.tractusx.traceability.bpn.domain.model.BpnEdcMapping;


import java.util.List;

public interface BpnService {
String findByBpn(String bpn);

List<BpnEdcMapping> findAllBpnMappings();

List<BpnEdcMapping> saveAllBpnEdcMappings(List<BpnMappingRequest> bpnEdcMappings);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/********************************************************************************
* Copyright (c) 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.traceability.bpn.infrastructure.client;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.traceability.bpn.infrastructure.model.BusinessPartnerResponse;
import org.eclipse.tractusx.traceability.common.properties.BpdmProperties;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Map;

import static org.eclipse.tractusx.traceability.common.config.RestTemplateConfiguration.BPDM_CLIENT_REST_TEMPLATE;

@Service
@Slf4j
public class BpdmClient {

private static final String PLACEHOLDER_BPID = "partnerId";
private static final String PLACEHOLDER_ID_TYPE = "idType";
private static final String ID_TYPE = "BPN";
private final @Qualifier(BPDM_CLIENT_REST_TEMPLATE) RestTemplate bpdmRestTemplate;
private final BpdmProperties bpdmProperties;

public BpdmClient(@Qualifier(BPDM_CLIENT_REST_TEMPLATE) RestTemplate bpdmRestTemplate, BpdmProperties bpdmProperties) {
this.bpdmRestTemplate = bpdmRestTemplate;
this.bpdmProperties = bpdmProperties;
}

public BusinessPartnerResponse getBusinessPartner(final String bpn) {
final UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(bpdmProperties.getBpnEndpoint());
final Map<String, String> values = Map.of(PLACEHOLDER_BPID, bpn, PLACEHOLDER_ID_TYPE, ID_TYPE);

try {
return bpdmRestTemplate.getForObject(uriBuilder.build(values), BusinessPartnerResponse.class);
} catch (HttpClientErrorException httpClientErrorException) {
log.warn("Could not request BPDM service.", httpClientErrorException);
return BusinessPartnerResponse.builder().bpn(bpn).build();
}

}


}
Loading
Loading