Skip to content

Commit

Permalink
Merge pull request #147 from catenax-ng/hotfix/v1.3.1-discovery-services
Browse files Browse the repository at this point in the history
[1º] - Hotfix/v1.3.1-discovery-service: Fixed timeout issue with inexistent BPN and EDC Discoveries listed in the "Discovery Service"
  • Loading branch information
matbmoser authored Nov 8, 2023
2 parents 736a1bc + 42b4c2c commit f492e49
Show file tree
Hide file tree
Showing 18 changed files with 144 additions and 33 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ In particular, the appliction is used to access the battery passport data provid

### Software Version
#### Helm Chart Version
<pre id="helm-version"><a href="https://github.com/eclipse-tractusx/digital-product-pass/releases/tag/digital-product-pass-1.3.0">1.3.0</a></pre>
<pre id="helm-version"><a href="https://github.com/eclipse-tractusx/digital-product-pass/releases/tag/digital-product-pass-1.3.1">1.3.1</a></pre>
#### Application Version
<pre id="app-version"><a href="https://github.com/eclipse-tractusx/digital-product-pass/releases/tag/v1.3.0">v1.3.0</a></pre>
<pre id="app-version"><a href="https://github.com/eclipse-tractusx/digital-product-pass/releases/tag/v1.3.1">v1.3.1</a></pre>


## Application Preview
Expand Down
4 changes: 2 additions & 2 deletions charts/digital-product-pass/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
9 changes: 5 additions & 4 deletions charts/digital-product-pass/README.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion charts/digital-product-pass/values-beta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,10 @@ backend:
bpn:
key: "manufacturerPartId"
searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search"
timeout: 1500
edc:
key: "bpn"
timeout: 1500
process:
store: true
Expand Down
3 changes: 2 additions & 1 deletion charts/digital-product-pass/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,10 @@ backend:
bpn:
key: "manufacturerPartId"
searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search"
timeout: 1500
edc:
key: "bpn"
timeout: 1500
process:
store: true
Expand Down
2 changes: 2 additions & 0 deletions charts/digital-product-pass/values-int.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,10 @@ backend:
bpn:
key: "manufacturerPartId"
searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search"
timeout: 1500
edc:
key: "bpn"
timeout: 1500
process:
Expand Down
2 changes: 2 additions & 0 deletions charts/digital-product-pass/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,11 @@ backend:
bpn:
key: "manufacturerPartId"
searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search"
timeout: 1500 # -- timeout in milliseconds for the bpn discovery APIs to respond
# -- edc discovery configuration
edc:
key: "bpn"
timeout: 1500 # -- timeout in milliseconds for the bpn discovery APIs to respond
# -- process configuration
process:
# -- directory for storing the contract negotiation files
Expand Down
2 changes: 1 addition & 1 deletion consumer-backend/productpass/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</parent>
<groupId>org.eclipse.tractusx</groupId>
<artifactId>productpass</artifactId>
<version>1.3.0</version>
<version>1.3.1</version>
<packaging>jar</packaging>
<name>Catena-X Digital Product Passport Backend</name>
<description>Product Passport Consumer Backend System for Product Passport Consumer Frontend Application
Expand Down
20 changes: 8 additions & 12 deletions consumer-backend/productpass/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<h1 style="display:flex; align-items: center;"><img src="../../docs/catena-x-logo.svg"/>&nbsp;&nbsp;Digital Product Pass Backend</h1>


<h2><strong>Version</strong>: <span style="color: cyan">1.0.0</span><h2>
<h2><strong>Version</strong>: <span style="color: cyan">v1.3.1</span><h2>

<br>

Expand All @@ -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)
<!-- TOC -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public static class BPNConfig {
String key;
String searchPath;

Integer timeout;

/** GETTERS AND SETTERS **/
public String getKey() {
return key;
Expand All @@ -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;
}
}

/**
Expand All @@ -96,13 +106,21 @@ public static class EDCConfig {
/** ATTRIBUTES **/
String key;

Integer timeout;
/** GETTERS AND SETTERS **/
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Integer getTimeout() {
return timeout;
}

public void setTimeout(Integer timeout) {
this.timeout = timeout;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -505,14 +505,15 @@ public List<EdcDiscoveryEndpoint> getEdcDiscovery(List<String> bpns) {
if (edcEndpoints == null) {
throw new ServiceException(this.getClass().getName() + ".getEdcDiscovery", "The edc discovery endpoint is empty!");
}
Integer timeout = discoveryConfig.getEdc().getTimeout();
List<EdcDiscoveryEndpoint> edcDiscoveryResponses = new ArrayList<>();
for(String edcEndpoint : edcEndpoints) {

// Add the technical token
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<EdcDiscoveryEndpoint> edcDiscoveryResponse = (List<EdcDiscoveryEndpoint>) jsonUtil.bindJsonNode(result, List.class);
if(edcDiscoveryResponse.isEmpty()) {
Expand Down Expand Up @@ -567,6 +568,7 @@ public List<BpnDiscovery> 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<BpnDiscovery> bpnDiscoveryResponse = new ArrayList<>();
for(String bpnEndpoint : bpnEndpoints) {

Expand All @@ -585,7 +587,7 @@ public List<BpnDiscovery> 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){
Expand All @@ -595,6 +597,7 @@ public List<BpnDiscovery> 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()){
Expand Down
39 changes: 39 additions & 0 deletions consumer-backend/productpass/src/main/java/utils/HttpUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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
* <p>
* @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<String, ?> params, Object body, Boolean retry, Boolean encode, Integer timeout) {
try {
ResponseEntity<?> response = null;
HttpEntity<Object> 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.
* <p>
Expand Down
39 changes: 34 additions & 5 deletions consumer-backend/productpass/src/main/java/utils/ThreadUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -121,5 +120,35 @@ public static void sleep(Integer milliseconds)
Thread.currentThread().interrupt();
}
}

/**
* Sets a timeout for a function added in a callable
* <p>
* @param milliseconds
* the {@code Integer} length of time of the timeout in milliseconds.
* @param function
* the {@code Callable<V>} function to be executed and then give the timeout if not returned before
* @param timeoutResponse
* the {@code <V>} timeout response to be returned when the function execution time reached the timeout
*/
public static <V> V timeout(Integer milliseconds, Callable<V> function, V timeoutResponse)
{
try {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<V> 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!");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ configuration:
bpn:
key: "manufacturerPartId"
searchPath: "/api/v1.0/administration/connectors/bpnDiscovery/search"
timeout: 1500
edc:
key: "bpn"
timeout: 1500


process:
Expand Down
9 changes: 9 additions & 0 deletions docs/RELEASE_USER.md
Original file line number Diff line number Diff line change
Expand Up @@ -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*

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "digital-product-pass-frontend",
"version": "1.3.0",
"version": "1.3.1",
"private": true,
"scripts": {
"serve": "vite --host localhost",
Expand Down

0 comments on commit f492e49

Please sign in to comment.