diff --git a/CHANGELOG.md b/CHANGELOG.md index ed9a4a279..eeee77a83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +## [2.1.0] - 2023-08-30 +### Fixed +- Added external subject in specific asset Ids. +- Update AAS submodel endpoints subprotocolBody. +- Supported Batch submodel version 2.0.0. +- DDTR update with latest version. +- Feign Client changes updated for child aspect relationship. + +## [2.0.11] - 2023-08-29 +### Changed +- Docker image name changed. + ## [2.0.10] - 2023-08-23 ### Fixed - Updated openAPI file for kics issue. @@ -203,9 +215,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Compliance with Catena-X Guidelines - Integration with Digital Twin registry service. -[unreleased]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/dftbackend-2.0.10...main -[2.0.10]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/dftbackend-2.0.9...dftbackend-2.0.10 -[2.0.9]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/dftbackend-2.0.8...dftbackend-2.0.9 +[unreleased]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/v2.1.0...main +[2.1.0]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/v2.0.11...v2.1.0 +[2.0.11]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/v2.0.10...v2.0.11 +[2.0.10]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/sdebackend-2.0.9...v2.0.10 +[2.0.9]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/sdebackend-2.0.8...sdebackend-2.0.9 [2.0.8]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/dftbackend-2.0.2...dftbackend-2.0.8 [2.0.2]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/dftbackend-2.0.1...dftbackend-2.0.2 [2.0.1]: https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/compare/dftbackend-2.0.0...dftbackend-2.0.1 diff --git a/INSTALL.md b/INSTALL.md index c270284cd..bd6ae0754 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -31,7 +31,7 @@ For more details, please refer configuration section from [README.md](README.md) - Postgres 11.9.13 #### Steps -1. Clone the GitHub Repository - https://github.com/eclipse-tractusx/dft-backend. +1. Clone the GitHub Repository - https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend. 2. Get your instance of postgres running (Create **dftdb** new database). 3. Setup your project environment to JDK 18. 4. Provide require application configuration in application.properties as specified in step configuration.properties. diff --git a/modules/sde-common/src/main/java/org/eclipse/tractusx/sde/common/constants/CommonConstants.java b/modules/sde-common/src/main/java/org/eclipse/tractusx/sde/common/constants/CommonConstants.java index 0731b07e1..f508cfd3e 100644 --- a/modules/sde-common/src/main/java/org/eclipse/tractusx/sde/common/constants/CommonConstants.java +++ b/modules/sde-common/src/main/java/org/eclipse/tractusx/sde/common/constants/CommonConstants.java @@ -37,13 +37,13 @@ private CommonConstants() { public static final String MANUFACTURER_ID = "manufacturerId"; public static final String CUSTOMER_PART_ID = "customerPartId"; public static final String ASSET_LIFECYCLE_PHASE = "assetLifecyclePhase"; - public static final String HTTP = "http"; + public static final String HTTP = "HTTP"; public static final String HTTPS = "HTTPS"; - public static final String ENDPOINT_PROTOCOL_VERSION = "0.1"; + public static final String ENDPOINT_PROTOCOL_VERSION = "1.1"; public static final String PREFIX = "urn:uuid:"; public static final String INTERFACE_EDC = "EDC"; - public static final String SUB_PROTOCOL = "IDS"; + public static final String SUB_PROTOCOL = "DSP"; public static final String SUBMODEL_CONTEXT_URL = "/submodel"; public static final String AS_PLANNED = "AsPlanned"; @@ -51,6 +51,6 @@ private CommonConstants() { public static final String EXTERNAL_REFERENCE = "ExternalReference"; public static final String GLOBAL_REFERENCE = "GlobalReference"; public static final String BODY_ENCODING = "plain"; - public static final String INTERFACE = "https://admin-shell.io/aas/API/3/0/SubmodelServiceSpecification/SSP-003"; + public static final String INTERFACE = "SUBMODEL-3.0"; } diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/ExternalSubjectId.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/ExternalSubjectId.java new file mode 100644 index 000000000..f9319a29b --- /dev/null +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/ExternalSubjectId.java @@ -0,0 +1,43 @@ +/******************************************************************************** + * Copyright (c) 2023 T-Systems International GmbH + * Copyright (c) 2023 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.sde.digitaltwins.entities.common; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class ExternalSubjectId { + + private String type; + + private List keys; + +} diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/KeyValuePair.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/KeyValuePair.java index 65516a342..ed98000a3 100644 --- a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/KeyValuePair.java +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/KeyValuePair.java @@ -21,15 +21,31 @@ package org.eclipse.tractusx.sde.digitaltwins.entities.common; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; + import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.SneakyThrows; @Data -@NoArgsConstructor +@Builder @AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) public class KeyValuePair { private String name; private String value; + private ExternalSubjectId externalSubjectId; + + @SneakyThrows + public String toJsonString() { + final ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(this); + } } diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/LookupQuery.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/LookupQuery.java new file mode 100644 index 000000000..b38c58c02 --- /dev/null +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/LookupQuery.java @@ -0,0 +1,44 @@ +/******************************************************************************** + * Copyright (c) 2023 T-Systems International GmbH + * Copyright (c) 2023 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.sde.digitaltwins.entities.common; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class LookupQuery { + + private String type; + private List assetIds; + private List semanticIds; + + + +} diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/ProtocolInformation.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/ProtocolInformation.java index f83f4b4eb..0bede9268 100644 --- a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/ProtocolInformation.java +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/ProtocolInformation.java @@ -45,4 +45,6 @@ public class ProtocolInformation { private String subProtocol; private String subprotocolBody; private String subprotocolBodyEncoding; + private List securityAttributes; + } diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/SecurityAttributes.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/SecurityAttributes.java new file mode 100644 index 000000000..e8b948ae2 --- /dev/null +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/common/SecurityAttributes.java @@ -0,0 +1,41 @@ +/******************************************************************************** + * Copyright (c) 2023 T-Systems International GmbH + * Copyright (c) 2023 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.sde.digitaltwins.entities.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class SecurityAttributes { + + + private String type; + private String key; + private String value; + +} diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/request/ShellDescriptorRequest.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/request/ShellDescriptorRequest.java index 9d2d3c0ee..07da2f45d 100644 --- a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/request/ShellDescriptorRequest.java +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/request/ShellDescriptorRequest.java @@ -23,9 +23,11 @@ import java.util.List; -import org.eclipse.tractusx.sde.digitaltwins.entities.common.KeyValuePair; import org.eclipse.tractusx.sde.digitaltwins.entities.common.MultiLanguage; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; @@ -38,13 +40,15 @@ @NoArgsConstructor @AllArgsConstructor @Getter +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(Include.NON_NULL) public class ShellDescriptorRequest { private String idShort; private String id; private List description; private String globalAssetId; - private List specificAssetIds; + private List specificAssetIds; @SneakyThrows public String toJsonString() { diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/request/ShellLookupQueryRequest.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/request/ShellLookupQueryRequest.java new file mode 100644 index 000000000..1f86713e0 --- /dev/null +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/entities/request/ShellLookupQueryRequest.java @@ -0,0 +1,40 @@ +/******************************************************************************** + * Copyright (c) 2023 T-Systems International GmbH + * Copyright (c) 2023 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.sde.digitaltwins.entities.request; + +import org.eclipse.tractusx.sde.digitaltwins.entities.common.LookupQuery; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +public class ShellLookupQueryRequest { + + private LookupQuery query; + + + + +} diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/facilitator/DigitalTwinsFacilitator.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/facilitator/DigitalTwinsFacilitator.java index b1f70bd83..c8594e00e 100644 --- a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/facilitator/DigitalTwinsFacilitator.java +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/facilitator/DigitalTwinsFacilitator.java @@ -25,6 +25,7 @@ import java.util.Base64; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.sde.common.exception.ServiceException; import org.eclipse.tractusx.sde.digitaltwins.entities.request.CreateSubModelRequest; import org.eclipse.tractusx.sde.digitaltwins.entities.request.ShellDescriptorRequest; @@ -55,20 +56,24 @@ public class DigitalTwinsFacilitator { @Value(value = "${digital-twins.api:/api/v3.0}") private String dtApiUri; + @Value(value = "${manufacturerId}") + public String manufacturerId; + public List shellLookup(ShellLookupRequest request) throws ServiceException { - return shellLookupFromDDTR(request, null); + return shellLookupFromDDTR(request, null, manufacturerId); } @SneakyThrows - public List shellLookupFromDDTR(ShellLookupRequest request, String ddtrUrl) throws ServiceException { + public List shellLookupFromDDTR(ShellLookupRequest request, String ddtrUrl, String edcBpn) + throws ServiceException { - URI dtURL = (ddtrUrl == null || ddtrUrl.length() <= 0) ? getDtURL(digitalTwinsHost) : getDtURL(ddtrUrl); + URI dtURL = StringUtils.isAllEmpty(ddtrUrl) ? getDtURL(digitalTwinsHost) : getDtURL(ddtrUrl); List shellIds = List.of(); try { ResponseEntity response = digitalTwinsFeignClient.shellLookup(dtURL, - request.toJsonString()); + request.toJsonString(), edcBpn); ShellLookupResponse body = response.getBody(); if (response.getStatusCode() == HttpStatus.OK && body != null) { @@ -106,17 +111,17 @@ public List getShellDescriptorsWithSubmodelDetails(List List items = new ArrayList<>(); for (String shellId : shellIds) { - items.add(getShellDetailsById(shellId, ddtrUrl)); + items.add(getShellDetailsById(shellId, ddtrUrl, manufacturerId)); } return items; } - public ShellDescriptorResponse getShellDetailsById(String shellId, String ddtrUrl) { + public ShellDescriptorResponse getShellDetailsById(String shellId, String ddtrUrl, String edcBpn) { - URI dtURL = (ddtrUrl == null || ddtrUrl.length() <= 0) ? getDtURL(digitalTwinsHost) : getDtURL(ddtrUrl); + URI dtURL = StringUtils.isAllEmpty(ddtrUrl) ? getDtURL(digitalTwinsHost) : getDtURL(ddtrUrl); ResponseEntity shellDescriptorResponse = digitalTwinsFeignClient - .getShellDescriptorByShellId(dtURL, encodeShellIdBase64Utf8(shellId)); + .getShellDescriptorByShellId(dtURL, encodeShellIdBase64Utf8(shellId), edcBpn); return shellDescriptorResponse.getBody(); } @@ -142,6 +147,18 @@ public ShellDescriptorResponse createShellDescriptor(ShellDescriptorRequest requ return responseBody; } + public void updateShellSpecificAssetIdentifiers(String shellId, List specificAssetIds) { + + digitalTwinsFeignClient.deleteShellSpecificAttributes(getDtURL(digitalTwinsHost), + encodeShellIdBase64Utf8(shellId), manufacturerId); + + ResponseEntity> registerSubmodel = digitalTwinsFeignClient.createShellSpecificAttributes( + getDtURL(digitalTwinsHost), encodeShellIdBase64Utf8(shellId), manufacturerId, specificAssetIds); + if (registerSubmodel.getStatusCode() != HttpStatus.CREATED) { + log.error("Error in shell SpecificAssetIdentifiers deletion: " + registerSubmodel.toString()); + } + } + public void createSubModel(String shellId, CreateSubModelRequest request) { request.setDescription(List.of()); diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/facilitator/DigitalTwinsUtility.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/facilitator/DigitalTwinsUtility.java index ade57a55d..d2cb2f7fb 100644 --- a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/facilitator/DigitalTwinsUtility.java +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/facilitator/DigitalTwinsUtility.java @@ -19,22 +19,30 @@ ********************************************************************************/ package org.eclipse.tractusx.sde.digitaltwins.facilitator; +import static org.eclipse.tractusx.sde.common.constants.CommonConstants.ASSET_LIFECYCLE_PHASE; +import static org.eclipse.tractusx.sde.common.constants.CommonConstants.MANUFACTURER_PART_ID; + import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.tractusx.sde.common.constants.CommonConstants; import org.eclipse.tractusx.sde.common.utils.UUIdGenerator; import org.eclipse.tractusx.sde.digitaltwins.entities.common.Endpoint; +import org.eclipse.tractusx.sde.digitaltwins.entities.common.ExternalSubjectId; import org.eclipse.tractusx.sde.digitaltwins.entities.common.KeyValuePair; import org.eclipse.tractusx.sde.digitaltwins.entities.common.Keys; import org.eclipse.tractusx.sde.digitaltwins.entities.common.ProtocolInformation; +import org.eclipse.tractusx.sde.digitaltwins.entities.common.SecurityAttributes; import org.eclipse.tractusx.sde.digitaltwins.entities.common.SemanticId; import org.eclipse.tractusx.sde.digitaltwins.entities.request.CreateSubModelRequest; import org.eclipse.tractusx.sde.digitaltwins.entities.request.ShellDescriptorRequest; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -46,6 +54,8 @@ @Getter public class DigitalTwinsUtility { + private static final String PUBLIC_READABLE = "PUBLIC_READABLE"; + @Value(value = "${manufacturerId}") public String manufacturerId; @@ -54,83 +64,114 @@ public class DigitalTwinsUtility { ObjectMapper mapper = new ObjectMapper(); + private static final Map> publicReadableSpecificAssetIDs = Map.of(MANUFACTURER_PART_ID, + List.of("*"), ASSET_LIFECYCLE_PHASE, List.of("AsBuilt", "AsPlanned")); + @SneakyThrows public ShellDescriptorRequest getShellDescriptorRequest(Map specificIdentifiers, Object object) { JsonNode jsonNode = mapper.convertValue(object, ObjectNode.class); + List bpns = getFieldFromJsonNodeArray(jsonNode, "bpn_numbers"); + return ShellDescriptorRequest.builder() .idShort(String.format("%s_%s_%s", getFieldFromJsonNode(jsonNode, "name_at_manufacturer"), manufacturerId, getFieldFromJsonNode(jsonNode, "manufacturer_part_id"))) .globalAssetId(getFieldFromJsonNode(jsonNode, "uuid")) - .specificAssetIds(getSpecificAssetIds(specificIdentifiers)) - .description(List.of()) - .id(UUIdGenerator.getUrnUuid()) - .build(); + .specificAssetIds(getSpecificAssetIds(specificIdentifiers, bpns)).description(List.of()) + .id(UUIdGenerator.getUrnUuid()).build(); } @SneakyThrows public CreateSubModelRequest getCreateSubModelRequest(String shellId, String sematicId, String idShortofModel) { String identification = UUIdGenerator.getUrnUuid(); - - SemanticId semanticId = SemanticId.builder() - .type(CommonConstants.EXTERNAL_REFERENCE) - .keys(List.of(new Keys(CommonConstants.GLOBAL_REFERENCE,sematicId))) - .build(); + + SemanticId semanticId = SemanticId.builder().type(CommonConstants.EXTERNAL_REFERENCE) + .keys(List.of(new Keys(CommonConstants.GLOBAL_REFERENCE, sematicId))).build(); List endpoints = prepareDtEndpoint(shellId, identification); - return CreateSubModelRequest.builder() - .id(identification) - .idShort(idShortofModel) - .semanticId(semanticId) - .endpoints(endpoints) - .build(); + return CreateSubModelRequest.builder().id(identification).idShort(idShortofModel).semanticId(semanticId) + .endpoints(endpoints).build(); } - + @SneakyThrows - public CreateSubModelRequest getCreateSubModelRequestForChild(String shellId, String sematicId, String idShortofModel, String identification) { - - SemanticId semanticId = SemanticId.builder() - .type(CommonConstants.EXTERNAL_REFERENCE) - .keys(List.of(new Keys(CommonConstants.GLOBAL_REFERENCE,sematicId))) - .build(); + public CreateSubModelRequest getCreateSubModelRequestForChild(String shellId, String sematicId, + String idShortofModel, String identification) { + + SemanticId semanticId = SemanticId.builder().type(CommonConstants.EXTERNAL_REFERENCE) + .keys(List.of(new Keys(CommonConstants.GLOBAL_REFERENCE, sematicId))).build(); List endpoints = prepareDtEndpoint(shellId, identification); - return CreateSubModelRequest.builder() - .idShort(idShortofModel) - .id(identification) - .semanticId(semanticId) - .endpoints(endpoints) - .build(); + return CreateSubModelRequest.builder().idShort(idShortofModel).id(identification).semanticId(semanticId) + .endpoints(endpoints).build(); } public List prepareDtEndpoint(String shellId, String submodelIdentification) { List endpoints = new ArrayList<>(); - endpoints.add(Endpoint.builder() - .endpointInterface(CommonConstants.INTERFACE) + endpoints.add(Endpoint.builder().endpointInterface(CommonConstants.INTERFACE) .protocolInformation(ProtocolInformation.builder() - .endpointAddress(edcEndpoint + "/api/public/" + encodedUrl("shells/"+shellId+ "/submodels/"+submodelIdentification) - + CommonConstants.SUBMODEL_CONTEXT_URL) + .endpointAddress(edcEndpoint + CommonConstants.SUBMODEL_CONTEXT_URL) .endpointProtocol(CommonConstants.HTTP) .endpointProtocolVersion(List.of(CommonConstants.ENDPOINT_PROTOCOL_VERSION)) .subProtocol(CommonConstants.SUB_PROTOCOL) + .subprotocolBody(encodedUrl("id=" + shellId + "-" + submodelIdentification) + ";dspEndpoint=" + + edcEndpoint) .subprotocolBodyEncoding(CommonConstants.BODY_ENCODING) - .build()) + .securityAttributes(List.of(new SecurityAttributes("NONE", "NONE", "NONE"))).build()) .build()); return endpoints; } - - private ArrayList getSpecificAssetIds(Map specificAssetIds) { - ArrayList specificIdentifiers = new ArrayList<>(); + @SneakyThrows + public List getSpecificAssetIds(Map specificAssetIds, List bpns) { + + List specificIdentifiers = new ArrayList<>(); + + List keyList = bpnKeyRefrence(bpns); + + specificAssetIds.entrySet().stream().forEach(entry -> { + + List list = publicReadableSpecificAssetIDs.get(entry.getKey()); + ExternalSubjectId externalSubjectId = null; + + if (list != null && (list.contains("*") || list.contains(entry.getValue()))) { + externalSubjectId = ExternalSubjectId.builder() + .type("ExternalReference") + .keys(List.of(Keys.builder().type("GlobalReference").value(PUBLIC_READABLE).build())) + .build(); + specificIdentifiers.add(new KeyValuePair(entry.getKey(), entry.getValue(), externalSubjectId)); + } + else { + if (keyList != null && !keyList.isEmpty()) { + + externalSubjectId = ExternalSubjectId.builder() + .type("ExternalReference").keys(keyList) + .build(); + specificIdentifiers.add(new KeyValuePair(entry.getKey(), entry.getValue(), externalSubjectId)); + + } else { + Map map = new HashMap<>(); + map.put("name", entry.getKey()); + map.put("value", entry.getValue()); + specificIdentifiers.add(map); + } + } + }); - specificAssetIds.entrySet().stream() - .forEach(entry -> specificIdentifiers.add(new KeyValuePair(entry.getKey(), entry.getValue()))); return specificIdentifiers; } + private List bpnKeyRefrence(List bpns) { + if (bpns != null && !(bpns.size() == 1 && bpns.contains(manufacturerId))) { + return bpns.stream() + .map(bpn -> Keys.builder().type("GlobalReference").value(bpn).build()) + .toList(); + } + return Collections.emptyList(); + } + private String encodedUrl(String format) { return format.replace(":", "%3A"); } @@ -142,4 +183,16 @@ private String getFieldFromJsonNode(JsonNode jnode, String fieldName) { return ""; } + @SneakyThrows + private List getFieldFromJsonNodeArray(JsonNode jsonNode, String fieldName) { + ObjectMapper objectMapper = new ObjectMapper(); + + if (jsonNode.get(fieldName) != null) + return objectMapper.readValue(jsonNode.get(fieldName).toString(), new TypeReference>() { + }); + + else + return List.of(); + } + } diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/gateways/external/DigitalTwinsFeignClient.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/gateways/external/DigitalTwinsFeignClient.java index 90eed3243..d7dbfadfb 100644 --- a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/gateways/external/DigitalTwinsFeignClient.java +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/gateways/external/DigitalTwinsFeignClient.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.sde.digitaltwins.gateways.external; import java.net.URI; +import java.util.List; import org.eclipse.tractusx.sde.common.model.KeycloakJWTTokenResponse; import org.eclipse.tractusx.sde.digitaltwins.entities.request.CreateSubModelRequest; @@ -36,6 +37,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(value = "DigitalTwinsFeignClient", url = "placeholder", configuration = DigitalTwinsFeignClientConfiguration.class) @@ -44,29 +46,40 @@ public interface DigitalTwinsFeignClient { @PostMapping KeycloakJWTTokenResponse readAuthToken(URI url, @RequestBody MultiValueMap body); - @DeleteMapping(path = "/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") - ResponseEntity deleteSubmodelfromShellById(URI url, @PathVariable("aasIdentifier") String shellId, - @PathVariable("submodelIdentifier") String submodelIdentifier); - @PostMapping(path = "/shell-descriptors") ResponseEntity createShellDescriptor(URI url, @RequestBody ShellDescriptorRequest request); + @GetMapping(path = "/shell-descriptors/{aasIdentifier}") ResponseEntity getShellDescriptorByShellId(URI url, - @PathVariable("aasIdentifier") String shellId); + @PathVariable("aasIdentifier") String shellId, @RequestHeader("Edc-Bpn") String edcBpn); + + @DeleteMapping(path = "/shell-descriptors/{aasIdentifier}") + ResponseEntity deleteShell(URI url, @PathVariable("assetIds") String shellId); @PostMapping(path = "/shell-descriptors/{aasIdentifier}/submodel-descriptors") ResponseEntity createSubModel(URI url, @PathVariable("aasIdentifier") String shellId, @RequestBody CreateSubModelRequest request); - + @GetMapping(path = "/shell-descriptors/{aasIdentifier}/submodel-descriptors") ResponseEntity getSubModels(URI digitalTwinsHost, @PathVariable("aasIdentifier") String shellId); - @GetMapping(path = "/lookup/shells") - ResponseEntity shellLookup(URI url, @RequestParam String assetIds); + @DeleteMapping(path = "/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") + ResponseEntity deleteSubmodelfromShellById(URI url, @PathVariable("aasIdentifier") String shellId, + @PathVariable("submodelIdentifier") String submodelIdentifier); + @GetMapping(path = "/lookup/shells") + ResponseEntity shellLookup(URI url, @RequestParam String assetIds, + @RequestHeader("Edc-Bpn") String edcBpn); + + @PostMapping(path = "/lookup/shells/{assetIds}") + ResponseEntity> createShellSpecificAttributes(URI url, @PathVariable("assetIds") String shellId, + @RequestHeader("Edc-Bpn") String edcBpn, @RequestBody List specificAssetIds); + @DeleteMapping(path = "/lookup/shells/{assetIds}") - ResponseEntity deleteShell(URI url, @PathVariable("assetIds") String shellId); + ResponseEntity deleteShellSpecificAttributes(URI url, @PathVariable("assetIds") String shellId, + @RequestHeader("Edc-Bpn") String edcBpn); + } diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/asset/DataAddressRequest.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/asset/DataAddressRequest.java index 8e2d762e2..207f89424 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/asset/DataAddressRequest.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/asset/DataAddressRequest.java @@ -38,7 +38,7 @@ public class DataAddressRequest { @Builder.Default - private String type = "HttpProxy"; + private String type = "HttpData"; private HashMap properties; diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/policies/PolicyConstraintBuilderService.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/policies/PolicyConstraintBuilderService.java index b30e416ea..b33928bc3 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/policies/PolicyConstraintBuilderService.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/policies/PolicyConstraintBuilderService.java @@ -53,41 +53,45 @@ public ActionRequest getUsagePolicyConstraints(List usagePolicies if (usagePolicies != null && !usagePolicies.isEmpty()) { usagePolicies.stream().forEach(policy -> usagePolicy(usageConstraintList, policy)); } - ActionRequest action = ActionRequest.builder().build(); - action.addProperty("@type", "LogicalConstraint"); - action.addProperty("odrl:and", usageConstraintList); - return action; + + if (!usageConstraintList.isEmpty()) { + ActionRequest action = ActionRequest.builder().build(); + action.addProperty("@type", "LogicalConstraint"); + action.addProperty("odrl:and", usageConstraintList); + return action; + } + return null; } private void usagePolicy(List usageConstraintList, UsagePolicies policy) { + ConstraintRequest request = null; + switch (policy.getType()) { case DURATION: - ConstraintRequest request = DurationPolicyDTO.fromUsagePolicy(policy).toConstraint(); - if (request != null) { - usageConstraintList.add(request); - } + request = DurationPolicyDTO.fromUsagePolicy(policy).toConstraint(); break; case PURPOSE: - ConstraintRequest purposeRequest = PurposePolicyDTO.fromUsagePolicy(policy).toConstraint(); - if (purposeRequest != null) { - usageConstraintList.add(purposeRequest); - } + request = PurposePolicyDTO.fromUsagePolicy(policy).toConstraint(); break; case ROLE: - ConstraintRequest roleRequest = RolePolicyDTO.fromUsagePolicy(policy).toConstraint(); - if (roleRequest != null) { - usageConstraintList.add(roleRequest); - } + request = RolePolicyDTO.fromUsagePolicy(policy).toConstraint(); break; default: break; } - } + if (request != null) { + usageConstraintList.add(request); + } + } + public ConstraintRequest toTraceabilityConstraint() { String operator = "odrl:eq"; - return ConstraintRequest.builder().leftOperand("FrameworkAgreement.traceability") - .operator(Operator.builder().id(operator).build()).rightOperand("active").build(); + return ConstraintRequest.builder() + .leftOperand("FrameworkAgreement.traceability") + .operator(Operator.builder().id(operator).build()) + .rightOperand("active") + .build(); } } diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/ContractNegotiateManagementHelper.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/ContractNegotiateManagementHelper.java index ea3a94839..f5a4cd80e 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/ContractNegotiateManagementHelper.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/ContractNegotiateManagementHelper.java @@ -31,6 +31,7 @@ import org.eclipse.tractusx.sde.edc.api.ContractApi; import org.eclipse.tractusx.sde.edc.entities.request.policies.ActionRequest; import org.eclipse.tractusx.sde.edc.entities.request.policies.ConstraintRequest; +import org.eclipse.tractusx.sde.edc.entities.request.policies.PermissionRequest; import org.eclipse.tractusx.sde.edc.enums.NegotiationState; import org.eclipse.tractusx.sde.edc.mapper.ContractMapper; import org.eclipse.tractusx.sde.edc.model.contractnegotiation.AcknowledgementId; @@ -84,6 +85,7 @@ public List getAllContractNegotiations(String type, Inte } + @SuppressWarnings("unchecked") @SneakyThrows public ContractAgreementResponse getAgreementBasedOnNegotiationId(String type, String negotiationId) { ContractAgreementResponse agreementResponse = null; @@ -99,18 +101,20 @@ public ContractAgreementResponse getAgreementBasedOnNegotiationId(String type, S } if (agreement != null) { List policies = new ArrayList<>(); - - Object object = agreement.getPolicy().getPermissions().getConstraint().get("odrl:and"); - if (object != null) - setContraint(objeMapper, policies, object); - else { - object = agreement.getPolicy().getPermissions().getConstraint().get("odrl:or"); - if (object != null) - setContraint(objeMapper, policies, object); + Object permissionObj = agreement.getPolicy().getPermissions(); + + if (permissionObj instanceof ArrayList) { + for (Object obj : (ArrayList) permissionObj) + formatPermissionConstraint(objeMapper, policies, obj); + } else if (permissionObj != null) { + formatPermissionConstraint(objeMapper, policies, permissionObj); } + if (policies.isEmpty()) + UtilityFunctions.getUsagePolicies(policies, List.of()); + UtilityFunctions.addCustomUsagePolicy(agreement.getPolicy().getExtensibleProperties(), policies); - + ContractAgreementInfo agreementInfo = ContractAgreementInfo.builder() .contractEndDate(agreement.getContractEndDate()) .contractSigningDate(agreement.getContractSigningDate()) @@ -126,16 +130,31 @@ public ContractAgreementResponse getAgreementBasedOnNegotiationId(String type, S return agreementResponse; } + private void formatPermissionConstraint(ObjectMapper objeMapper, List policies, + Object permissionObj) { + ObjectMapper objMapper = new ObjectMapper(); + PermissionRequest permissionRequest = objMapper.convertValue(permissionObj, PermissionRequest.class); + + Object object = permissionRequest.getConstraint().get("odrl:and"); + if (object != null) + setContraint(objeMapper, policies, object); + else { + object = permissionRequest.getConstraint().get("odrl:or"); + if (object != null) + setContraint(objeMapper, policies, object); + } + } + private void setContraint(ObjectMapper objeMapper, List policies, Object object) { if (object instanceof ArrayList) { List convertValue = objeMapper.convertValue(object, new TypeReference>() { }); - policies.addAll(UtilityFunctions.getUsagePolicies(convertValue)); + UtilityFunctions.getUsagePolicies(policies, convertValue); } else if (object !=null ){ ConstraintRequest convertValue = objeMapper.convertValue(object, ConstraintRequest.class); - policies.addAll(UtilityFunctions.getUsagePolicies(List.of(convertValue))); + UtilityFunctions.getUsagePolicies(policies, List.of(convertValue)); } } diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/CreateEDCAssetFacilator.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/CreateEDCAssetFacilator.java index de1a8d18c..7ec4f9965 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/CreateEDCAssetFacilator.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/CreateEDCAssetFacilator.java @@ -59,26 +59,24 @@ public Map createEDCAsset(AssetEntryRequest assetEntryRequest, L String assetId = assetEntryRequest.getAsset().getId(); - ActionRequest usageAction = policyConstraintBuilderService.getUsagePolicyConstraints(usagePolicies); + ActionRequest accessAction = policyConstraintBuilderService.getAccessConstraints(bpns); String customValue = getCustomValue(usagePolicies); if (StringUtils.isNotBlank(getCustomValue(usagePolicies))) { extensibleProperties.put(UsagePolicyEnum.CUSTOM.name(), customValue); } - + PolicyDefinitionRequest accessPolicyDefinitionRequest = policyFactory.getPolicy(assetId, accessAction, new HashMap<>()); edcGateway.createPolicyDefinition(accessPolicyDefinitionRequest); String accessPolicyId = accessPolicyDefinitionRequest.getId(); - String usagePolicyId = accessPolicyDefinitionRequest.getId(); - if (usageAction != null) { - PolicyDefinitionRequest usagePolicyDefinitionRequest = policyFactory.getPolicy(assetId, usageAction, - extensibleProperties); - edcGateway.createPolicyDefinition(usagePolicyDefinitionRequest); - usagePolicyId = usagePolicyDefinitionRequest.getId(); - } + ActionRequest usageAction = policyConstraintBuilderService.getUsagePolicyConstraints(usagePolicies); + PolicyDefinitionRequest usagePolicyDefinitionRequest = policyFactory.getPolicy(assetId, usageAction, + extensibleProperties); + edcGateway.createPolicyDefinition(usagePolicyDefinitionRequest); + String usagePolicyId = usagePolicyDefinitionRequest.getId(); ContractDefinitionRequest contractDefinitionRequest = contractFactory.getContractDefinitionRequest(assetId, accessPolicyId, usagePolicyId); diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/policies/PolicyDefinition.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/policies/PolicyDefinition.java index 30d53de95..bb76d6830 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/policies/PolicyDefinition.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/policies/PolicyDefinition.java @@ -23,8 +23,6 @@ import java.util.List; import java.util.Map; -import org.eclipse.tractusx.sde.edc.entities.request.policies.PermissionRequest; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -49,7 +47,7 @@ public class PolicyDefinition { private String id; @JsonProperty("odrl:permission") - private PermissionRequest permissions; + private Object permissions; @JsonProperty("odrl:prohibition") private List prohibitions; diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/UtilityFunctions.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/UtilityFunctions.java index 1b4132b20..ca8ae15c8 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/UtilityFunctions.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/UtilityFunctions.java @@ -20,7 +20,6 @@ package org.eclipse.tractusx.sde.edc.util; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -97,8 +96,7 @@ private static UsagePolicies getResponse(String value, DurationEnum durationUnit return policyResponse; } - public static List getUsagePolicies(List constraints) { - List usagePolicies = new ArrayList<>(); + public static List getUsagePolicies(List usagePolicies, List constraints) { constraints.forEach(constraint -> { String leftExpVal = constraint.getLeftOperand(); String rightExpVal = constraint.getRightOperand().toString(); diff --git a/modules/sde-submodules/assembly-part-relationship/src/main/java/org/eclipse/tractusx/sde/submodels/apr/steps/DigitalTwinsAspectRelationShipCsvHandlerUseCase.java b/modules/sde-submodules/assembly-part-relationship/src/main/java/org/eclipse/tractusx/sde/submodels/apr/steps/DigitalTwinsAspectRelationShipCsvHandlerUseCase.java index d86357e69..cc5213c3c 100644 --- a/modules/sde-submodules/assembly-part-relationship/src/main/java/org/eclipse/tractusx/sde/submodels/apr/steps/DigitalTwinsAspectRelationShipCsvHandlerUseCase.java +++ b/modules/sde-submodules/assembly-part-relationship/src/main/java/org/eclipse/tractusx/sde/submodels/apr/steps/DigitalTwinsAspectRelationShipCsvHandlerUseCase.java @@ -195,7 +195,7 @@ private CreateSubModelRequest getCreateSubModelRequest(AspectRelationship aspect for (String ddtUrl : dtURls) { - List childshellIds = digitalTwinfacilitaor.shellLookupFromDDTR(shellLookupRequest, ddtUrl); + List childshellIds = digitalTwinfacilitaor.shellLookupFromDDTR(shellLookupRequest, ddtUrl, aspectRelationShip.getChildManufacturerId()); if (childshellIds.isEmpty()) { log.warn(aspectRelationShip.getRowNumber() + ", " + ddtUrl + ", No child aspect found for " @@ -209,8 +209,11 @@ private CreateSubModelRequest getCreateSubModelRequest(AspectRelationship aspect if (childshellIds.size() == 1) { ShellDescriptorResponse shellDescriptorResponse = digitalTwinfacilitaor - .getShellDetailsById(childshellIds.get(0), ddtUrl); + .getShellDetailsById(childshellIds.get(0), ddtUrl, aspectRelationShip.getChildManufacturerId()); childUUID = shellDescriptorResponse.getGlobalAssetId(); + log.debug(aspectRelationShip.getRowNumber() + ", " + ddtUrl + ", Child aspect found for " + + shellLookupRequest.toJsonString()); + break; } } diff --git a/modules/sde-submodules/batch/batch.md b/modules/sde-submodules/batch/batch.md index 9e3016234..42dd7530a 100644 --- a/modules/sde-submodules/batch/batch.md +++ b/modules/sde-submodules/batch/batch.md @@ -5,9 +5,9 @@ This module use for Batch submodel specification and descriptors. It's contain the codes related to Batch to validate, parse and transfer data for DigitalTwins and EDC to create aspect twins and data offer. --- -#### Version: 1.0.2 -#### Batch Aspect Model URN: urn:bamm:io.catenax.batch:1.0.2#Batch -#### Semantic Id: urn:bamm:io.catenax.batch:1.0.2 +#### Version: 2.0.0 +#### Batch Aspect Model URN: urn:bamm:io.catenax.batch:2.0.0#Batch +#### Semantic Id: urn:samm:io.catenax.batch:2.0.0 --- ### Schema @@ -27,10 +27,8 @@ Please find below links for schema details: | manufacturing_date | Yes | 4 | | manufacturing_country | No | 5 | | manufacturer_part_id | Yes | 6 | -| customer_part_id | No | 7 | -| classification | Yes | 8 | -| name_at_manufacturer | Yes | 9 | -| name_at_customer | No | 10 | +| classification | Yes | 7 | +| name_at_manufacturer | Yes | 8 | #### [CSV Sample File Link] diff --git a/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/entity/BatchEntity.java b/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/entity/BatchEntity.java index 65ea6eae2..538c8fdba 100644 --- a/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/entity/BatchEntity.java +++ b/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/entity/BatchEntity.java @@ -48,14 +48,10 @@ public class BatchEntity implements Serializable { private String manufacturingCountry; @Column(name = "manufacturer_part_id") private String manufacturerPartId; - @Column(name = "customer_part_id") - private String customerPartId; @Column(name = "classification") private String classification; @Column(name = "name_at_manufacturer") private String nameAtManufacturer; - @Column(name = "name_at_customer") - private String nameAtCustomer; @Column(name = "shell_id") private String shellId; @Column(name = "sub_model_id") diff --git a/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/mapper/BatchMapper.java b/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/mapper/BatchMapper.java index cdd6fad8a..7a16291e5 100644 --- a/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/mapper/BatchMapper.java +++ b/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/mapper/BatchMapper.java @@ -81,10 +81,8 @@ public JsonObject mapToResponse(BatchEntity entity) { PartTypeInformation partTypeInformation = PartTypeInformation.builder() .manufacturerPartId(entity.getManufacturerPartId()) - .customerPartId(entity.getCustomerPartId()) .classification(entity.getClassification()) .nameAtManufacturer(entity.getNameAtManufacturer()) - .nameAtCustomer(entity.getNameAtCustomer()) .build(); return new Gson().toJsonTree(SubmodelResultResponse.builder().localIdentifiers(localIdentifiers) diff --git a/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/steps/DigitalTwinsBatchCsvHandlerUseCase.java b/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/steps/DigitalTwinsBatchCsvHandlerUseCase.java index c7b7de189..8e234b4a5 100644 --- a/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/steps/DigitalTwinsBatchCsvHandlerUseCase.java +++ b/modules/sde-submodules/batch/src/main/java/org/eclipse/tractusx/sde/submodels/batch/steps/DigitalTwinsBatchCsvHandlerUseCase.java @@ -80,6 +80,10 @@ private Batch doRun(Batch batch) throws CsvHandlerDigitalTwinUseCaseException { } else if (shellIds.size() == 1) { logDebug(String.format("Shell id found for '%s'", shellLookupRequest.toJsonString())); shellId = shellIds.stream().findFirst().orElse(null); + + digitalTwinsFacilitator.updateShellSpecificAssetIdentifiers(shellId, + digitalTwinsUtility.getSpecificAssetIds(getSpecificAssetIds(batch), batch.getBpnNumbers())); + logDebug(String.format("Shell id '%s'", shellId)); } else { throw new CsvHandlerDigitalTwinUseCaseException( diff --git a/modules/sde-submodules/batch/src/main/resources/batch.csv b/modules/sde-submodules/batch/src/main/resources/batch.csv index ee8859b45..dacea3033 100644 --- a/modules/sde-submodules/batch/src/main/resources/batch.csv +++ b/modules/sde-submodules/batch/src/main/resources/batch.csv @@ -1,2 +1,2 @@ -uuid;batch_id;part_instance_id;manufacturing_date;manufacturing_country;manufacturer_part_id;customer_part_id;classification;name_at_manufacturer;name_at_customer;optional_identifier_key;optional_identifier_value -urn:uuid:8eea5f45-0823-48ce-a4fc-c3bf1f8ff4c2;BIDNO345678;PIDNO678905;2022-02-05T14:48:54;HUR;122-0.740-3430-A;PRT-NO345;product;Mirror left;side element A;; \ No newline at end of file +uuid;batch_id;part_instance_id;manufacturing_date;manufacturing_country;manufacturer_part_id;classification;name_at_manufacturer; +urn:uuid:8eea5f45-0823-48ce-a4fc-c3bf1f8ff4c2;BIDNO345678;PIDNO678905;2022-02-05T14:48:54;HUR;122-0.740-3430-A;product;Mirror left \ No newline at end of file diff --git a/modules/sde-submodules/batch/src/main/resources/batch.json b/modules/sde-submodules/batch/src/main/resources/batch.json index 556a3dacd..71fcf2c07 100644 --- a/modules/sde-submodules/batch/src/main/resources/batch.json +++ b/modules/sde-submodules/batch/src/main/resources/batch.json @@ -4,8 +4,8 @@ "type": "array", "id": "batch", "idShort": "Batch", - "version": "1.0.2", - "semantic_id": "urn:bamm:io.catenax.batch:1.0.2#Batch", + "version": "2.0.0", + "semantic_id": "urn:samm:io.catenax.batch:2.0.0#Batch", "title": "Batch", "shortDescription": "BoM AsBuilt - Submodel Batch", "description": "A batch is a quantity of (semi-) finished products or (raw) material product that have been produced under the same circumstances (e.g. same production location), as specified groups or amounts, within a certain time frame. Every batch can differ in the number or amount of products. Different batches can have varied specifications, e.g., different colors. A batch is identified via a Batch ID.", @@ -280,17 +280,6 @@ "37754B7-76" ] }, - "customer_part_id": { - "type": [ - "string", - "null" - ], - "title": "Customer Part ID", - "description": "Part ID as assigned by the manufacturer of the part. The Part ID identifies the part (as designed) in the customer`s dataspace. The Part ID does not reference a specific instance of a part and thus should not be confused with the serial number or batch number. Note: This property may only be populated in case there is a single customer for the batch.", - "examples": [ - "37754B7-76" - ] - }, "classification": { "type": [ "string" @@ -319,17 +308,6 @@ "examples": [ "Sensor" ] - }, - "name_at_customer": { - "type": [ - "string", - "null" - ], - "title": "Name At Customer", - "description": "Name of the part as assigned by the customer", - "examples": [ - "Customer" - ] } } }, @@ -337,14 +315,12 @@ { "uuid": "urn:uuid:8eea5f45-0823-48ce-a4fc-c3bf1cdfa4c2", "batch_id": "NO-159040131155901488695376", - "part_instance_id":"PINO-34634534535", + "part_instance_id": "PINO-34634534535", "manufacturing_date": "2022-02-04T14:48:54.709Z", "manufacturing_country": "DEU", "manufacturer_part_id": "37754B7-76", - "customer_part_id": "37754B7-76", "classification": "component", - "name_at_manufacturer": "Sensor", - "name_at_customer": "Sensor" + "name_at_manufacturer": "Sensor" } ] } diff --git a/modules/sde-submodules/part-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/pap/steps/DigitalTwinsPartAsPlannedHandlerStep.java b/modules/sde-submodules/part-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/pap/steps/DigitalTwinsPartAsPlannedHandlerStep.java index 70dd331d8..8f34e4e9b 100644 --- a/modules/sde-submodules/part-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/pap/steps/DigitalTwinsPartAsPlannedHandlerStep.java +++ b/modules/sde-submodules/part-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/pap/steps/DigitalTwinsPartAsPlannedHandlerStep.java @@ -77,6 +77,10 @@ private PartAsPlanned doRun(PartAsPlanned partAsPlannedAspect) throws CsvHandler } else if (shellIds.size() == 1) { logDebug(String.format("Shell id found for '%s'", shellLookupRequest.toJsonString())); shellId = shellIds.stream().findFirst().orElse(null); + + digitalTwinsFacilitator.updateShellSpecificAssetIdentifiers(shellId, + digitalTwinsUtility.getSpecificAssetIds(getSpecificAssetIds(partAsPlannedAspect), partAsPlannedAspect.getBpnNumbers())); + logDebug(String.format("Shell id '%s'", shellId)); } else { throw new CsvHandlerDigitalTwinUseCaseException( diff --git a/modules/sde-submodules/part-site-information-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/psiap/steps/DigitalTwinsPartSiteInformationAsPlannedHandlerStep.java b/modules/sde-submodules/part-site-information-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/psiap/steps/DigitalTwinsPartSiteInformationAsPlannedHandlerStep.java index 2555513c1..ac6cbf64e 100644 --- a/modules/sde-submodules/part-site-information-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/psiap/steps/DigitalTwinsPartSiteInformationAsPlannedHandlerStep.java +++ b/modules/sde-submodules/part-site-information-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/psiap/steps/DigitalTwinsPartSiteInformationAsPlannedHandlerStep.java @@ -80,6 +80,11 @@ private PartSiteInformationAsPlanned doRun(PartSiteInformationAsPlanned partSite } else if (shellIds.size() == 1) { logDebug(String.format("Shell id found for '%s'", shellLookupRequest.toJsonString())); shellId = shellIds.stream().findFirst().orElse(null); + + digitalTwinsFacilitator.updateShellSpecificAssetIdentifiers(shellId, + digitalTwinsUtility.getSpecificAssetIds(getSpecificAssetIds(partSiteInformationAsPlannedAspect), + partSiteInformationAsPlannedAspect.getBpnNumbers())); + logDebug(String.format("Shell id '%s'", shellId)); } else { throw new CsvHandlerDigitalTwinUseCaseException( diff --git a/modules/sde-submodules/serial-part-typization/src/main/java/org/eclipse/tractusx/sde/submodels/spt/steps/DigitalTwinsAspectCsvHandlerUseCase.java b/modules/sde-submodules/serial-part-typization/src/main/java/org/eclipse/tractusx/sde/submodels/spt/steps/DigitalTwinsAspectCsvHandlerUseCase.java index 18ef9c5fa..be3984045 100644 --- a/modules/sde-submodules/serial-part-typization/src/main/java/org/eclipse/tractusx/sde/submodels/spt/steps/DigitalTwinsAspectCsvHandlerUseCase.java +++ b/modules/sde-submodules/serial-part-typization/src/main/java/org/eclipse/tractusx/sde/submodels/spt/steps/DigitalTwinsAspectCsvHandlerUseCase.java @@ -78,6 +78,8 @@ private Aspect doRun(Aspect aspect) throws CsvHandlerDigitalTwinUseCaseException } else if (shellIds.size() == 1) { logDebug(String.format("Shell id found for '%s'", shellLookupRequest.toJsonString())); shellId = shellIds.stream().findFirst().orElse(null); + digitalTwinsFacilitator.updateShellSpecificAssetIdentifiers(shellId, + digitalTwinsUtility.getSpecificAssetIds(getSpecificAssetIds(aspect), aspect.getBpnNumbers())); logDebug(String.format("Shell id '%s'", shellId)); } else { throw new CsvHandlerDigitalTwinUseCaseException( diff --git a/modules/sde-submodules/single-level-bom-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/slbap/steps/DigitalTwinsSingleLevelBoMAsPlannedHandlerStep.java b/modules/sde-submodules/single-level-bom-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/slbap/steps/DigitalTwinsSingleLevelBoMAsPlannedHandlerStep.java index cb382dbcc..2d2601f8a 100644 --- a/modules/sde-submodules/single-level-bom-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/slbap/steps/DigitalTwinsSingleLevelBoMAsPlannedHandlerStep.java +++ b/modules/sde-submodules/single-level-bom-as-planned/src/main/java/org/eclipse/tractusx/sde/submodels/slbap/steps/DigitalTwinsSingleLevelBoMAsPlannedHandlerStep.java @@ -80,6 +80,12 @@ private SingleLevelBoMAsPlanned doRun(SingleLevelBoMAsPlanned singleLevelBoMAsPl } else if (shellIds.size() == 1) { logDebug(String.format("Shell id found for '%s'", shellLookupRequest.toJsonString())); shellId = shellIds.stream().findFirst().orElse(null); + + digitalTwinsFacilitator.updateShellSpecificAssetIdentifiers(shellId, + digitalTwinsUtility.getSpecificAssetIds( + getSpecificAssetIdsForSingleLevel(singleLevelBoMAsPlannedAspect), + singleLevelBoMAsPlannedAspect.getBpnNumbers())); + logDebug(String.format("Shell id '%s'", shellId)); } else { throw new CsvHandlerDigitalTwinUseCaseException( @@ -145,14 +151,22 @@ private Map getSpecificAssetIds(PartAsPlanned partAsPlannedAspec } private ShellLookupRequest getShellLookupRequest(SingleLevelBoMAsPlanned singleLevelBoMAsPlannedAspect) { + ShellLookupRequest shellLookupRequest = new ShellLookupRequest(); - shellLookupRequest.addLocalIdentifier(CommonConstants.ASSET_LIFECYCLE_PHASE, CommonConstants.AS_PLANNED); - shellLookupRequest.addLocalIdentifier(CommonConstants.MANUFACTURER_PART_ID, - singleLevelBoMAsPlannedAspect.getParentManufacturerPartId()); - shellLookupRequest.addLocalIdentifier(CommonConstants.MANUFACTURER_ID, digitalTwinsUtility.getManufacturerId()); + getSpecificAssetIdsForSingleLevel(singleLevelBoMAsPlannedAspect).entrySet().stream() + .forEach(entry -> shellLookupRequest.addLocalIdentifier(entry.getKey(), entry.getValue())); return shellLookupRequest; } + + private Map getSpecificAssetIdsForSingleLevel(SingleLevelBoMAsPlanned singleLevelBoMAsPlannedAspect) { + Map specificIdentifiers = new HashMap<>(); + specificIdentifiers.put(CommonConstants.ASSET_LIFECYCLE_PHASE, CommonConstants.AS_PLANNED); + specificIdentifiers.put(CommonConstants.MANUFACTURER_PART_ID, + singleLevelBoMAsPlannedAspect.getParentManufacturerPartId()); + specificIdentifiers.put(CommonConstants.MANUFACTURER_ID, digitalTwinsUtility.getManufacturerId()); + return specificIdentifiers; + } private ShellDescriptorRequest getShellDescriptorRequest(PartAsPlanned partAsPlannedAspect) { diff --git a/modules/sde-submodules/single-level-usage-as-built/src/main/java/org/eclipse/tractusx/sde/submodels/sluab/steps/DigitalTwinsSingleLevelUsageAsBuiltCsvHandlerUseCase.java b/modules/sde-submodules/single-level-usage-as-built/src/main/java/org/eclipse/tractusx/sde/submodels/sluab/steps/DigitalTwinsSingleLevelUsageAsBuiltCsvHandlerUseCase.java index 6897de509..112bffbd9 100644 --- a/modules/sde-submodules/single-level-usage-as-built/src/main/java/org/eclipse/tractusx/sde/submodels/sluab/steps/DigitalTwinsSingleLevelUsageAsBuiltCsvHandlerUseCase.java +++ b/modules/sde-submodules/single-level-usage-as-built/src/main/java/org/eclipse/tractusx/sde/submodels/sluab/steps/DigitalTwinsSingleLevelUsageAsBuiltCsvHandlerUseCase.java @@ -80,6 +80,12 @@ private SingleLevelUsageAsBuilt doRun(SingleLevelUsageAsBuilt aspectSingleLevelU } else if (shellIds.size() == 1) { logDebug(String.format("Shell id found for '%s'", shellLookupRequest.toJsonString())); shellId = shellIds.stream().findFirst().orElse(null); + + digitalTwinsFacilitator.updateShellSpecificAssetIdentifiers(shellId, + digitalTwinsUtility.getSpecificAssetIds( + getSpecificAssetIdsForSingleLevel(aspectSingleLevelUsageAsBuilt), + aspectSingleLevelUsageAsBuilt.getBpnNumbers())); + logDebug(String.format("Shell id '%s'", shellId)); } else { throw new CsvHandlerDigitalTwinUseCaseException( @@ -143,18 +149,29 @@ private String createShellDescriptor(SingleLevelUsageAsBuilt aspectSingleLevelUs private ShellLookupRequest getShellLookupRequest(SingleLevelUsageAsBuilt aspectSingleLevelUsageAsBuilt) { ShellLookupRequest shellLookupRequest = new ShellLookupRequest(); - shellLookupRequest.addLocalIdentifier(CommonConstants.PART_INSTANCE_ID, + + getSpecificAssetIdsForSingleLevel(aspectSingleLevelUsageAsBuilt).entrySet().stream() + .forEach(entry -> shellLookupRequest.addLocalIdentifier(entry.getKey(), entry.getValue())); + + return shellLookupRequest; + } + + private Map getSpecificAssetIdsForSingleLevel( + SingleLevelUsageAsBuilt aspectSingleLevelUsageAsBuilt) { + + Map specificIdentifiers = new HashMap<>(); + + specificIdentifiers.put(CommonConstants.PART_INSTANCE_ID, aspectSingleLevelUsageAsBuilt.getParentPartInstanceId()); - shellLookupRequest.addLocalIdentifier(CommonConstants.MANUFACTURER_PART_ID, + specificIdentifiers.put(CommonConstants.MANUFACTURER_PART_ID, aspectSingleLevelUsageAsBuilt.getParentManufacturerPartId()); - shellLookupRequest.addLocalIdentifier(CommonConstants.MANUFACTURER_ID, digitalTwinsUtility.getManufacturerId()); + specificIdentifiers.put(CommonConstants.MANUFACTURER_ID, digitalTwinsUtility.getManufacturerId()); if (aspectSingleLevelUsageAsBuilt.hasOptionalParentIdentifier()) { - shellLookupRequest.addLocalIdentifier(aspectSingleLevelUsageAsBuilt.getParentOptionalIdentifierKey(), + specificIdentifiers.put(aspectSingleLevelUsageAsBuilt.getParentOptionalIdentifierKey(), aspectSingleLevelUsageAsBuilt.getParentOptionalIdentifierValue()); } - - return shellLookupRequest; + return specificIdentifiers; } private Map getSpecificAssetIds(Aspect aspect) { diff --git a/modules/sde-submodules/submodules.md b/modules/sde-submodules/submodules.md index dad23f05b..a88bb663d 100644 --- a/modules/sde-submodules/submodules.md +++ b/modules/sde-submodules/submodules.md @@ -9,7 +9,7 @@ Currently SDE supports below submodels. ### Supported Models #### [serial-part-typization in Version 1.1.1] -#### [batch in Version 1.0.2] +#### [batch in Version 2.0.0] #### [assembly-part-relationship in Version 1.1.1] #### [partAsPlanned in Version 1.0.0] #### [singleLevelBoMAsPlanned in Version 1.0.1] @@ -36,7 +36,7 @@ Once your maven module ready just do the clean build and install so submodel wil [serial-part-typization in Version 1.1.1]: serial-part-typization/serial-part-typization.md -[batch in Version 1.0.2]: batch/batch.md +[batch in Version 2.0.0]: batch/batch.md [assembly-part-relationship in Version 1.1.1]: assembly-part-relationship/assembly-part-relationship.md [partAsPlanned in Version 1.0.0]: part-as-planned/part-as-planned.md [singleLevelBoMAsPlanned in Version 1.0.1]: single-level-bom-as-planned/single-level-bom-as-planned.md