diff --git a/CHANGELOG.md b/CHANGELOG.md index 2af6ebd79..a5731fde5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Refactored/Updated SingleLevelUsageAsBuilt maven module to support multi version. - Refactored/Updated PCF maven module to support multi version. - Added new flyway files. -- Supporting new submodel Singlelevelbomasplanned +- Supporting new submodel Singlelevelbomasplanned. +- Support EDC 7. +- Added new files for digital twin access rule support. ### Fixed - Remove garbage character from 'edc_request_template' path. Fixed [#147](https://github.com/eclipse-tractusx/managed-simple-data-exchanger-backend/issues/147). diff --git a/modules/pcf-exchange/src/main/java/org/eclipse/tractusx/sde/pcfexchange/service/impl/ProxyRequestInterface.java b/modules/pcf-exchange/src/main/java/org/eclipse/tractusx/sde/pcfexchange/service/impl/ProxyRequestInterface.java index 5ece7ab33..55c535485 100644 --- a/modules/pcf-exchange/src/main/java/org/eclipse/tractusx/sde/pcfexchange/service/impl/ProxyRequestInterface.java +++ b/modules/pcf-exchange/src/main/java/org/eclipse/tractusx/sde/pcfexchange/service/impl/ProxyRequestInterface.java @@ -80,7 +80,7 @@ public void requestToProviderForPCFValue(String productId, StringBuilder sb, Str pcfpushEnpoint = new URI(edrToken.getEndpoint()); Map header = new HashMap<>(); - header.put(edrToken.getAuthKey(), edrToken.getAuthCode()); + header.put("authorization", edrToken.getAuthorization()); // Send request to data provider for PCF value push pcfExchangeProxy.getPcfByProduct(pcfpushEnpoint, header, manufacturerId, @@ -136,7 +136,7 @@ private void sendNotification(JsonObject calculatedPCFValue, String productId, S edrToken.getEndpoint() + SLASH_DELIMETER + PRODUCT_IDS + SLASH_DELIMETER + productId); Map header = new HashMap<>(); - header.put(edrToken.getAuthKey(), edrToken.getAuthCode()); + header.put("authorization", edrToken.getAuthorization()); pcfExchangeProxy.uploadPcfSubmodel(pcfpushEnpoint, header, bpnNumber, requestId, message, jsonObjectMapper.gsonObjectToJsonNode(calculatedPCFValue)); @@ -161,4 +161,4 @@ private void sendNotification(JsonObject calculatedPCFValue, String productId, S -} +} \ No newline at end of file diff --git a/modules/sde-core/src/main/java/org/eclipse/tractusx/sde/core/submodel/executor/step/DigitalTwinLookUpInRegistry.java b/modules/sde-core/src/main/java/org/eclipse/tractusx/sde/core/submodel/executor/step/DigitalTwinLookUpInRegistry.java index fe3ba5a5b..524760903 100644 --- a/modules/sde-core/src/main/java/org/eclipse/tractusx/sde/core/submodel/executor/step/DigitalTwinLookUpInRegistry.java +++ b/modules/sde-core/src/main/java/org/eclipse/tractusx/sde/core/submodel/executor/step/DigitalTwinLookUpInRegistry.java @@ -143,7 +143,7 @@ private String lookUpChildTwin(Integer rowIndex, ShellLookupRequest shellLookupR try { Map header = new HashMap<>(); - header.put(edrToken.getAuthKey(), edrToken.getAuthCode()); + header.put("authorization", edrToken.getAuthorization()); header.put("Edc-Bpn", bpnForRemoteRegistry); ShellLookupResponse shellLookup = eDCDigitalTwinProxyForLookUp.shellLookup(new URI(endpoint), @@ -197,4 +197,4 @@ private String encodeShellIdBase64Utf8(String shellId) { return Base64.getUrlEncoder().encodeToString(shellId.getBytes()); } -} +} \ No newline at end of file diff --git a/modules/sde-core/src/main/java/org/eclipse/tractusx/sde/core/submodel/executor/step/SubmoduleResponseHandler.java b/modules/sde-core/src/main/java/org/eclipse/tractusx/sde/core/submodel/executor/step/SubmoduleResponseHandler.java index b0309111b..643a1d59d 100644 --- a/modules/sde-core/src/main/java/org/eclipse/tractusx/sde/core/submodel/executor/step/SubmoduleResponseHandler.java +++ b/modules/sde-core/src/main/java/org/eclipse/tractusx/sde/core/submodel/executor/step/SubmoduleResponseHandler.java @@ -61,14 +61,12 @@ public JsonObject mapJsonbjectToFormatedResponse(JsonObject jsonObject) { removeNullAndEmptyElementsFromJson(removeNullAndEmptyElementsFromJson(valueReplacer))); } - @SuppressWarnings("deprecation") public static String removeNullAndEmptyElementsFromJson(String jsonString) { if (jsonString == null) { return jsonString; } try { - JsonParser parser = new JsonParser(); - JsonElement element = parser.parse(jsonString); + JsonElement element = JsonParser.parseString(jsonString); cleanByTree(element); jsonString = new GsonBuilder().disableHtmlEscaping().create().toJson(element); return jsonString; @@ -78,8 +76,8 @@ public static String removeNullAndEmptyElementsFromJson(String jsonString) { } private static void cleanByTree(JsonElement e1) { - if (e1 == null || e1.isJsonNull()) { - } else if (e1.isJsonArray()) { + if (e1 == null || e1.isJsonNull()) {} + else if (e1.isJsonArray()) { for (Iterator it = e1.getAsJsonArray().iterator(); it.hasNext();) { extracted(it); } @@ -126,4 +124,4 @@ private static void extracted(Iterator it) { } } -} +} \ No newline at end of file diff --git a/modules/sde-core/src/main/resources/flyway/V32__Alter_pcf_aspect_Tables.sql b/modules/sde-core/src/main/resources/flyway/V32__Alter_pcf_aspect_Tables.sql new file mode 100644 index 000000000..4d3f7a1b5 --- /dev/null +++ b/modules/sde-core/src/main/resources/flyway/V32__Alter_pcf_aspect_Tables.sql @@ -0,0 +1,31 @@ +/******************************************************************************** + * Copyright (c) 2024 T-Systems International GmbH + * 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 + ********************************************************************************/ + +DO $$ +BEGIN + IF EXISTS (select 1 as foundtable from pg_tables WHERE tablename = 'pcf_aspect') + THEN + DELETE FROM pcf_aspect WHERE id IN (SELECT id FROM (SELECT id, ROW_NUMBER() OVER( PARTITION BY productid ORDER BY id ) AS row_num FROM pcf_aspect ) t WHERE t.row_num > 1); +END IF; +END $$; + +ALTER TABLE IF EXISTS pcf_aspect DROP CONSTRAINT IF EXISTS "pcf_aspect_un"; + +ALTER TABLE IF EXISTS pcf_aspect ADD CONSTRAINT pcf_aspect_un UNIQUE (productid); diff --git a/modules/sde-core/src/main/resources/flyway/V33__Alter_all_aspect_Tables_fordt_access_ids.sql b/modules/sde-core/src/main/resources/flyway/V33__Alter_all_aspect_Tables_fordt_access_ids.sql new file mode 100644 index 000000000..b8390a32b --- /dev/null +++ b/modules/sde-core/src/main/resources/flyway/V33__Alter_all_aspect_Tables_fordt_access_ids.sql @@ -0,0 +1,47 @@ +/******************************************************************************** + * Copyright (c) 2024 T-Systems International GmbH + * 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 + ********************************************************************************/ + +ALTER TABLE IF EXISTS aspect ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS aspect_relationship ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS batch ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS batch_v_300 ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS part_as_planned ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS part_site_information_as_planned ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS parttypeinformation_v_100 ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS pcf_aspect ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS serialpart_v_300 ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS single_level_bom_as_planned ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS single_level_bom_as_planned_v_300 ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS single_level_bom_asbuilt_v_300 ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS single_level_usage_as_built ADD IF NOT EXISTS shell_access_rule_ids text NULL; + +ALTER TABLE IF EXISTS single_level_usage_as_built_v_300 ADD IF NOT EXISTS shell_access_rule_ids text NULL; diff --git a/modules/sde-external-services/.DS_Store b/modules/sde-external-services/.DS_Store deleted file mode 100644 index 8d7b03a33..000000000 Binary files a/modules/sde-external-services/.DS_Store and /dev/null differ diff --git a/modules/sde-external-services/bpn-discovery/src/main/java/org/eclipse/tractusx/sde/bpndiscovery/handler/BPNDiscoveryUseCaseHandler.java b/modules/sde-external-services/bpn-discovery/src/main/java/org/eclipse/tractusx/sde/bpndiscovery/handler/BPNDiscoveryUseCaseHandler.java index eda567ec9..b176dc201 100644 --- a/modules/sde-external-services/bpn-discovery/src/main/java/org/eclipse/tractusx/sde/bpndiscovery/handler/BPNDiscoveryUseCaseHandler.java +++ b/modules/sde-external-services/bpn-discovery/src/main/java/org/eclipse/tractusx/sde/bpndiscovery/handler/BPNDiscoveryUseCaseHandler.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2023, 2024 T-Systems International GmbH - * Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2023,2024 T-Systems International GmbH + * Copyright (c) 2023,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -40,6 +40,7 @@ import com.google.gson.JsonObject; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; @Service @RequiredArgsConstructor @@ -64,19 +65,9 @@ public void run(Map input) throws ServiceException { } } + @SneakyThrows @Override public JsonNode run(Integer rowIndex, ObjectNode jsonObject, String processId, PolicyModel policy) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void delete(Integer rowIndex, JsonObject jsonObject, String delProcessId, String refProcessId) { - // TODO Auto-generated method stub - - } - - public void run(JsonNode jsonObject) throws ServiceException { if (StringUtils.isBlank( JsonObjectUtility.getValueFromJsonObjectAsString(jsonObject, SubmoduleCommonColumnsConstant.UPDATED))) { try { @@ -94,8 +85,15 @@ public void run(JsonNode jsonObject) throws ServiceException { throw new ServiceException("Exception in BPN Discovery creation : " + e.getMessage()); } } + return jsonObject; } + @Override + public void delete(Integer rowIndex, JsonObject jsonObject, String delProcessId, String refProcessId) { + // Nothing to do with bpn discovery for delete + } + + private Map generateBPNDiscoveryIdentifiersIds(JsonNode jsonObject) { return getBPNDiscoverySpecsOfModel().entrySet().stream().map(entry -> { String value = JsonObjectUtility.getValueFromJsonObjectAsString(jsonObject, entry.getValue().getAsString()); @@ -107,4 +105,4 @@ private Map generateBPNDiscoveryIdentifiersIds(JsonNode jsonObje } -} +} \ No newline at end of file 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 4fc3fcb54..edb53fe48 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 @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2024 T-Systems International GmbH - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -24,6 +24,7 @@ import java.util.List; import java.util.Optional; +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; @@ -32,11 +33,14 @@ import org.eclipse.tractusx.sde.digitaltwins.entities.response.ShellLookupResponse; import org.eclipse.tractusx.sde.digitaltwins.entities.response.SubModelListResponse; import org.eclipse.tractusx.sde.digitaltwins.gateways.external.DigitalTwinsFeignClient; +import org.eclipse.tractusx.sde.digitaltwins.gateways.external.IAccessRuleManagementApi; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import com.fasterxml.jackson.databind.JsonNode; + import feign.FeignException; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; @@ -48,7 +52,7 @@ public class DigitalTwinsFacilitator { private final DigitalTwinsFeignClient digitalTwinsFeignClient; - + @Value(value = "${manufacturerId}") private String manufacturerId; @@ -57,6 +61,8 @@ public class DigitalTwinsFacilitator { private final DigitalTwinsUtility digitalTwinsUtility; + private final IAccessRuleManagementApi iAccessRuleManagementApi; + @SneakyThrows public List shellLookup(ShellLookupRequest request) throws ServiceException { @@ -148,6 +154,22 @@ public ShellDescriptorResponse createShellDescriptor(ShellDescriptorRequest requ } return responseBody; } + + public JsonNode createAccessControlsRule(String edcBpn, JsonNode request) { + return iAccessRuleManagementApi.createAccessControlsRule(edcBpn, request); + } + + public void updateAccessControlsRule(String ruleId, String edcBpn, JsonNode request) { + iAccessRuleManagementApi.updateAccessControlsRule(ruleId, edcBpn, request); + } + + public JsonNode getAccessControlsRule(String ruleId, String edcBpn) { + return iAccessRuleManagementApi.getAccessControlsRuleById(ruleId, edcBpn); + } + + public void deleteAccessControlsRule(String ruleId, String edcBpn) { + iAccessRuleManagementApi.deleteAccessControlsRule(ruleId, edcBpn); + } public void updateShellDetails(String shellId, ShellDescriptorRequest aasDescriptorRequest, CreateSubModelRequest createSubModelRequest) { @@ -169,7 +191,11 @@ public void updateShellDetails(String shellId, ShellDescriptorRequest aasDescrip if (shellDescriptorResponse != null) { - shellDescriptorResponse.getSubmodelDescriptors().forEach(e -> + shellDescriptorResponse.getSubmodelDescriptors() + .stream() + .filter(ele -> createSubModelRequest == null || (createSubModelRequest != null + && !ele.getIdShort().equals(createSubModelRequest.getIdShort()))) + .forEach(e -> aasDescriptorRequest.getSubmodelDescriptors().add(CreateSubModelRequest.builder() .id(e.getId()) .idShort(e.getIdShort()) @@ -178,10 +204,15 @@ public void updateShellDetails(String shellId, ShellDescriptorRequest aasDescrip .description(e.getDescription()) .build()) ); - } + if (StringUtils.isBlank(aasDescriptorRequest.getIdShort()) && (shellDescriptorResponse != null + && StringUtils.isNotBlank(shellDescriptorResponse.getIdShort()))) { + aasDescriptorRequest.setIdShort(shellDescriptorResponse.getIdShort()); + } + aasDescriptorRequest.setId(shellId); + log.debug(aasDescriptorRequest.toJsonString()); ResponseEntity updateShellDescriptorByShellId = digitalTwinsFeignClient .updateShellDescriptorByShellId(digitalTwinsUtility.encodeValueAsBase64Utf8(shellId), 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 d0d19784a..6558e9520 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 @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2024 T-Systems International GmbH - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -47,47 +47,47 @@ public interface DigitalTwinsFeignClient { @PostMapping KeycloakJWTTokenResponse readAuthToken(URI url, @RequestBody MultiValueMap body); - @PostMapping(path = "${digital-twins.registry.uri:/api/v3.0}/shell-descriptors") + @PostMapping(path = "${digital-twins.registry.uri:/api/v3}/shell-descriptors") ResponseEntity createShellDescriptor(@RequestBody ShellDescriptorRequest request); - @GetMapping(path = "${digital-twins.registry.uri:/api/v3.0}/shell-descriptors/{aasIdentifier}") + @GetMapping(path = "${digital-twins.registry.uri:/api/v3}/shell-descriptors/{aasIdentifier}") ResponseEntity getShellDescriptorByShellId(@PathVariable("aasIdentifier") String shellId, @RequestHeader("Edc-Bpn") String edcBpn); - @PutMapping(path = "${digital-twins.registry.uri:/api/v3.0}/shell-descriptors/{aasIdentifier}") + @PutMapping(path = "${digital-twins.registry.uri:/api/v3}/shell-descriptors/{aasIdentifier}") ResponseEntity updateShellDescriptorByShellId(@PathVariable("aasIdentifier") String shellId, @RequestHeader("Edc-Bpn") String edcBpn, @RequestBody ShellDescriptorRequest request); - @DeleteMapping(path = "${digital-twins.registry.uri:/api/v3.0}/shell-descriptors/{aasIdentifier}") + @DeleteMapping(path = "${digital-twins.registry.uri:/api/v3}/shell-descriptors/{aasIdentifier}") ResponseEntity deleteShell(@PathVariable("assetIds") String shellId); - @PostMapping(path = "${digital-twins.registry.uri:/api/v3.0}/shell-descriptors/{aasIdentifier}/submodel-descriptors") + @PostMapping(path = "${digital-twins.registry.uri:/api/v3}/shell-descriptors/{aasIdentifier}/submodel-descriptors") ResponseEntity createSubModel(@PathVariable("aasIdentifier") String shellId, @RequestBody CreateSubModelRequest request, @RequestHeader("Edc-Bpn") String edcBpn); - @PutMapping(path = "${digital-twins.registry.uri:/api/v3.0}/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") + @PutMapping(path = "${digital-twins.registry.uri:/api/v3}/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") ResponseEntity updateSubModel(@PathVariable("aasIdentifier") String shellId, @PathVariable("submodelIdentifier") String submodelIdentifier, @RequestBody CreateSubModelRequest request, @RequestHeader("Edc-Bpn") String edcBpn); - @GetMapping(path = "${digital-twins.registry.uri:/api/v3.0}/shell-descriptors/{aasIdentifier}/submodel-descriptors") + @GetMapping(path = "${digital-twins.registry.uri:/api/v3}/shell-descriptors/{aasIdentifier}/submodel-descriptors") ResponseEntity getSubModels(@PathVariable("aasIdentifier") String shellId, @RequestHeader("Edc-Bpn") String edcBpn); - @DeleteMapping(path = "${digital-twins.registry.uri:/api/v3.0}/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") + @DeleteMapping(path = "${digital-twins.registry.uri:/api/v3}/shell-descriptors/{aasIdentifier}/submodel-descriptors/{submodelIdentifier}") ResponseEntity deleteSubmodelfromShellById(@PathVariable("aasIdentifier") String shellId, @PathVariable("submodelIdentifier") String submodelIdentifier); - @GetMapping(path = "${digital-twins.registry.lookup.uri:/api/v3.0}/lookup/shells") + @GetMapping(path = "${digital-twins.registry.lookup.uri:/api/v3}/lookup/shells") ResponseEntity shellLookup(@RequestParam("assetIds") List assetIds, @RequestHeader("Edc-Bpn") String edcBpn); - @PostMapping(path = "${digital-twins.registry.lookup.uri:/api/v3.0}/lookup/shells/{shellId}") + @PostMapping(path = "${digital-twins.registry.lookup.uri:/api/v3}/lookup/shells/{shellId}") ResponseEntity> createShellSpecificAttributes(@PathVariable("shellId") String shellId, @RequestHeader("Edc-Bpn") String edcBpn, @RequestBody List specificAssetIds); - @DeleteMapping(path = "${digital-twins.registry.lookup.uri:/api/v3.0}/lookup/shells/{shellId}") + @DeleteMapping(path = "${digital-twins.registry.lookup.uri:/api/v3}/lookup/shells/{shellId}") ResponseEntity deleteShellSpecificAttributes(@PathVariable("assetIds") String shellId, @RequestHeader("Edc-Bpn") String edcBpn); -} +} \ No newline at end of file diff --git a/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/gateways/external/IAccessRuleManagementApi.java b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/gateways/external/IAccessRuleManagementApi.java new file mode 100644 index 000000000..84af9a2b2 --- /dev/null +++ b/modules/sde-external-services/digital-twins/src/main/java/org/eclipse/tractusx/sde/digitaltwins/gateways/external/IAccessRuleManagementApi.java @@ -0,0 +1,54 @@ +/******************************************************************************** + * Copyright (c) 2024 T-Systems International GmbH + * 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.sde.digitaltwins.gateways.external; + +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; + +import com.fasterxml.jackson.databind.JsonNode; + +@FeignClient(value = "IAccessRuleManagementApi", url = "${digital-twins.hostname:default}", configuration = DigitalTwinsFeignClientConfiguration.class) +public interface IAccessRuleManagementApi { + + @GetMapping(path = "${digital-twins.registry.uri:/api/v3}/access-controls/rules") + public JsonNode getAccessControlsRules(@RequestHeader("Edc-Bpn") String edcBpn); + + @PostMapping(path = "${digital-twins.registry.uri:/api/v3}/access-controls/rules") + public JsonNode createAccessControlsRule(@RequestHeader("Edc-Bpn") String edcBpn, @RequestBody JsonNode request); + + @GetMapping(path = "${digital-twins.registry.uri:/api/v3}/access-controls/rules/{ruleId}") + public JsonNode getAccessControlsRuleById(@PathVariable("ruleId") String ruleId, + @RequestHeader("Edc-Bpn") String edcBpn); + + @PutMapping(path = "${digital-twins.registry.uri:/api/v3}/access-controls/rules/{ruleId}") + public JsonNode updateAccessControlsRule(@PathVariable("ruleId") String ruleId, + @RequestHeader("Edc-Bpn") String edcBpn, @RequestBody JsonNode request); + + @DeleteMapping(path = "${digital-twins.registry.uri:/api/v3}/access-controls/rules/{ruleId}") + public void deleteAccessControlsRule(@PathVariable("ruleId") String ruleId, + @RequestHeader("Edc-Bpn") String edcBpn); + +} \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/api/EDRApiProxy.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/api/EDRApiProxy.java index 45e203589..bfa92f0ad 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/api/EDRApiProxy.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/api/EDRApiProxy.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2023 T-Systems International GmbH - * Copyright (c) 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2023,2024 T-Systems International GmbH + * Copyright (c) 2023,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -37,20 +37,22 @@ import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; +import com.fasterxml.jackson.databind.JsonNode; + @FeignClient(value = "EDRApiProxy", url = "placeholder") public interface EDRApiProxy { - @PostMapping(path = "/edrs", consumes = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(path = "/v2/edrs", consumes = MediaType.APPLICATION_JSON_VALUE) AcknowledgementId edrCacheCreate(URI url, @RequestBody ContractNegotiations requestBody, @RequestHeader Map requestHeader); - @GetMapping(path = "/edrs", consumes = MediaType.APPLICATION_JSON_VALUE) - List getEDRCachedByAsset(URI url, @RequestParam("assetId") String assetId, + @PostMapping(path = "/v2/edrs/request", consumes = MediaType.APPLICATION_JSON_VALUE) + List getEDRCachedByAsset(URI url, @RequestBody JsonNode requestBody, @RequestHeader Map requestHeader); - @GetMapping(path = "/edrs/{transferProcessId}") + @GetMapping(path = "/v2/edrs/{transferProcessId}/dataaddress") EDRCachedByIdResponse getEDRCachedByTransferProcessId(URI url, - @PathVariable("transferProcessId") String transferProcessId, + @PathVariable("transferProcessId") String transferProcessId, @RequestParam("auto_refresh") boolean autoRefresh, @RequestHeader Map requestHeader); @GetMapping diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/constants/EDCAssetConstant.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/constants/EDCAssetConstant.java index 40c37e37d..bdb586606 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/constants/EDCAssetConstant.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/constants/EDCAssetConstant.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2024 T-Systems International GmbH - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -40,6 +40,7 @@ public final class EDCAssetConstant { public static final String DATA_CORE_PCF_EXCHANGE_ENPOINT_TYPE = "data.pcf.exchangeEndpoint"; public static final String CX_TAXO_PREFIX = "cx-taxo:"; + public static final String TX_AUTH_PREFIX = "tx-auth:"; public static final String DCT_TYPE = "dct:type"; public static final String AAS_SEMANTICS_SEMANTIC_ID = "aas-semantics:semanticId"; @@ -52,6 +53,8 @@ public final class EDCAssetConstant { public static final String ASSET_PROP_VERSION_VALUE = "1.0.0"; public static final String TYPE = "HttpData"; + + public static final String ASSET_PREFIX = ""; private EDCAssetConstant() { diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/policies/PolicyRequest.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/policies/PolicyRequest.java index 335e0bcc6..ea4733750 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/policies/PolicyRequest.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/entities/request/policies/PolicyRequest.java @@ -1,7 +1,7 @@ /******************************************************************************** * Copyright (c) 2022 BMW GmbH - * Copyright (c) 2022, 2024 T-Systems International GmbH - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -47,8 +47,15 @@ public class PolicyRequest { @JsonProperty("@type") @Builder.Default - private String type = "Policy"; - + private String type = "Set"; + + @JsonProperty("@context") + @Builder.Default + private String context = "http://www.w3.org/ns/odrl.jsonld"; + + @JsonProperty("@id") + private String id; + @JsonProperty("odrl:permission") private Object permissions; @@ -61,7 +68,11 @@ public class PolicyRequest { private Map extensibleProperties; @JsonProperty("odrl:target") - private String target; + private Map target; + + @JsonProperty("odrl:assigner") + private Map assigner; + @SneakyThrows public String toJsonString() { diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/EDRRequestHelper.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/EDRRequestHelper.java index ef09394bd..af78d3da3 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/EDRRequestHelper.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/facilitator/EDRRequestHelper.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2023, 2024 T-Systems International GmbH - * Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2023,2024 T-Systems International GmbH + * Copyright (c) 2023,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -34,6 +34,9 @@ import org.eclipse.tractusx.sde.edc.model.edr.EDRCachedResponse; import org.springframework.stereotype.Service; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -50,11 +53,11 @@ public class EDRRequestHelper extends AbstractEDCStepsHelper { public String edrRequestInitiate(String providerUrl, String providerId, String offerId, String assetId, ActionRequest action, Map extensibleProperty) { - ContractNegotiations contractNegotiations = contractMapper - .prepareContractNegotiations(providerUrl, offerId, assetId, providerId, action); - + ContractNegotiations contractNegotiations = contractMapper.prepareContractNegotiations(providerUrl, offerId, + assetId, providerId, action); + log.info(contractNegotiations.toJsonString()); - + AcknowledgementId acknowledgementId = edrApiProxy.edrCacheCreate(new URI(consumerHostWithDataPath), contractNegotiations, getAuthHeader()); return acknowledgementId.getId(); @@ -62,21 +65,41 @@ public String edrRequestInitiate(String providerUrl, String providerId, String o @SneakyThrows public List getEDRCachedByAsset(String assetId) { - return edrApiProxy.getEDRCachedByAsset(new URI(consumerHostWithDataPath), assetId, getAuthHeader()); + String requestbody = """ + { + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@type": "QuerySpec", + "offset": 0, + "limit": 10, + "sortOrder": "DESC", + "sortField": "assetId", + "filterExpression": [ + { + "operandLeft": "assetId", + "operator": "=", + "operandRight": "%s" + } + ] + } + """; + JsonNode requestBody = new ObjectMapper().readTree(String.format(requestbody, assetId)); + + return edrApiProxy.getEDRCachedByAsset(new URI(consumerHostWithDataPath), requestBody, getAuthHeader()); } @SneakyThrows public EDRCachedByIdResponse getEDRCachedByTransferProcessId(String transferProcessId) { - return edrApiProxy.getEDRCachedByTransferProcessId(new URI(consumerHostWithDataPath), transferProcessId, + return edrApiProxy.getEDRCachedByTransferProcessId(new URI(consumerHostWithDataPath), transferProcessId, true, getAuthHeader()); } @SneakyThrows public Object getDataFromProvider(EDRCachedByIdResponse authorizationToken, String endpoint) { Map authHeader = new HashMap<>(); - authHeader.put(authorizationToken.getAuthKey(), authorizationToken.getAuthCode()); - return edrApiProxy.getActualDataFromProviderDataPlane(new URI(endpoint), - authHeader); + authHeader.put("authorization", authorizationToken.getAuthorization()); + return edrApiProxy.getActualDataFromProviderDataPlane(new URI(endpoint), authHeader); } } \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/mapper/ContractMapper.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/mapper/ContractMapper.java index 77dc459c2..64702cbf2 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/mapper/ContractMapper.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/mapper/ContractMapper.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2023 T-Systems International GmbH - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -20,10 +20,11 @@ package org.eclipse.tractusx.sde.edc.mapper; +import java.util.Map; + import org.eclipse.tractusx.sde.edc.entities.request.policies.ActionRequest; import org.eclipse.tractusx.sde.edc.entities.request.policies.PolicyRequest; import org.eclipse.tractusx.sde.edc.model.contractnegotiation.ContractNegotiations; -import org.eclipse.tractusx.sde.edc.model.contractnegotiation.Offer; import org.springframework.stereotype.Component; import lombok.RequiredArgsConstructor; @@ -36,20 +37,18 @@ public class ContractMapper { private final ContractPolicyMapper contractPolicyMapper; @SneakyThrows - public ContractNegotiations prepareContractNegotiations(String providerProtocolUrl, String offerId, String assetId, String provider, - ActionRequest action) { - + public ContractNegotiations prepareContractNegotiations(String providerProtocolUrl, String offerId, String assetId, + String provider, ActionRequest action) { + PolicyRequest policy = contractPolicyMapper.preparePolicy(assetId, action); - Offer offer = Offer.builder().assetId(assetId).offerId(offerId).policy(policy).build(); + policy.setId(offerId); + policy.setAssigner(Map.of("@id", provider)); return ContractNegotiations.builder() .connectorAddress(providerProtocolUrl) - .connectorId(provider) - .providerId(provider) .protocol("dataspace-protocol-http") - .offer(offer) + .policy(policy) .build(); - } -} +} \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/mapper/ContractPolicyMapper.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/mapper/ContractPolicyMapper.java index f6b1d87e8..3764cbdf6 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/mapper/ContractPolicyMapper.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/mapper/ContractPolicyMapper.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2024 T-Systems International GmbH - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.eclipse.tractusx.sde.edc.entities.request.policies.ActionRequest; import org.eclipse.tractusx.sde.edc.entities.request.policies.PermissionRequest; @@ -45,8 +46,8 @@ public PolicyRequest preparePolicy(String assetId, ActionRequest action) { if (!permissions.isEmpty()) permissionObj = permissions.get(0); - return PolicyRequest.builder().type("odrl:Set") - .target(assetId) + return PolicyRequest.builder().type("http://www.w3.org/ns/odrl/2/Offer") + .target(Map.of("@id",assetId)) .permissions(permissionObj) .prohibitions(new ArrayList<>()) .obligations(new ArrayList<>()).build(); diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/contractnegotiation/ContractNegotiations.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/contractnegotiation/ContractNegotiations.java index a1e9c11dc..fe812dcf6 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/contractnegotiation/ContractNegotiations.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/contractnegotiation/ContractNegotiations.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2024 T-Systems International GmbH - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -22,11 +22,13 @@ import java.util.Map; +import org.eclipse.tractusx.sde.edc.entities.request.policies.PolicyRequest; + 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 com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Builder; @@ -44,23 +46,19 @@ public class ContractNegotiations { @JsonProperty("@context") @Builder.Default - private Map context = Map.of("odrl", "http://www.w3.org/ns/odrl/2/"); + private Map context = Map.of("odrl", "http://www.w3.org/ns/odrl/2/", + "edc", "https://w3id.org/edc/v0.0.1/ns/"); @JsonProperty("@type") @Builder.Default - private String type = "NegotiationInitiateRequestDto"; + private String type = "ContractRequest"; @JsonProperty("counterPartyAddress") private String connectorAddress; private String protocol; - @JsonProperty("counterPartyId") - private String connectorId; - - private String providerId; - - private Offer offer; + private PolicyRequest policy; @SneakyThrows public String toJsonString() { diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/contractoffers/ContractOfferRequestFactory.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/contractoffers/ContractOfferRequestFactory.java index 78287e328..ed5c25f35 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/contractoffers/ContractOfferRequestFactory.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/contractoffers/ContractOfferRequestFactory.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2024 T-Systems International GmbH - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -32,7 +32,7 @@ public class ContractOfferRequestFactory { @SneakyThrows - public ObjectNode getContractOfferRequest(String providerUrl, Integer limit, Integer offset, + public ObjectNode getContractOfferRequest(String providerUrl, String counterPartyId, Integer limit, Integer offset, String filterExpression) { if (!StringUtils.isBlank(filterExpression)) @@ -45,6 +45,7 @@ public ObjectNode getContractOfferRequest(String providerUrl, Integer limit, Int "@context": {}, "protocol": "dataspace-protocol-http", "counterPartyAddress": "%s", + "counterPartyId":"%s", "querySpec": { "offset": %s, "limit": %s @@ -52,7 +53,7 @@ public ObjectNode getContractOfferRequest(String providerUrl, Integer limit, Int } } """; - String jsonString = String.format(formatSchema, providerUrl, offset, limit, + String jsonString = String.format(formatSchema, providerUrl, counterPartyId, offset, limit, filterExpression); return (ObjectNode) new ObjectMapper().readTree(jsonString); diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/edr/EDRCachedByIdResponse.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/edr/EDRCachedByIdResponse.java index 85321885c..4c562ac72 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/edr/EDRCachedByIdResponse.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/edr/EDRCachedByIdResponse.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2023, 2024 T-Systems International GmbH - * Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2023,2024 T-Systems International GmbH + * Copyright (c) 2023,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -43,16 +43,25 @@ public class EDRCachedByIdResponse { @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "type") private String type; - @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "authCode") - private String authCode; + @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "authorization") + private String authorization; @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "endpoint") private String endpoint; - @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "id") - private String id; + @JsonProperty(EDCAssetConstant.TX_AUTH_PREFIX + "refreshEndpoint") + private String refreshEndpoint; + + @JsonProperty(EDCAssetConstant.TX_AUTH_PREFIX + "audience") + private String audience; + + @JsonProperty(EDCAssetConstant.TX_AUTH_PREFIX + "refreshToken") + private String refreshToken; + + @JsonProperty(EDCAssetConstant.TX_AUTH_PREFIX + "expiresIn") + private String expiresIn; - @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "authKey") - private String authKey; + @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "refreshAudience") + private String refreshAudience; -} +} \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/edr/EDRCachedResponse.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/edr/EDRCachedResponse.java index 2a2939a1b..9617729ee 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/edr/EDRCachedResponse.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/edr/EDRCachedResponse.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2023, 2024 T-Systems International GmbH - * Copyright (c) 2023, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2023,2024 T-Systems International GmbH + * Copyright (c) 2023,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -57,11 +57,8 @@ public class EDRCachedResponse { @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "providerId") private String providerId; - - @JsonProperty("tx:edrState") - private String edrState; - - @JsonProperty("tx:expirationDate") - private String expirationDate; + + @JsonProperty(EDCAssetConstant.ASSET_PREFIX + "contractNegotiationId") + private String contractNegotiationId; } \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/request/QueryDataOfferRequest.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/request/QueryDataOfferRequest.java index 2942d38f6..dd328bcc2 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/request/QueryDataOfferRequest.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/model/request/QueryDataOfferRequest.java @@ -44,6 +44,8 @@ public class QueryDataOfferRequest { private String connectorOfferUrl; + private String publisher; + private PolicyModel policy; } \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/CatalogResponseBuilder.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/CatalogResponseBuilder.java index 4cad79442..e8fcabf92 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/CatalogResponseBuilder.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/CatalogResponseBuilder.java @@ -44,7 +44,7 @@ public class CatalogResponseBuilder extends AbstractEDCStepsHelper { private final ContractOfferCatalogApi contractOfferCatalogApiProxy; private final ContractOfferRequestFactory contractOfferRequestFactory; - public List queryOnDataOffers(String providerUrl, Integer offset, Integer limit, + public List queryOnDataOffers(String providerUrl, String counterPartyId, Integer offset, Integer limit, String filterExpression) { providerUrl = UtilityFunctions.removeLastSlashOfUrl(providerUrl); @@ -57,7 +57,7 @@ public List queryOnDataOffers(String providerUrl, Integer o List queryOfferResponse = new ArrayList<>(); JsonNode contractOfferCatalog = contractOfferCatalogApiProxy.getContractOffersCatalog( - contractOfferRequestFactory.getContractOfferRequest(sproviderUrl, limit, offset, filterExpression)); + contractOfferRequestFactory.getContractOfferRequest(sproviderUrl, counterPartyId, limit, offset, filterExpression)); JsonNode jOffer = contractOfferCatalog.get("dcat:dataset"); if (jOffer.isArray()) { @@ -76,7 +76,7 @@ public QueryDataOfferModel buildContractOffer(String sproviderUrl, JsonNode cont JsonNode policy = offer.get("odrl:hasPolicy"); - String edcstr = "edc:"; + String edcstr = EDCAssetConstant.ASSET_PREFIX; QueryDataOfferModel build = QueryDataOfferModel.builder() .assetId(getFieldFromJsonNode(offer, edcstr + EDCAssetConstant.ASSET_PROP_ID)) @@ -90,7 +90,7 @@ public QueryDataOfferModel buildContractOffer(String sproviderUrl, JsonNode cont .version(getFieldFromJsonNode(offer, edcstr + EDCAssetConstant.ASSET_PROP_VERSION)) .fileName(getFieldFromJsonNode(offer, edcstr + EDCAssetConstant.ASSET_PROP_FILENAME)) .fileContentType(getFieldFromJsonNode(offer, edcstr + EDCAssetConstant.ASSET_PROP_CONTENTTYPE)) - .connectorId(getFieldFromJsonNode(contractOfferCatalog, "edc:participantId")).build(); + .connectorId(getFieldFromJsonNode(contractOfferCatalog, edcstr+"participantId")).build(); checkAndSetPolicyPermission(build, policy); diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/ConsumerControlPanelService.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/ConsumerControlPanelService.java index d3be2add4..440aa4dce 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/ConsumerControlPanelService.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/ConsumerControlPanelService.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2024 T-Systems International GmbH - * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -33,6 +33,7 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.eclipse.tractusx.sde.bpndiscovery.handler.BpnDiscoveryProxyService; import org.eclipse.tractusx.sde.bpndiscovery.model.request.BpnDiscoverySearchRequest; import org.eclipse.tractusx.sde.bpndiscovery.model.request.BpnDiscoverySearchRequest.Search; @@ -67,7 +68,6 @@ @RequiredArgsConstructor public class ConsumerControlPanelService { - private static final String NEGOTIATED = "NEGOTIATED"; private static final String STATUS = "status"; private final ContractNegotiateManagementHelper contractNegotiateManagement; @@ -175,7 +175,7 @@ public void subscribeDataOffers(ConsumerRequest consumerRequest, String processI public Map subcribeAndDownloadOffer(Offer offer, ActionRequest action, boolean flagToDownloadImidiate, String downloadAs) { - + Map resultFields = new ConcurrentHashMap<>(); try { var recipientURL = UtilityFunctions.removeLastSlashOfUrl(offer.getConnectorOfferUrl()); @@ -216,13 +216,8 @@ private void doVerifyResult(String assetId, EDRCachedResponse checkContractNegot + " but intiate data transfer is not completed and no EDR token available, download is not possible"); } - String state = Optional.ofNullable(checkContractNegotiationStatus).filter( - verifyEDRRequestStatusLocal -> NEGOTIATED.equalsIgnoreCase(verifyEDRRequestStatusLocal.getEdrState())) - .map(EDRCachedResponse::getEdrState) - .orElseThrow(() -> new ServiceException( - "Time out!! to get 'NEGOTIATED' EDC EDR status to download data, the current status is '" - + checkContractNegotiationStatus.getEdrState() + "'")); - log.info("The EDR token status :" + state); + if (Optional.ofNullable(checkContractNegotiationStatus).isEmpty()) + throw new ServiceException("Time out!! to get 'EDC EDR status to download data"); } @SneakyThrows @@ -260,7 +255,7 @@ private void prepareErrorMap(Map resultFields, String errorMsg) @SneakyThrows private Object downloadFile(EDRCachedResponse verifyEDRRequestStatus, String downloadDataAs) { - if (verifyEDRRequestStatus != null && NEGOTIATED.equalsIgnoreCase(verifyEDRRequestStatus.getEdrState())) { + if (verifyEDRRequestStatus != null) { try { EDRCachedByIdResponse authorizationToken = contractNegotiationService .getAuthorizationTokenForDataDownload(verifyEDRRequestStatus.getTransferProcessId()); @@ -282,14 +277,11 @@ private Object downloadFile(EDRCachedResponse verifyEDRRequestStatus, String dow public List getEDCPolicy(List queryDataOfferModel) { - Map> collect = queryDataOfferModel.stream() - .collect(Collectors.groupingBy(QueryDataOfferRequest::getConnectorOfferUrl, - Collectors.mapping(QueryDataOfferRequest::getAssetId, Collectors.toList()))); - - return collect.entrySet().stream() - .map(entry -> lookUpDTTwin.getEDCOffer(entry.getValue(), entry.getKey())) - .flatMap(Collection::stream) - .toList(); + Map, List> collect = queryDataOfferModel.stream() + .collect(Collectors.groupingBy(ele -> Pair.of(ele.getConnectorOfferUrl(), ele.getPublisher()))); + + return collect.entrySet().stream().map(entry -> lookUpDTTwin.getEDCOffer(entry.getValue(), entry.getKey())) + .flatMap(Collection::stream).toList(); } -} +} \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/ContractNegotiationService.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/ContractNegotiationService.java index 01556239e..126507702 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/ContractNegotiationService.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/ContractNegotiationService.java @@ -47,15 +47,14 @@ @Slf4j @Service @RequiredArgsConstructor -public class ContractNegotiationService extends AbstractEDCStepsHelper { - - private static final String NEGOTIATED = "NEGOTIATED"; +public class ContractNegotiationService extends AbstractEDCStepsHelper { + private final EDRRequestHelper edrRequestHelper; private static final Integer RETRY = 5; private static final Integer THRED_SLEEP_TIME = 5000; - + private final ContractNegotiateManagementHelper contractNegotiateManagement; - + @SneakyThrows public EDRCachedResponse verifyOrCreateContractNegotiation(String connectorId, Map extensibleProperty, String recipientURL, ActionRequest action, Offer offer) { @@ -71,30 +70,25 @@ public EDRCachedResponse verifyOrCreateContractNegotiation(String connectorId, if (checkContractNegotiationStatus == null) { String contractAgreementId = checkandGetContractAgreementId(assetId); if (StringUtils.isBlank(contractAgreementId)) { - log.info(LogUtil.encode("The EDR process was not completed, no 'NEGOTIATED' EDR status found " - + "and not valid contract agreementId for " + assetId + ", so initiating EDR process")); + log.info(LogUtil.encode("The EDR process was not completed, no EDR status found " + + "and not valid contract agreementId for " + recipientURL + ", " + assetId + + ", so initiating EDR process")); edrRequestHelper.edrRequestInitiate(recipientURL, connectorId, offer.getOfferId(), assetId, action, extensibleProperty); checkContractNegotiationStatus = verifyEDRRequestStatus(assetId); } else { - log.info(LogUtil.encode("There is valid contract agreement exist for " + assetId + log.info(LogUtil.encode("There is valid contract agreement exist for " + recipientURL + ", " + assetId + ", so ignoring EDR process initiation")); checkContractNegotiationStatus = EDRCachedResponse.builder().agreementId(contractAgreementId) .assetId(assetId).build(); } - } else { - log.info(LogUtil.encode("There was EDR process initiated " + assetId - + ", so ignoring EDR process initiation, going to check EDR status only")); - if (!NEGOTIATED.equals(checkContractNegotiationStatus.getEdrState())) - checkContractNegotiationStatus = verifyEDRRequestStatus(assetId); - } - + } return checkContractNegotiationStatus; } - + @SneakyThrows private String checkandGetContractAgreementId(String assetId) { - + List contractAgreements = contractNegotiateManagement.getAllContractAgreements(assetId, Type.CONSUMER.name(), 0, 10); String contractAgreementId = null; @@ -110,25 +104,17 @@ private String checkandGetContractAgreementId(String assetId) { return contractAgreementId; } - + private EDRCachedResponse verifyEDRResponse(List eDRCachedResponseList) { EDRCachedResponse eDRCachedResponse = null; if (eDRCachedResponseList != null && !eDRCachedResponseList.isEmpty()) { for (EDRCachedResponse edrCachedResponseObj : eDRCachedResponseList) { - String edrState = edrCachedResponseObj.getEdrState(); - // For EDC connector 5.0 edrState field not supported so checking token - // validation by calling direct API - if (NEGOTIATED.equalsIgnoreCase(edrState) || isEDRTokenValid(edrCachedResponseObj)) { - eDRCachedResponse = edrCachedResponseObj; - eDRCachedResponse.setEdrState(NEGOTIATED); - break; - } eDRCachedResponse = edrCachedResponseObj; } } return eDRCachedResponse; } - + @SneakyThrows public EDRCachedResponse verifyEDRRequestStatus(String assetId) { EDRCachedResponse eDRCachedResponse = null; @@ -139,17 +125,17 @@ public EDRCachedResponse verifyEDRRequestStatus(String assetId) { do { if (counter > 1) Thread.sleep(THRED_SLEEP_TIME); - + eDRCachedResponseList = edrRequestHelper.getEDRCachedByAsset(assetId); eDRCachedResponse = verifyEDRResponse(eDRCachedResponseList); - if (eDRCachedResponse != null && eDRCachedResponse.getEdrState() != null) - edrStatus = eDRCachedResponse.getEdrState(); + if (eDRCachedResponse != null) + edrStatus = "FoundEDR"; - log.info(LogUtil.encode("Verifying 'NEGOTIATED' EDC EDR status to download data for '" + assetId - + "', The current status is '" + edrStatus + "', Attempt " + counter)); + log.info(LogUtil.encode("Verifying EDC EDR status to download data for '" + assetId + "', The current status is '" + + edrStatus + "', Attempt " + counter)); counter++; - } while (counter <= RETRY && !NEGOTIATED.equals(edrStatus)); + } while (counter <= RETRY && eDRCachedResponse == null); if (eDRCachedResponse == null) { String contractAgreementId = checkandGetContractAgreementId(assetId); @@ -157,7 +143,8 @@ public EDRCachedResponse verifyEDRRequestStatus(String assetId) { eDRCachedResponse = EDRCachedResponse.builder().agreementId(contractAgreementId).assetId(assetId) .build(); } else - throw new ServiceException("Time out!! unable to get Contract negotiation FINALIZED status"); + throw new ServiceException( + "Time out!! unable to get Contract negotiation FINALIZED status for " + assetId); } } catch (FeignException e) { @@ -178,31 +165,6 @@ public EDRCachedResponse verifyEDRRequestStatus(String assetId) { return eDRCachedResponse; } - @SneakyThrows - private boolean isEDRTokenValid(EDRCachedResponse edrCachedResponseObj) { - String assetId = edrCachedResponseObj.getAssetId(); - try { - EDRCachedByIdResponse authorizationToken = getAuthorizationTokenForDataDownload( - edrCachedResponseObj.getTransferProcessId()); - edrRequestHelper.getDataFromProvider(authorizationToken, authorizationToken.getEndpoint()); - } catch (FeignException e) { - log.error("FeignException RequestBody: " + e.request()); - String errorMsg = "FeignExceptionton for verifyEDR token " + assetId + "," + e.status() + "::" - + e.contentUTF8(); - log.error("FeignException Response: " + errorMsg); - - if (e.status() == 403) { - log.error("Got 403 as token status so going to try new EDR token: " + errorMsg); - return false; - } - } catch (Exception e) { - String errorMsg = "Exception for asset in isEDRTokenValid " + assetId + "," + e.getMessage(); - log.error(errorMsg); - } - return true; - } - - @SneakyThrows public EDRCachedByIdResponse getAuthorizationTokenForDataDownload(String transferProcessId) { return edrRequestHelper.getEDRCachedByTransferProcessId(transferProcessId); diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/LookUpDTTwin.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/LookUpDTTwin.java index fa803918d..b2e99360d 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/LookUpDTTwin.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/services/LookUpDTTwin.java @@ -29,6 +29,7 @@ import java.util.Optional; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.eclipse.tractusx.sde.common.constants.CommonConstants; import org.eclipse.tractusx.sde.digitaltwins.entities.common.KeyValuePair; import org.eclipse.tractusx.sde.digitaltwins.entities.common.MultiLanguage; @@ -40,6 +41,7 @@ import org.eclipse.tractusx.sde.digitaltwins.facilitator.DigitalTwinsUtility; import org.eclipse.tractusx.sde.digitaltwins.gateways.external.EDCDigitalTwinProxyForLookUp; import org.eclipse.tractusx.sde.edc.model.edr.EDRCachedByIdResponse; +import org.eclipse.tractusx.sde.edc.model.request.QueryDataOfferRequest; import org.eclipse.tractusx.sde.edc.model.response.QueryDataOfferModel; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -83,7 +85,7 @@ public List lookUpTwin(EDRCachedByIdResponse edrToken, Quer String endpoint = edrToken.getEndpoint(); String dtOfferUrl = dtOffer.getConnectorOfferUrl(); Map header = new HashMap<>(); - header.put(edrToken.getAuthKey(), edrToken.getAuthCode()); + header.put("authorization", edrToken.getAuthorization()); submodel = StringUtils.isBlank(submodel) ? "" : submodel; if (StringUtils.isNotBlank(bpnNumber)) @@ -192,26 +194,29 @@ private void buildQdmOffer(String submodel, List queryOnDat .filter(e -> e.getLanguage().contains("en")).map(MultiLanguage::getText).findFirst(); String description = descriptionOptional.isPresent() ? descriptionOptional.get() : ""; - - QueryDataOfferModel qdm = QueryDataOfferModel.builder() - .publisher(manufacturerBPNId) - .manufacturerPartId(manufacturerPartId) - .connectorOfferUrl(connectorInfo[1]) - .assetId(assetInfo[1]) - .type(subModelResponse.getIdShort()) - .sematicVersion(sematicId) - .title(shellDescriptorResponse.getIdShort()) - .description(description) - .build(); + QueryDataOfferModel qdm = QueryDataOfferModel.builder() + .publisher(manufacturerBPNId) + .manufacturerPartId(manufacturerPartId) + .connectorOfferUrl(connectorInfo[1]) + .assetId(assetInfo[1]) + .type(subModelResponse.getIdShort()) + .sematicVersion(sematicId) + .title(shellDescriptorResponse.getIdShort()) + .description(description) + .build(); + queryOnDataOffers.add(qdm); } } - public List getEDCOffer(List assetId, String connectorOfferUrl) { - String joinStr = StringUtils.join(assetId, "\",\""); + public List getEDCOffer(List assetId, + Pair queryDataOfferRequestKey) { + + String joinStr = StringUtils.join(assetId.stream().map(QueryDataOfferRequest::getAssetId).toList(), "\",\""); String filterExpression = String.format(filterExpressionTemplate, joinStr); - return catalogResponseBuilder.queryOnDataOffers(connectorOfferUrl, 0, 1000, filterExpression); + return catalogResponseBuilder.queryOnDataOffers(queryDataOfferRequestKey.getLeft(), + queryDataOfferRequestKey.getRight(), 0, 1000, filterExpression); } private String getSpecificKeyFromList(ShellDescriptorResponse shellDescriptorResponse, String key) { @@ -243,4 +248,4 @@ private Map getSpecificAssetIds(String manufacturerPartId, Strin return specificIdentifiers; } -} +} \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/EDCAssetLookUp.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/EDCAssetLookUp.java index e8e1875f5..87ded8bc4 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/EDCAssetLookUp.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/EDCAssetLookUp.java @@ -53,18 +53,20 @@ public class EDCAssetLookUp { public List getEDCAssetsByType(String bpnNumber, String assetType) { List connectorInfos = portalProxyService.fetchConnectorInfo(List.of(bpnNumber)); + + List distinctList = connectorInfos.stream().distinct().toList(); List offers = new ArrayList<>(); String filterExpression = String.format(filterExpressionTemplate, assetType); - connectorInfos.stream().forEach( + distinctList.stream().forEach( connectorInfo -> connectorInfo.getConnectorEndpoint().parallelStream().distinct().forEach(connector -> { try { if (!connector.contains(consumerHost)) { List queryDataOfferModel = catalogResponseBuilder - .queryOnDataOffers(connector, 0, 100, filterExpression); + .queryOnDataOffers(connector, bpnNumber, 0, 100, filterExpression); log.info("For Connector " + connector + ", found " + assetType + " assets :" + queryDataOfferModel.size()); @@ -86,4 +88,5 @@ public List getEDCAssetsByType(String bpnNumber, String ass return offers; } + } \ No newline at end of file diff --git a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/EDCAssetUrlCacheService.java b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/EDCAssetUrlCacheService.java index ab6522cc8..16a7da3e2 100644 --- a/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/EDCAssetUrlCacheService.java +++ b/modules/sde-external-services/edc/src/main/java/org/eclipse/tractusx/sde/edc/util/EDCAssetUrlCacheService.java @@ -69,13 +69,9 @@ public EDRCachedByIdResponse verifyAndGetToken(String bpnNumber, QueryDataOfferM bpnNumber, Map.of(), queryDataOfferModel.getConnectorOfferUrl(), action, offer); if (eDRCachedResponse == null) { - throw new ServiceException("Time out!! to get 'NEGOTIATED' EDC EDR status to lookup '" + throw new ServiceException("Time out!! to get EDC EDR status to lookup '" + queryDataOfferModel.getConnectorOfferUrl() + ", " + queryDataOfferModel.getAssetId() + "', The current status is null"); - } else if (!"NEGOTIATED".equalsIgnoreCase(eDRCachedResponse.getEdrState())) { - throw new ServiceException("Time out!! to get 'NEGOTIATED' EDC EDR status to lookup for '" - + queryDataOfferModel.getConnectorOfferUrl() + ", " + queryDataOfferModel.getAssetId() - + "', The current status is '" + eDRCachedResponse.getEdrState() + "'"); } else return contractNegotiationService .getAuthorizationTokenForDataDownload(eDRCachedResponse.getTransferProcessId()); diff --git a/modules/sde-external-services/portal/src/main/java/org/eclipse/tractusx/sde/portal/api/IPartnerPoolExternalServiceApi.java b/modules/sde-external-services/portal/src/main/java/org/eclipse/tractusx/sde/portal/api/IPartnerPoolExternalServiceApi.java index 75b4b899c..d9ca4cdfe 100644 --- a/modules/sde-external-services/portal/src/main/java/org/eclipse/tractusx/sde/portal/api/IPartnerPoolExternalServiceApi.java +++ b/modules/sde-external-services/portal/src/main/java/org/eclipse/tractusx/sde/portal/api/IPartnerPoolExternalServiceApi.java @@ -1,6 +1,6 @@ /******************************************************************************** - * Copyright (c) 2022, 2023 T-Systems International GmbH - * Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation + * Copyright (c) 2022,2024 T-Systems International GmbH + * Copyright (c) 2022,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -28,7 +28,7 @@ @FeignClient(value = "IPartnerPoolExternalServiceApi", url = "${partner.pool.hostname}" , configuration = PartnerPoolExternalServiceApiConfiguration.class) public interface IPartnerPoolExternalServiceApi { - @GetMapping(path = "/api/catena/legal-entities") + @GetMapping(path = "/legal-entities") LegalEntityData fetchLegalEntityData(@RequestParam String legalName, @RequestParam Integer page, @RequestParam Integer size); -} +} \ No newline at end of file diff --git a/modules/sde-submodules/part-site-information-as-planned/part-site-information-as-planned.md b/modules/sde-submodules/part-site-information-as-planned/part-site-information-as-planned.md index b805b5243..cba5132ee 100644 --- a/modules/sde-submodules/part-site-information-as-planned/part-site-information-as-planned.md +++ b/modules/sde-submodules/part-site-information-as-planned/part-site-information-as-planned.md @@ -47,4 +47,4 @@ Please find below links for schema details: - DigitalTwins - EDC Connectors - - BPN Discovery + - BPN Discovery \ No newline at end of file diff --git a/modules/sde-submodules/part-type-Information/part-type-information.md b/modules/sde-submodules/part-type-Information/part-type-information.md deleted file mode 100644 index c8f72056f..000000000 --- a/modules/sde-submodules/part-type-Information/part-type-information.md +++ /dev/null @@ -1,52 +0,0 @@ - # PartTypeInformation (SDE Maven module) ---- -## Description - -This module use for PartTypeInformation submodel specification and descriptors. It's contain the codes related to PartTypeInformation to validate, parse and transfer data for DigitalTwins and EDC to create aspect twins and data offer. - ---- -#### Version: 1.0.0 -#### PartTypeInformation Aspect Model URN: urn:bamm:io.catenax.part_as_planned:1.0.0#PartTypeInformation -#### Semantic Id: urn:samm:io.catenax.part_type_information:1.0.0#PartTypeInformation ---- - -### Schema - -Please find below links for schema details: - -- [PartTypeInformation V1.0.0 schema](src/main/resources/part-type-information-v1.0.0.json) - -### CSV file headers - -| Headers Name | Mandatory | Position | -|------------------------ |---------------------------|-------- | -| uuid | Yes | 1 | -| manufacturer_part_id | Yes | 2 | -| classification_standard | Yes | 3 | -| classification_id | Yes | 4 | -| classification_description | No | 5 | -| function | Yes | 6 | -| function_valid_from | No | 7 | -| function_valid_until | No | 8 | -| name_at_manufacturer | Yes | 9 | - -#### [CSV Sample File Link] - -#### Example for submodel PartAsPlanned - -### Work Flow - - - CSV to POJO - - CSV column validation and mandatory field validation - - POJO TO DTO - - UUID generate v4 - - DigitalTwins API's calls - - EDC API's calls - - BPN Discovery calls - - DB Store - -### External Services Call - - - DigitalTwins - - EDC Connectors - - BPN Discovery diff --git a/modules/sde-submodules/part-type-Information/pom.xml b/modules/sde-submodules/part-type-Information/pom.xml deleted file mode 100644 index 1bdde3818..000000000 --- a/modules/sde-submodules/part-type-Information/pom.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - 4.0.0 - - org.eclipse.tractusx - sde - 0.0.1 - ../../../ - - - part-type-information - part-type-information - part-type-information - - - - org.eclipse.tractusx - sde-common - 0.0.1 - - - org.eclipse.tractusx - edc - 0.0.1 - - - org.eclipse.tractusx - digital-twins - 0.0.1 - - - org.eclipse.tractusx - bpn-discovery - 0.0.1 - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - - org.projectlombok - lombok - ${lombok.version} - - - org.mapstruct - mapstruct-processor - ${org.mapstruct.processor.version} - - - - - -Amapstruct.unmappedTargetPolicy=IGNORE - - - - - - - \ No newline at end of file diff --git a/modules/sde-submodules/part-type-Information/src/main/java/org/eclipse/tractusx/sde/submodels/pti/PartTypeInformationV100.java b/modules/sde-submodules/part-type-Information/src/main/java/org/eclipse/tractusx/sde/submodels/pti/PartTypeInformationV100.java deleted file mode 100644 index d7abc740d..000000000 --- a/modules/sde-submodules/part-type-Information/src/main/java/org/eclipse/tractusx/sde/submodels/pti/PartTypeInformationV100.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2024 T-Systems International GmbH - * 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.sde.submodels.pti; - -import java.io.InputStream; - -import org.eclipse.tractusx.sde.common.extensions.SubmodelExtension; -import org.eclipse.tractusx.sde.common.model.Submodel; -import org.springframework.stereotype.Component; - -import jakarta.annotation.PostConstruct; - -@Component -public class PartTypeInformationV100 extends SubmodelExtension { - - private Submodel submodel = null; - - @PostConstruct - public void init() { - - String resource = "part-type-information-v1.0.0.json"; - // this is the path within the jar file - InputStream input = this.getClass().getResourceAsStream("/resources/" + resource); - if (input == null) { - // this is how we load file within editor (eg eclipse) - input = this.getClass().getClassLoader().getResourceAsStream(resource); - } - - submodel = loadSubmodel(input); - - submodel.addProperties("tableName", "parttypeinformation_v_100"); - } - - @Override - public Submodel submodel() { - return submodel; - } - -} diff --git a/modules/sde-submodules/part-type-Information/src/main/resources/part-type-information-v1.0.0.json b/modules/sde-submodules/part-type-Information/src/main/resources/part-type-information-v1.0.0.json deleted file mode 100644 index 57af48ee4..000000000 --- a/modules/sde-submodules/part-type-Information/src/main/resources/part-type-information-v1.0.0.json +++ /dev/null @@ -1,197 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "http://example.com/example.json", - "type": "array", - "id": "parttypeinformation_100", - "idShort": "partTypeInformation", - "version": "1.0.0", - "semantic_id": "urn:samm:io.catenax.part_type_information:1.0.0#PartTypeInformation", - "title": "Part Type Information", - "shortDescription": "BoM As-Planned - Submodel PartTypeInformation", - "description": "A Part Type Information represents an item in the Catena-X Bill of Material (BOM) on a type level in a specific version.", - "items": { - "type": "object", - "required": [ - "uuid", - "manufacturer_part_id", - "catenax_site_id", - "name_at_manufacturer", - "classification_standard", - "classification_id", - "function" - ], - "dependentRequired": { - }, - "properties": { - "uuid": { - "type": [ - "string" - ], - "title": "UUID URN", - "description": "The provided regular expression ensures that the UUID is composed of five groups of characters separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters (32 hexadecimal characters and 4 hyphens), optionally prefixed by \"urn:uuid:\" to make it an IRI.", - "minLength": 1, - "pattern" : "(^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)|(^urn:uuid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$)", - "examples": [ - "urn:uuid:8eea5f45-0823-48ce-a4fc-c3bf1cdfa4c2" - ] - }, - "manufacturer_part_id": { - "type": [ - "string" - ], - "minLength": 1, - "title": "Manufacturer Part Id", - "description" : "Part ID as assigned by the manufacturer of the part. The part ID identifies the part in the manufacturer`s dataspace. The part ID references a specific version of a part. The version number must be included in the part ID if it is available. The part ID does not reference a specific instance of a part and must not be confused with the serial number.", - "examples": [ - "123-0.740-3434-A" - ] - }, - "catenax_site_id": { - "type": [ - "string" - ], - "minLength": 1, - "title": "catenaX Site Id", - "description": "The identifier of the site according to Catena-X BPDM. The catenaXsiteId must be a valid Catena-X BPN. The BPN is a unique, unchangeable identifier for Business Partners / company locations from foundation to closure, regardless of the different business relationships / structures between or within the Business Partners or company locations.", - "examples": [ - "BPNS1234567890ZZ" - ] - }, - "classification_standard": { - "type": [ - "string" - ], - "minLength": 1, - "title": "Classification Standard", - "description": "Identified classification standards that align to the Catena-X needs.", - "examples": [ - "IEC" - ] - }, - "classification_id": { - "type": [ - "string" - ], - "minLength": 1, - "title": "Classification Id", - "description": "The classification ID of the part type according to the corresponding standard definition mentioned in the key value pair.", - "examples": [ - "61360- 2:2012" - ] - }, - "classification_description": { - "type": [ - "string", - "null" - ], - "title": "Classification Description", - "description": "Optional property describing the classification standard.", - "examples": [ - "Standard data element types with associated classification scheme for electric components." - ] - }, - "function": { - "type": [ - "string" - ], - "enum": [ - "production", - "warehouse", - "spare part warehouse" - ], - "title": "Function", - "minLength": 1, - "description" : "The function of the site in relation to the part (i.e. the activity within the value chain of the part that is performed at the site).", - "examples": [ - "production" - ] - }, - "function_valid_from": { - "type": [ - "string", - "null" - ], - "title": "Function Valid From", - "pattern" : "^(?:[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:[.][0-9]+)?Z|[0-9]{4}-[0-9]{2}-[0-9]{2}(?:T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:[.][0-9]+)?(?:Z|[+-][0-9]{2}:[0-9]{2}))?)$", - "description" : "Timestamp, from when the site has the specified function for the given part.", - "examples": [ - "2024-01-29T12:00:00.123+02:00" - ] - }, - "function_valid_until": { - "type": [ - "string", - "null" - ], - "title": "Function Valid Until", - "pattern" : "^(?:[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:[.][0-9]+)?Z|[0-9]{4}-[0-9]{2}-[0-9]{2}(?:T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:[.][0-9]+)?(?:Z|[+-][0-9]{2}:[0-9]{2}))?)$", - "description" : "Timestamp, from when the site has the specified function for the given part.", - "examples": [ - "2024-01-29T12:00:00.123+02:00" - ] - }, - "name_at_manufacturer": { - "type": [ - "string" - ], - "minLength": 1, - "title": "Name At Manufacturer", - "description": "Name of the part as assigned by the manufacturer", - "examples": [ - "Mirror left" - ] - } - } - }, - "examples": [ - { - "uuid": "urn:uuid:055c1128-0375-47c8-98de-7cf802c3241d", - "manufacturer_part_id": "123-0.740-3434-A", - "catenax_site_id": "BPNS1234567890ZZ", - "classification_standard": "IEC", - "classification_id": "61360- 2:2012", - "classification_description": "Standard data element types with associated classification scheme for electric components.", - "function": "production", - "function_valid_from": "2024-01-29T12:00:00.123+02:00", - "function_valid_until": "2024-03-29T12:00:00.123+02:00", - "name_at_manufacturer": "Mirror left" - } - ], - "addOn": { - "identifier": "${uuid}", - "lookupShellSpecificAssetIdsSpecs": { - "manufacturerPartId": "${manufacturer_part_id}", - "assetLifecyclePhase" :"AsPlanned" - }, - "shortIdSpecs": [ - "${name_at_manufacturer}", - "${manufacturer_part_id}" - ], - "createShellIfNotExist": true, - "bpnDiscoverySpecs": { - "manufacturerPartId": "${manufacturer_part_id}" - }, - "responseTemplate": { - "partTypeInformation": { - "partClassification": [ - { - "classificationStandard": "${classification_standard}", - "classificationID": "${classification_id}", - "classificationDescription": "${classification_description}" - } - ], - "manufacturerPartId": "${manufacturer_part_id}", - "nameAtManufacturer": "${name_at_manufacturer}" - }, - "partSitesInformationAsPlanned": [ - { - "functionValidUntil": "${function_valid_until}", - "catenaXsiteId": "${catenax_site_id}", - "function": "${function}", - "functionValidFrom": "${function_valid_from}" - } - ], - "catenaXId": "${uuid}" - } - } -} \ No newline at end of file diff --git a/modules/sde-submodules/single-level-bom-as-planned/src/main/resources/single-level-bom-as-planned-v1.0.1.json b/modules/sde-submodules/single-level-bom-as-planned/src/main/resources/single-level-bom-as-planned-v1.0.1.json index 5703d4872..f131ba00f 100644 --- a/modules/sde-submodules/single-level-bom-as-planned/src/main/resources/single-level-bom-as-planned-v1.0.1.json +++ b/modules/sde-submodules/single-level-bom-as-planned/src/main/resources/single-level-bom-as-planned-v1.0.1.json @@ -8,7 +8,7 @@ "semantic_id": "urn:bamm:io.catenax.single_level_bom_as_planned:1.0.1#SingleLevelBomAsPlanned", "title": "Single Level Bom AsPlanned", "shortDescription": "BoM As-Planned - Submodel SingleLevelBomAsPlanned", - "description":"The single-level Bill of Material represents one sub-level of an assembly and does not include any lower-level subassemblies. In As-Planned lifecycle state all variants are covered ('120% BOM'). It includes multiple suppliers for the same component.", + "description": "The single-level Bill of Material represents one sub-level of an assembly and does not include any lower-level subassemblies. In As-Planned lifecycle state all variants are covered ('120% BOM'). It includes multiple suppliers for the same component.", "items": { "type": "object", "required": [ @@ -20,8 +20,7 @@ "measurement_unit", "created_on" ], - "dependentRequired": { - }, + "dependentRequired": {}, "properties": { "parent_uuid": { "type": [ @@ -41,7 +40,7 @@ ], "minLength": 1, "title": "Parent Manufacturer Part ID", - "description":"The Parent Manufacturer Part ID of the parent object Manufacturer Part ID, to identify parent object in digital twins.", + "description": "The Parent Manufacturer Part ID of the parent object Manufacturer Part ID, to identify parent object in digital twins.", "examples": [ "37754B7-76" ] @@ -64,7 +63,7 @@ ], "minLength": 1, "title": "Manufacturer Part ID", - "description":"The ID of the type/catalog part (of which the serialized part is an instance of) from the manufacturer.", + "description": "The ID of the type/catalog part (of which the serialized part is an instance of) from the manufacturer.", "examples": [ "37754B7-76" ] @@ -112,7 +111,7 @@ ], "format": "date-time", "title": "Last Modified On", - "description":"Timestamp when the relationship between parent part and child part was last modified.", + "description": "Timestamp when the relationship between parent part and child part was last modified.", "examples": [ "2022-02-03T14:48:54.709Z" ] @@ -165,4 +164,4 @@ ] } } -} +} \ No newline at end of file diff --git a/modules/sde-submodules/single-level-bom-as-planned/src/main/resources/single-level-bom-as-planned.json b/modules/sde-submodules/single-level-bom-as-planned/src/main/resources/single-level-bom-as-planned.json new file mode 100644 index 000000000..03f701cad --- /dev/null +++ b/modules/sde-submodules/single-level-bom-as-planned/src/main/resources/single-level-bom-as-planned.json @@ -0,0 +1,159 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "http://example.com/example.json", + "type": "array", + "id": "singlelevelbomasplanned", + "idShort": "singleLevelBomAsPlanned", + "version": "1.0.1", + "semantic_id": "urn:bamm:io.catenax.single_level_bom_as_planned:1.0.1#SingleLevelBomAsPlanned", + "title": "Single Level Bom AsPlanned", + "shortDescription": "BoM As-Planned - Submodel SingleLevelBomAsPlanned", + "description":"The single-level Bill of Material represents one sub-level of an assembly and does not include any lower-level subassemblies. In As-Planned lifecycle state all variants are covered ('120% BOM'). It includes multiple suppliers for the same component.", + "items": { + "type": "object", + "required": [ + "parent_uuid", + "parent_manufacturer_part_id", + "uuid", + "manufacturer_part_id", + "quantity_number", + "measurement_unit_lexical_value", + "datatype_uri", + "created_on" + ], + "dependentRequired": { + }, + "properties": { + "parent_uuid": { + "type": [ + "string" + ], + "minLength": 1, + "pattern": "^urn:uuid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", + "title": "Parent UUID", + "description":"The Catena-X ID of the parent object, into which the given child object is assembled in.", + "examples": [ + "urn:uuid:8eea5f45-0823-48ce-a4fc-c3bf34dfa4c2" + ] + }, + "parent_manufacturer_part_id": { + "type": [ + "string" + ], + "minLength": 1, + "title": "Parent Manufacturer Part ID", + "description":"The Parent Manufacturer Part ID of the parent object Manufacturer Part ID, to identify parent object in digital twins.", + "examples": [ + "37754B7-76" + ] + }, + "uuid": { + "type": [ + "string" + ], + "minLength": 1, + "title": "UUID", + "description":"The Catena-X ID of the given part (e.g. the component), valid for the Catena-X dataspace.", + "pattern": "^urn:uuid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", + "examples": [ + "urn:uuid:5daB938E-Cafa-92B3-7ca1-9aD7885e9dC8" + ] + }, + "manufacturer_part_id": { + "type": [ + "string" + ], + "minLength": 1, + "title": "Manufacturer Part ID", + "description":"The ID of the type/catalog part (of which the serialized part is an instance of) from the manufacturer.", + "examples": [ + "37754B7-76" + ] + }, + "customer_part_id": { + "type": [ + "string", + "null" + ], + "title": "Customer Part Id", + "description":"The ID of the type/catalog part (of which the serialized part is an instance of) from the customer.", + "examples": [ + "Currently missing the syntax" + ] + }, + "quantity_number": { + "type": [ + "number" + ], + "minLength": 1, + "multipleOf": 0.01, + "title": "Quantity Number", + "description":"Quantity of which the child part is assembled into the parent part.", + "examples": [ + 2.5 + ] + }, + "measurement_unit_lexical_value": { + "type": [ + "string" + ], + "minLength": 1, + "title": "Lexical Value", + "description":"Unit of Measurement for the quantity of serialized objects", + "examples": [ + "litre", + "unit" + ] + }, + "datatype_uri": { + "type": [ + "string" + ], + "minLength": 1, + "title": "Datatype URI", + "description":"", + "examples": [ + "urn:bamm:io.openmanufacturing:meta-model:1.0.0#curie" + ] + }, + "created_on": { + "type": [ + "string" + ], + "minLength": 1, + "format": "date-time", + "title": "Created On", + "description":"Timestamp when the relation between the parent part and the child part was created", + "examples": [ + "2022-02-03T14:48:54.709Z" + ] + }, + "last_modified_on": { + "type": [ + "string", + "null" + ], + "format": "date-time", + "title": "Last Modified On", + "description":"Timestamp when the relationship between parent part and child part was last modified.", + "examples": [ + "2022-02-03T14:48:54.709Z" + ] + } + } + }, + "examples": [ + { + "parent_uuid": "urn:uuid:055c1128-0375-47c8-98de-7cf802c3241d", + "parent_manufacturer_part_id": "37754B7-76", + "uuid": "urn:uuid:5daB938E-Cafa-92B3-7ca1-9aD7885e9dC8", + "manufacturer_part_id": "37754B7-76", + "customer_part_id": "AsPlanned", + "quantity_number": 2.5, + "measurement_unit_lexical_value": "litre", + "datatype_uri": "urn:bamm:io.openmanufacturing:meta-model:1.0.0#curie", + "created_on": "2022-02-03T14:48:54.709Z", + "last_modified_on": "2022-02-03T14:48:54.709Z" + } + ] +} diff --git a/modules/sde-submodules/submodules.md b/modules/sde-submodules/submodules.md index 983728f82..3bb98ef05 100644 --- a/modules/sde-submodules/submodules.md +++ b/modules/sde-submodules/submodules.md @@ -12,7 +12,6 @@ Currently SDE supports below submodels. #### [batch in Version 2.0.0] #### [assembly-part-relationship in Version 1.1.1] #### [partAsPlanned in Version 1.0.0] -#### [PartTypeInformation in Version 1.0.0] #### [singleLevelBoMAsPlanned in Version 1.0.1] #### [partSiteInformationAsPlanned in Version 1.0.0] #### [SingleLevelUsageAsBuilt in Version 1.0.1]