From 8e3ffc4579a799df7c530a547903803159911595 Mon Sep 17 00:00:00 2001 From: Mathias Brunkow Moser Date: Wed, 8 Nov 2023 11:55:23 +0100 Subject: [PATCH 1/2] feat: added timeout at bpn and edc endpoints and httpUtil doPost --- charts/digital-product-pass/values-beta.yaml | 3 +- charts/digital-product-pass/values-dev.yaml | 3 +- charts/digital-product-pass/values-int.yaml | 2 + charts/digital-product-pass/values.yaml | 2 + consumer-backend/productpass/pom.xml | 2 +- .../productpass/config/DiscoveryConfig.java | 18 +++++++++ .../productpass/services/CatenaXService.java | 7 +++- .../src/main/java/utils/HttpUtil.java | 39 +++++++++++++++++++ .../src/main/java/utils/ThreadUtil.java | 37 +++++++++++++++--- .../src/main/resources/application.yml | 2 + 10 files changed, 105 insertions(+), 10 deletions(-) diff --git a/charts/digital-product-pass/values-beta.yaml b/charts/digital-product-pass/values-beta.yaml index f7faff1dd..14d762e1e 100644 --- a/charts/digital-product-pass/values-beta.yaml +++ b/charts/digital-product-pass/values-beta.yaml @@ -158,9 +158,10 @@ backend: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" + timeout: 2000 edc: key: "bpn" - + timeout: 2000 process: store: true diff --git a/charts/digital-product-pass/values-dev.yaml b/charts/digital-product-pass/values-dev.yaml index 995a40800..87ad8170d 100644 --- a/charts/digital-product-pass/values-dev.yaml +++ b/charts/digital-product-pass/values-dev.yaml @@ -158,9 +158,10 @@ backend: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" + timeout: 2000 edc: key: "bpn" - + timeout: 2000 process: store: true diff --git a/charts/digital-product-pass/values-int.yaml b/charts/digital-product-pass/values-int.yaml index 2648a0a70..e8f654666 100644 --- a/charts/digital-product-pass/values-int.yaml +++ b/charts/digital-product-pass/values-int.yaml @@ -157,8 +157,10 @@ backend: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" + timeout: 2000 edc: key: "bpn" + timeout: 2000 process: diff --git a/charts/digital-product-pass/values.yaml b/charts/digital-product-pass/values.yaml index 6d47efbc0..cba595ea7 100644 --- a/charts/digital-product-pass/values.yaml +++ b/charts/digital-product-pass/values.yaml @@ -190,9 +190,11 @@ backend: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" + timeout: 2000 # -- timeout in milliseconds for the bpn discovery APIs to respond # -- edc discovery configuration edc: key: "bpn" + timeout: 2000 # -- timeout in milliseconds for the bpn discovery APIs to respond # -- process configuration process: # -- directory for storing the contract negotiation files diff --git a/consumer-backend/productpass/pom.xml b/consumer-backend/productpass/pom.xml index 7a7036bb2..aa01c11a0 100644 --- a/consumer-backend/productpass/pom.xml +++ b/consumer-backend/productpass/pom.xml @@ -33,7 +33,7 @@ org.eclipse.tractusx productpass - 1.3.0 + 1.3.1 jar Catena-X Digital Product Passport Backend Product Passport Consumer Backend System for Product Passport Consumer Frontend Application diff --git a/consumer-backend/productpass/src/main/java/org/eclipse/tractusx/productpass/config/DiscoveryConfig.java b/consumer-backend/productpass/src/main/java/org/eclipse/tractusx/productpass/config/DiscoveryConfig.java index 5954f0c47..b6b2bd6c7 100644 --- a/consumer-backend/productpass/src/main/java/org/eclipse/tractusx/productpass/config/DiscoveryConfig.java +++ b/consumer-backend/productpass/src/main/java/org/eclipse/tractusx/productpass/config/DiscoveryConfig.java @@ -72,6 +72,8 @@ public static class BPNConfig { String key; String searchPath; + Integer timeout; + /** GETTERS AND SETTERS **/ public String getKey() { return key; @@ -86,6 +88,14 @@ public String getSearchPath() { public void setSearchPath(String searchPath) { this.searchPath = searchPath; } + + public Integer getTimeout() { + return timeout; + } + + public void setTimeout(Integer timeout) { + this.timeout = timeout; + } } /** @@ -96,6 +106,7 @@ public static class EDCConfig { /** ATTRIBUTES **/ String key; + Integer timeout; /** GETTERS AND SETTERS **/ public String getKey() { return key; @@ -103,6 +114,13 @@ public String getKey() { public void setKey(String key) { this.key = key; } + public Integer getTimeout() { + return timeout; + } + + public void setTimeout(Integer timeout) { + this.timeout = timeout; + } } } diff --git a/consumer-backend/productpass/src/main/java/org/eclipse/tractusx/productpass/services/CatenaXService.java b/consumer-backend/productpass/src/main/java/org/eclipse/tractusx/productpass/services/CatenaXService.java index 6ce7a178f..2aef7e7c4 100644 --- a/consumer-backend/productpass/src/main/java/org/eclipse/tractusx/productpass/services/CatenaXService.java +++ b/consumer-backend/productpass/src/main/java/org/eclipse/tractusx/productpass/services/CatenaXService.java @@ -505,6 +505,7 @@ public List getEdcDiscovery(List bpns) { if (edcEndpoints == null) { throw new ServiceException(this.getClass().getName() + ".getEdcDiscovery", "The edc discovery endpoint is empty!"); } + Integer timeout = discoveryConfig.getEdc().getTimeout(); List edcDiscoveryResponses = new ArrayList<>(); for(String edcEndpoint : edcEndpoints) { @@ -512,7 +513,7 @@ public List getEdcDiscovery(List bpns) { HttpHeaders headers = httpUtil.getHeadersWithToken(this.authService.getToken().getAccessToken()); headers.add("Content-Type", "application/json"); try{ - ResponseEntity response = httpUtil.doPost(edcEndpoint, JsonNode.class, headers, httpUtil.getParams(), bpns, false, false); + ResponseEntity response = httpUtil.doPost(edcEndpoint, JsonNode.class, headers, httpUtil.getParams(), bpns, false, false, timeout); JsonNode result = (JsonNode) response.getBody(); List edcDiscoveryResponse = (List) jsonUtil.bindJsonNode(result, List.class); if(edcDiscoveryResponse.isEmpty()) { @@ -567,6 +568,7 @@ public List getBpnDiscovery(String id, String type){ if(bpnEndpoints == null){ throw new ServiceException(this.getClass().getName() + ".getBpnDiscovery", "The bpn discovery endpoint is empty!"); } + Integer timeout = discoveryConfig.getBpn().getTimeout(); // Get timeout in configuration for the bpn discovery endpoints List bpnDiscoveryResponse = new ArrayList<>(); for(String bpnEndpoint : bpnEndpoints) { @@ -585,7 +587,7 @@ public List getBpnDiscovery(String id, String type){ HttpHeaders headers = httpUtil.getHeadersWithToken(this.authService.getToken().getAccessToken()); headers.add("Content-Type", "application/json"); try{ - ResponseEntity response = httpUtil.doPost(searchEndpoint, JsonNode.class, headers, httpUtil.getParams(), body, false, false); + ResponseEntity response = httpUtil.doPost(searchEndpoint, JsonNode.class, headers, httpUtil.getParams(), body, false, false, timeout); JsonNode result = (JsonNode) response.getBody(); BpnDiscovery bpnDiscovery = (BpnDiscovery) jsonUtil.bindJsonNode(result, BpnDiscovery.class); if(bpnDiscovery == null){ @@ -595,6 +597,7 @@ public List getBpnDiscovery(String id, String type){ bpnDiscoveryResponse.add(bpnDiscovery); }catch (Exception e){ LogUtil.printException(e, "BPN Number not found for ["+searchEndpoint+"] and keyType ["+type+"]!"); + break; } } if(bpnDiscoveryResponse.isEmpty()){ diff --git a/consumer-backend/productpass/src/main/java/utils/HttpUtil.java b/consumer-backend/productpass/src/main/java/utils/HttpUtil.java index 6fefdf544..f5434fbe6 100644 --- a/consumer-backend/productpass/src/main/java/utils/HttpUtil.java +++ b/consumer-backend/productpass/src/main/java/utils/HttpUtil.java @@ -25,6 +25,7 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.logging.Log; import org.eclipse.tractusx.productpass.models.edc.Jwt; import org.eclipse.tractusx.productpass.models.http.Response; import org.springframework.beans.factory.annotation.Autowired; @@ -47,6 +48,7 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.*; /** * This class consists exclusively of methods to operate on the HTTP protocol. @@ -905,6 +907,43 @@ public ResponseEntity doPost(String url, Class responseType, HttpHeaders } } + /** + * Builds and make an HTTP POST request with headers, parameters, body and timeout + *

+ * @param url + * the base URL. + * @param responseType + * the class type of the response (e.g: a String, an Object, etc.) + * @param headers + * the HTTP headers to configure. + * @param params + * the Map with key/value pair from each parameter. + * @param body + * the {@code Object} object representing the body for the request. + * @param retry + * if true it will retry to do the request a predefined couple of times. + * @param encode + * if true will encode the value of each parameter. + * @param timeout + * if true will encode the value of each parameter. + * + * @return the {@code ResponseEntity} with the result of the POST request. + * + */ + public ResponseEntity doPost(String url, Class responseType, HttpHeaders headers, Map params, Object body, Boolean retry, Boolean encode, Integer timeout) { + try { + ResponseEntity response = null; + HttpEntity requestEntity = new HttpEntity<>(body, headers); + response = ThreadUtil.timeout(timeout,() -> doRequest(url, responseType, HttpMethod.POST, requestEntity, params, retry, encode), null); + if(response == null){ + LogUtil.printError("[TIMEOUT] Timeout reached! " + POST_ERROR_MESSAGE + url); + } + return response; + } catch (Exception e) { + throw new UtilException(HttpUtil.class, e, POST_ERROR_MESSAGE + url); + } + } + /** * Builds and make an HTTP POST request with parameters, without headers and body. *

diff --git a/consumer-backend/productpass/src/main/java/utils/ThreadUtil.java b/consumer-backend/productpass/src/main/java/utils/ThreadUtil.java index d297d0800..730e014c0 100644 --- a/consumer-backend/productpass/src/main/java/utils/ThreadUtil.java +++ b/consumer-backend/productpass/src/main/java/utils/ThreadUtil.java @@ -23,12 +23,11 @@ package utils; +import utils.exceptions.UtilException; + import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.*; /** * This class consists exclusively of methods to operate on a Thread level. @@ -121,5 +120,33 @@ public static void sleep(Integer milliseconds) Thread.currentThread().interrupt(); } } - + /** + * Puts the scheduled thread in the runtime that this method is called to sleep for a given time. + *

+ * Note: In case of an exception, the thread put to sleep is interrupted. + *

+ * @param milliseconds + * the length of time to sleep in milliseconds. + */ + public static V timeout(Integer milliseconds, Callable function, V timeoutResponse) + { + try { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future future = executor.submit(function); + boolean timeout = false; + V returnObject = null; + try { + returnObject = future.get(milliseconds, TimeUnit.MILLISECONDS); + } catch (TimeoutException e) { + timeout = true; + } + executor.shutdownNow(); + if(timeout){ + return timeoutResponse; + } + return returnObject; + } catch (Exception e) { + throw new UtilException(ThreadUtil.class, e, "Failed to execute the timeout functions!"); + } + } } diff --git a/consumer-backend/productpass/src/main/resources/application.yml b/consumer-backend/productpass/src/main/resources/application.yml index c817886a8..2e9f99d4a 100644 --- a/consumer-backend/productpass/src/main/resources/application.yml +++ b/consumer-backend/productpass/src/main/resources/application.yml @@ -95,8 +95,10 @@ configuration: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" + timeout: 2000 edc: key: "bpn" + timeout: 2000 process: From 42b4c2c8226487872f96b2a54ef6edc14eba1350 Mon Sep 17 00:00:00 2001 From: Mathias Brunkow Moser Date: Wed, 8 Nov 2023 17:52:09 +0100 Subject: [PATCH 2/2] chore: runned ip checks and updated chart version to v1.3.1 --- CHANGELOG.md | 8 ++++++++ README.md | 4 ++-- charts/digital-product-pass/Chart.yaml | 4 ++-- charts/digital-product-pass/README.md | 9 +++++---- charts/digital-product-pass/values-beta.yaml | 4 ++-- charts/digital-product-pass/values-dev.yaml | 4 ++-- charts/digital-product-pass/values-int.yaml | 4 ++-- charts/digital-product-pass/values.yaml | 4 ++-- consumer-backend/productpass/readme.md | 20 ++++++++----------- .../src/main/java/utils/ThreadUtil.java | 10 ++++++---- .../src/main/resources/application.yml | 4 ++-- docs/RELEASE_USER.md | 9 +++++++++ package-lock.json | 4 ++-- package.json | 2 +- 14 files changed, 53 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 432c69052..82018a3b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,14 @@ The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [released] +## [v1.3.1] - 08-11-2023 + +## Added +- Added timeout for the `BPN Discovery` and `EDC Discovery` APIs returned in the Discovery Service API. +- Created a new `doPost` function in the `HttpUtils`that allows the usage of timeouts in API calls. +- Create a new `timeout` function in `ThreadUtils` to be applied to the call of functions. + ## [released] ## [v1.3.0] - 03-11-2023 diff --git a/README.md b/README.md index be676c27a..61059ea64 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,9 @@ In particular, the appliction is used to access the battery passport data provid ### Software Version #### Helm Chart Version -

1.3.0
+
1.3.1
#### Application Version -
v1.3.0
+
v1.3.1
## Application Preview diff --git a/charts/digital-product-pass/Chart.yaml b/charts/digital-product-pass/Chart.yaml index bb483d910..837a43c37 100644 --- a/charts/digital-product-pass/Chart.yaml +++ b/charts/digital-product-pass/Chart.yaml @@ -40,10 +40,10 @@ type: application # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.3.0 +version: 1.3.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.3.0" +appVersion: "1.3.1" diff --git a/charts/digital-product-pass/README.md b/charts/digital-product-pass/README.md index 67058e396..c038f05da 100644 --- a/charts/digital-product-pass/README.md +++ b/charts/digital-product-pass/README.md @@ -1,6 +1,6 @@ # digital-product-pass -![Version: 1.3.0](https://img.shields.io/badge/Version-1.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.3.0](https://img.shields.io/badge/AppVersion-1.3.0-informational?style=flat-square) +![Version: 1.3.1](https://img.shields.io/badge/Version-1.3.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.3.1](https://img.shields.io/badge/AppVersion-1.3.1-informational?style=flat-square) A Helm chart for Tractus-X Digital Product Pass Kubernetes @@ -15,8 +15,8 @@ A Helm chart for Tractus-X Digital Product Pass Kubernetes | Key | Type | Default | Description | |-----|------|---------|-------------| | affinity | object | `{}` | | -| backend | object | `{"application":{"yml":"# -- spring boot configuration\nspring:\n name: \"Catena-X Product Passport Consumer Backend\"\n main:\n allow-bean-definition-overriding: true\n devtools:\n add-properties: false\n jackson:\n serialization:\n indent_output: true\nlogging:\n level:\n # -- general logging level\n root: INFO\n # -- logging for the util components\n utils: INFO\nconfiguration:\n # -- max retries for the backend services\n maxRetries: 5\n # -- keycloak configuration\n keycloak:\n realm: CX-Central\n resource: Cl13-CX-Battery\n tokenUri: 'https:///auth/realms//protocol/openid-connect/token'\n userInfoUri: 'https:///auth/realms//protocol/openid-connect/userinfo'\n # -- edc consumer connection configuration\n edc:\n endpoint: 'https://'\n management: '/management/v2'\n catalog: '/catalog/request'\n negotiation: '/contractnegotiations'\n transfer: '/transferprocesses'\n receiverEndpoint: 'https:///endpoint'\n delay: 100 # -- Negotiation status Delay in milliseconds in between async requests [<= 500]\n # -- security configuration\n security:\n check:\n enabled: false\n bpn: false\n edc: false\n # -- irs configuration \n irs:\n enabled: true # -- Enable search for children in the requests\n endpoint: \"https://\" # -- IRS endpoint\n paths:\n job: \"/irs/jobs\" # -- API path for calling in the IRS endpoints and staring/getting jobs\n tree:\n fileName: \"treeDataModel\" # -- Tree dataModel filename created in the processId directory\n indent: true # -- Indent tree file\n callbackUrl: \"https:///api/irs\" # -- Backend call back base url for the irs controller\n # -- digital twin registry configuration\n dtr:\n central: false\n # -- central digital twin registry url\n centralUrl: 'https://'\n # -- asset type to search for the registry in the edc\n assetType: 'data.core.digitalTwinRegistry'\n # -- submodel endpoint interface to search\n endpointInterface: 'SUBMODEL-3.0'\n # -- dsp endpoint key inside submodel body\n dspEndpointKey: 'dspEndpoint'\n # -- decentral digital twin apis\n decentralApis:\n search: \"/lookup/shells\"\n digitalTwin: \"/shell-descriptors\"\n subModel: \"/submodel-descriptors\"\n # -- timeouts for the digital twin registry async negotiation\n timeouts:\n search: 10\n negotiation: 40\n transfer: 10\n digitalTwin: 20\n # -- temporary storage of dDTRs for optimization\n temporaryStorage: true\n # -- discovery configuration\n discovery:\n # -- discovery finder configuration\n endpoint: \"https:///discoveryfinder/api/v1.0/administration/connectors/discovery/search\"\n # -- bpn discovery configuration\n bpn:\n key: \"manufacturerPartId\"\n searchPath: \"/api/v1.0/administration/connectors/bpnDiscovery/search\"\n # -- edc discovery configuration\n edc:\n key: \"bpn\"\n # -- process configuration\n process:\n # -- directory for storing the contract negotiation files\n dir: \"process\"\n # -- indent the process negotiation files\n indent: true\n # -- unique sha512 hash key used for the passport encryption\n signKey: \"\"\n # -- passport data transfer configuration\n passport:\n # -- configure the data transfer\n dataTransfer:\n # -- encrypt the passport when he arrives from the edc data plane\n encrypt: true\n # -- the indent from the passport\n indent: true\n # -- directory to store the passport when is not linked to a process\n dir: \"data/transfer\"\n # -- passport versions and aspects allowed\n aspects:\n - \"urn:bamm:io.catenax.generic.digital_product_passport:1.0.0#DigitalProductPassport\"\n - \"urn:bamm:io.catenax.battery.battery_pass:3.0.1#BatteryPass\"\n# -- configuration of the spring boot server\nserver:\n # -- configuration of backend errors\n error:\n include-message: ALWAYS\n include-binding-errors: ALWAYS\n include-stacktrace: ON_PARAM\n include-exception: false\n # -- listening port for the backend\n port: 8888\n # -- maximum allowed connections\n tomcat:\n max-connections: 10000"},"edc":{"clientId":"","clientSecret":"","participantId":"","xApiKey":""},"image":{"pullPolicy":"Always","repository":"docker.io/tractusx/digital-product-pass-backend"},"imagePullSecrets":[],"ingress":{"enabled":false},"name":"dpp-backend","service":{"port":8888,"type":"ClusterIP"}}` | Backend configuration | -| backend.application | object | `{"yml":"# -- spring boot configuration\nspring:\n name: \"Catena-X Product Passport Consumer Backend\"\n main:\n allow-bean-definition-overriding: true\n devtools:\n add-properties: false\n jackson:\n serialization:\n indent_output: true\nlogging:\n level:\n # -- general logging level\n root: INFO\n # -- logging for the util components\n utils: INFO\nconfiguration:\n # -- max retries for the backend services\n maxRetries: 5\n # -- keycloak configuration\n keycloak:\n realm: CX-Central\n resource: Cl13-CX-Battery\n tokenUri: 'https:///auth/realms//protocol/openid-connect/token'\n userInfoUri: 'https:///auth/realms//protocol/openid-connect/userinfo'\n # -- edc consumer connection configuration\n edc:\n endpoint: 'https://'\n management: '/management/v2'\n catalog: '/catalog/request'\n negotiation: '/contractnegotiations'\n transfer: '/transferprocesses'\n receiverEndpoint: 'https:///endpoint'\n delay: 100 # -- Negotiation status Delay in milliseconds in between async requests [<= 500]\n # -- security configuration\n security:\n check:\n enabled: false\n bpn: false\n edc: false\n # -- irs configuration \n irs:\n enabled: true # -- Enable search for children in the requests\n endpoint: \"https://\" # -- IRS endpoint\n paths:\n job: \"/irs/jobs\" # -- API path for calling in the IRS endpoints and staring/getting jobs\n tree:\n fileName: \"treeDataModel\" # -- Tree dataModel filename created in the processId directory\n indent: true # -- Indent tree file\n callbackUrl: \"https:///api/irs\" # -- Backend call back base url for the irs controller\n # -- digital twin registry configuration\n dtr:\n central: false\n # -- central digital twin registry url\n centralUrl: 'https://'\n # -- asset type to search for the registry in the edc\n assetType: 'data.core.digitalTwinRegistry'\n # -- submodel endpoint interface to search\n endpointInterface: 'SUBMODEL-3.0'\n # -- dsp endpoint key inside submodel body\n dspEndpointKey: 'dspEndpoint'\n # -- decentral digital twin apis\n decentralApis:\n search: \"/lookup/shells\"\n digitalTwin: \"/shell-descriptors\"\n subModel: \"/submodel-descriptors\"\n # -- timeouts for the digital twin registry async negotiation\n timeouts:\n search: 10\n negotiation: 40\n transfer: 10\n digitalTwin: 20\n # -- temporary storage of dDTRs for optimization\n temporaryStorage: true\n # -- discovery configuration\n discovery:\n # -- discovery finder configuration\n endpoint: \"https:///discoveryfinder/api/v1.0/administration/connectors/discovery/search\"\n # -- bpn discovery configuration\n bpn:\n key: \"manufacturerPartId\"\n searchPath: \"/api/v1.0/administration/connectors/bpnDiscovery/search\"\n # -- edc discovery configuration\n edc:\n key: \"bpn\"\n # -- process configuration\n process:\n # -- directory for storing the contract negotiation files\n dir: \"process\"\n # -- indent the process negotiation files\n indent: true\n # -- unique sha512 hash key used for the passport encryption\n signKey: \"\"\n # -- passport data transfer configuration\n passport:\n # -- configure the data transfer\n dataTransfer:\n # -- encrypt the passport when he arrives from the edc data plane\n encrypt: true\n # -- the indent from the passport\n indent: true\n # -- directory to store the passport when is not linked to a process\n dir: \"data/transfer\"\n # -- passport versions and aspects allowed\n aspects:\n - \"urn:bamm:io.catenax.generic.digital_product_passport:1.0.0#DigitalProductPassport\"\n - \"urn:bamm:io.catenax.battery.battery_pass:3.0.1#BatteryPass\"\n# -- configuration of the spring boot server\nserver:\n # -- configuration of backend errors\n error:\n include-message: ALWAYS\n include-binding-errors: ALWAYS\n include-stacktrace: ON_PARAM\n include-exception: false\n # -- listening port for the backend\n port: 8888\n # -- maximum allowed connections\n tomcat:\n max-connections: 10000"}` | specific backend and spring boot configurations | +| backend | object | `{"application":{"yml":"# -- spring boot configuration\nspring:\n name: \"Catena-X Product Passport Consumer Backend\"\n main:\n allow-bean-definition-overriding: true\n devtools:\n add-properties: false\n jackson:\n serialization:\n indent_output: true\nlogging:\n level:\n # -- general logging level\n root: INFO\n # -- logging for the util components\n utils: INFO\nconfiguration:\n # -- max retries for the backend services\n maxRetries: 5\n # -- keycloak configuration\n keycloak:\n realm: CX-Central\n resource: Cl13-CX-Battery\n tokenUri: 'https:///auth/realms//protocol/openid-connect/token'\n userInfoUri: 'https:///auth/realms//protocol/openid-connect/userinfo'\n # -- edc consumer connection configuration\n edc:\n endpoint: 'https://'\n management: '/management/v2'\n catalog: '/catalog/request'\n negotiation: '/contractnegotiations'\n transfer: '/transferprocesses'\n receiverEndpoint: 'https:///endpoint'\n delay: 100 # -- Negotiation status Delay in milliseconds in between async requests [<= 500]\n # -- security configuration\n security:\n check:\n enabled: false\n bpn: false\n edc: false\n # -- irs configuration\n irs:\n enabled: true # -- Enable search for children in the requests\n endpoint: \"https://\" # -- IRS endpoint\n paths:\n job: \"/irs/jobs\" # -- API path for calling in the IRS endpoints and staring/getting jobs\n tree:\n fileName: \"treeDataModel\" # -- Tree dataModel filename created in the processId directory\n indent: true # -- Indent tree file\n callbackUrl: \"https:///api/irs\" # -- Backend call back base url for the irs controller\n # -- digital twin registry configuration\n dtr:\n central: false\n # -- central digital twin registry url\n centralUrl: 'https://'\n # -- asset type to search for the registry in the edc\n assetType: 'data.core.digitalTwinRegistry'\n # -- submodel endpoint interface to search\n endpointInterface: 'SUBMODEL-3.0'\n # -- dsp endpoint key inside submodel body\n dspEndpointKey: 'dspEndpoint'\n # -- decentral digital twin apis\n decentralApis:\n search: \"/lookup/shells\"\n digitalTwin: \"/shell-descriptors\"\n subModel: \"/submodel-descriptors\"\n # -- timeouts for the digital twin registry async negotiation\n timeouts:\n search: 10\n negotiation: 40\n transfer: 10\n digitalTwin: 20\n # -- temporary storage of dDTRs for optimization\n temporaryStorage: true\n # -- discovery configuration\n discovery:\n # -- discovery finder configuration\n endpoint: \"https:///discoveryfinder/api/v1.0/administration/connectors/discovery/search\"\n # -- bpn discovery configuration\n bpn:\n key: \"manufacturerPartId\"\n searchPath: \"/api/v1.0/administration/connectors/bpnDiscovery/search\"\n timeout: 2000 # -- timeout in milliseconds for the bpn discovery APIs to respond\n # -- edc discovery configuration\n edc:\n key: \"bpn\"\n timeout: 2000 # -- timeout in milliseconds for the bpn discovery APIs to respond\n # -- process configuration\n process:\n # -- directory for storing the contract negotiation files\n dir: \"process\"\n # -- indent the process negotiation files\n indent: true\n # -- unique sha512 hash key used for the passport encryption\n signKey: \"\"\n # -- passport data transfer configuration\n passport:\n # -- configure the data transfer\n dataTransfer:\n # -- encrypt the passport when he arrives from the edc data plane\n encrypt: true\n # -- the indent from the passport\n indent: true\n # -- directory to store the passport when is not linked to a process\n dir: \"data/transfer\"\n # -- passport versions and aspects allowed\n aspects:\n - \"urn:bamm:io.catenax.generic.digital_product_passport:1.0.0#DigitalProductPassport\"\n - \"urn:bamm:io.catenax.battery.battery_pass:3.0.1#BatteryPass\"\n# -- configuration of the spring boot server\nserver:\n # -- configuration of backend errors\n error:\n include-message: ALWAYS\n include-binding-errors: ALWAYS\n include-stacktrace: ON_PARAM\n include-exception: false\n # -- listening port for the backend\n port: 8888\n # -- maximum allowed connections\n tomcat:\n max-connections: 10000"},"edc":{"clientId":"","clientSecret":"","participantId":"","xApiKey":""},"image":{"pullPolicy":"Always","repository":"docker.io/tractusx/digital-product-pass-backend"},"imagePullSecrets":[],"ingress":{"enabled":false},"name":"dpp-backend","service":{"port":8888,"type":"ClusterIP"}}` | Backend configuration | +| backend.application | object | `{"yml":"# -- spring boot configuration\nspring:\n name: \"Catena-X Product Passport Consumer Backend\"\n main:\n allow-bean-definition-overriding: true\n devtools:\n add-properties: false\n jackson:\n serialization:\n indent_output: true\nlogging:\n level:\n # -- general logging level\n root: INFO\n # -- logging for the util components\n utils: INFO\nconfiguration:\n # -- max retries for the backend services\n maxRetries: 5\n # -- keycloak configuration\n keycloak:\n realm: CX-Central\n resource: Cl13-CX-Battery\n tokenUri: 'https:///auth/realms//protocol/openid-connect/token'\n userInfoUri: 'https:///auth/realms//protocol/openid-connect/userinfo'\n # -- edc consumer connection configuration\n edc:\n endpoint: 'https://'\n management: '/management/v2'\n catalog: '/catalog/request'\n negotiation: '/contractnegotiations'\n transfer: '/transferprocesses'\n receiverEndpoint: 'https:///endpoint'\n delay: 100 # -- Negotiation status Delay in milliseconds in between async requests [<= 500]\n # -- security configuration\n security:\n check:\n enabled: false\n bpn: false\n edc: false\n # -- irs configuration\n irs:\n enabled: true # -- Enable search for children in the requests\n endpoint: \"https://\" # -- IRS endpoint\n paths:\n job: \"/irs/jobs\" # -- API path for calling in the IRS endpoints and staring/getting jobs\n tree:\n fileName: \"treeDataModel\" # -- Tree dataModel filename created in the processId directory\n indent: true # -- Indent tree file\n callbackUrl: \"https:///api/irs\" # -- Backend call back base url for the irs controller\n # -- digital twin registry configuration\n dtr:\n central: false\n # -- central digital twin registry url\n centralUrl: 'https://'\n # -- asset type to search for the registry in the edc\n assetType: 'data.core.digitalTwinRegistry'\n # -- submodel endpoint interface to search\n endpointInterface: 'SUBMODEL-3.0'\n # -- dsp endpoint key inside submodel body\n dspEndpointKey: 'dspEndpoint'\n # -- decentral digital twin apis\n decentralApis:\n search: \"/lookup/shells\"\n digitalTwin: \"/shell-descriptors\"\n subModel: \"/submodel-descriptors\"\n # -- timeouts for the digital twin registry async negotiation\n timeouts:\n search: 10\n negotiation: 40\n transfer: 10\n digitalTwin: 20\n # -- temporary storage of dDTRs for optimization\n temporaryStorage: true\n # -- discovery configuration\n discovery:\n # -- discovery finder configuration\n endpoint: \"https:///discoveryfinder/api/v1.0/administration/connectors/discovery/search\"\n # -- bpn discovery configuration\n bpn:\n key: \"manufacturerPartId\"\n searchPath: \"/api/v1.0/administration/connectors/bpnDiscovery/search\"\n timeout: 2000 # -- timeout in milliseconds for the bpn discovery APIs to respond\n # -- edc discovery configuration\n edc:\n key: \"bpn\"\n timeout: 2000 # -- timeout in milliseconds for the bpn discovery APIs to respond\n # -- process configuration\n process:\n # -- directory for storing the contract negotiation files\n dir: \"process\"\n # -- indent the process negotiation files\n indent: true\n # -- unique sha512 hash key used for the passport encryption\n signKey: \"\"\n # -- passport data transfer configuration\n passport:\n # -- configure the data transfer\n dataTransfer:\n # -- encrypt the passport when he arrives from the edc data plane\n encrypt: true\n # -- the indent from the passport\n indent: true\n # -- directory to store the passport when is not linked to a process\n dir: \"data/transfer\"\n # -- passport versions and aspects allowed\n aspects:\n - \"urn:bamm:io.catenax.generic.digital_product_passport:1.0.0#DigitalProductPassport\"\n - \"urn:bamm:io.catenax.battery.battery_pass:3.0.1#BatteryPass\"\n# -- configuration of the spring boot server\nserver:\n # -- configuration of backend errors\n error:\n include-message: ALWAYS\n include-binding-errors: ALWAYS\n include-stacktrace: ON_PARAM\n include-exception: false\n # -- listening port for the backend\n port: 8888\n # -- maximum allowed connections\n tomcat:\n max-connections: 10000"}` | specific backend and spring boot configurations | | backend.edc | object | `{"clientId":"","clientSecret":"","participantId":"","xApiKey":""}` | in this section we configure the values that are inserted as secrets in the backend | | backend.edc.clientId | string | `""` | note: this credentials need to have access to the Discovery Finder, BPN Discovery and EDC Discovery | | backend.edc.participantId | string | `""` | BPN Number | @@ -38,7 +38,8 @@ A Helm chart for Tractus-X Digital Product Pass Kubernetes | frontend.productpass.idp_url | string | `""` | url of the identity provider service | | frontend.productpass.irs | object | `{"maxWaitingTime":30,"requestDelay":30000}` | irs api timeouts | | frontend.productpass.irs.maxWaitingTime | int | `30` | maximum waiting time to get the irs job status | -| frontend.productpass.irs.requestDelay | int | `30000` | request timeout delay | +| frontend.productpass.irs.requestDelay | int | `30000` | request timeout delay | +| frontend.productpass.keycloak | object | `{"clientId":"","onLoad":"login-required","realm":""}` | keycloak specific configuration for frontend authentication | | frontend.service.port | int | `8080` | | | frontend.service.type | string | `"ClusterIP"` | [Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to expose the running application on a set of Pods as a network service | | name | string | `"digital-product-pass"` | | diff --git a/charts/digital-product-pass/values-beta.yaml b/charts/digital-product-pass/values-beta.yaml index 14d762e1e..9d8affa6f 100644 --- a/charts/digital-product-pass/values-beta.yaml +++ b/charts/digital-product-pass/values-beta.yaml @@ -158,10 +158,10 @@ backend: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" - timeout: 2000 + timeout: 1500 edc: key: "bpn" - timeout: 2000 + timeout: 1500 process: store: true diff --git a/charts/digital-product-pass/values-dev.yaml b/charts/digital-product-pass/values-dev.yaml index 87ad8170d..3a1f8e186 100644 --- a/charts/digital-product-pass/values-dev.yaml +++ b/charts/digital-product-pass/values-dev.yaml @@ -158,10 +158,10 @@ backend: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" - timeout: 2000 + timeout: 1500 edc: key: "bpn" - timeout: 2000 + timeout: 1500 process: store: true diff --git a/charts/digital-product-pass/values-int.yaml b/charts/digital-product-pass/values-int.yaml index e8f654666..3ecb014ad 100644 --- a/charts/digital-product-pass/values-int.yaml +++ b/charts/digital-product-pass/values-int.yaml @@ -157,10 +157,10 @@ backend: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" - timeout: 2000 + timeout: 1500 edc: key: "bpn" - timeout: 2000 + timeout: 1500 process: diff --git a/charts/digital-product-pass/values.yaml b/charts/digital-product-pass/values.yaml index cba595ea7..274a8a32c 100644 --- a/charts/digital-product-pass/values.yaml +++ b/charts/digital-product-pass/values.yaml @@ -190,11 +190,11 @@ backend: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" - timeout: 2000 # -- timeout in milliseconds for the bpn discovery APIs to respond + timeout: 1500 # -- timeout in milliseconds for the bpn discovery APIs to respond # -- edc discovery configuration edc: key: "bpn" - timeout: 2000 # -- timeout in milliseconds for the bpn discovery APIs to respond + timeout: 1500 # -- timeout in milliseconds for the bpn discovery APIs to respond # -- process configuration process: # -- directory for storing the contract negotiation files diff --git a/consumer-backend/productpass/readme.md b/consumer-backend/productpass/readme.md index 63903c467..408c3be81 100644 --- a/consumer-backend/productpass/readme.md +++ b/consumer-backend/productpass/readme.md @@ -23,7 +23,7 @@

  Digital Product Pass Backend

-

Version: 1.0.0

+

Version: v1.3.1


@@ -36,26 +36,22 @@ - [API Services](#api-services) - [Data](#data) - [Passport API](#passport-api) + - [Request body](#request-body) - [Versions Available](#versions-available) - [Contract API](#contract-api) + - [Request body](#request-body-1) + - [Request body](#request-body-2) + - [Request body](#request-body-3) + - [Request body](#request-body-4) + - [Request body](#request-body-5) - [Public APIs](#public-apis) + - [Response](#response) - [OSS License Check](#oss-license-check) - [Swagger Docs](#swagger-docs) - [Run the application](#run-the-application) - [Modify the configurations in the deployment files](#modify-the-configurations-in-the-deployment-files) - [TL;DR](#tldr) - - [Pre-requisites](#pre-requisites) - [Install](#install) - - [Expose the ports](#expose-the-ports) - - [Get pod name](#get-pod-name) - - [Port forward](#port-forward) - - [Check if the application is running](#check-if-the-application-is-running) -- [Frequently asked questions](#frequently-asked-questions) - - [How to install the application and run it locally?](#how-to-install-the-application-and-run-it-locally) - - [Install](#install-1) - - [Run the JAR file](#run-the-jar-file) - - [Configure the secrets](#configure-the-secrets) - - [How to start the application locally using Spring Boot?](#how-to-start-the-application-locally-using-spring-boot) - [License](#license) diff --git a/consumer-backend/productpass/src/main/java/utils/ThreadUtil.java b/consumer-backend/productpass/src/main/java/utils/ThreadUtil.java index 730e014c0..d92333315 100644 --- a/consumer-backend/productpass/src/main/java/utils/ThreadUtil.java +++ b/consumer-backend/productpass/src/main/java/utils/ThreadUtil.java @@ -121,12 +121,14 @@ public static void sleep(Integer milliseconds) } } /** - * Puts the scheduled thread in the runtime that this method is called to sleep for a given time. - *

- * Note: In case of an exception, the thread put to sleep is interrupted. + * Sets a timeout for a function added in a callable *

* @param milliseconds - * the length of time to sleep in milliseconds. + * the {@code Integer} length of time of the timeout in milliseconds. + * @param function + * the {@code Callable} function to be executed and then give the timeout if not returned before + * @param timeoutResponse + * the {@code } timeout response to be returned when the function execution time reached the timeout */ public static V timeout(Integer milliseconds, Callable function, V timeoutResponse) { diff --git a/consumer-backend/productpass/src/main/resources/application.yml b/consumer-backend/productpass/src/main/resources/application.yml index 2e9f99d4a..778385128 100644 --- a/consumer-backend/productpass/src/main/resources/application.yml +++ b/consumer-backend/productpass/src/main/resources/application.yml @@ -95,10 +95,10 @@ configuration: bpn: key: "manufacturerPartId" searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search" - timeout: 2000 + timeout: 1500 edc: key: "bpn" - timeout: 2000 + timeout: 1500 process: diff --git a/docs/RELEASE_USER.md b/docs/RELEASE_USER.md index 29e14c4d9..c350cdba9 100644 --- a/docs/RELEASE_USER.md +++ b/docs/RELEASE_USER.md @@ -23,6 +23,15 @@ # Release Notes Digital Product Pass Application User friendly relase notes without especific technical details. + +**November 08 2023 (Version 1.3.1)** +*08.11.2023* + +### Added +#### Added functionality to timeout when `BPN` and `EDC` Discovery API are taking more than the configured time +Now when the application is creating a process and searching to the BPN discovery and the EDC discovery there is a timeout which can be configured to skip the api call if the timeout expires, in this way when APIs that not exist are added to the `Discovery Service` they will be ignored redusing the waiting time for retrieving the passport. + + **November 03 2023 (Version 1.3.0)** *03.11.2023* diff --git a/package-lock.json b/package-lock.json index 2fa038226..feb75ea98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "digital-product-pass-frontend", - "version": "1.3.0", + "version": "1.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "digital-product-pass-frontend", - "version": "1.3.0", + "version": "1.3.1", "dependencies": { "@mdi/font": "5.9.55", "@popperjs/core": "^2.11.2", diff --git a/package.json b/package.json index 70a3479de..1ec81c1ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "digital-product-pass-frontend", - "version": "1.3.0", + "version": "1.3.1", "private": true, "scripts": { "serve": "vite --host localhost",