Skip to content

Commit

Permalink
Merge pull request #314 from catenax-ng/release/v3.0.0-edc7-integration
Browse files Browse the repository at this point in the history
feat(edc 0.7.0): integrated the latest edc in the backend + e2e bugs solved
  • Loading branch information
matbmoser authored May 13, 2024
2 parents 413683b + 82f4467 commit 1c507d2
Show file tree
Hide file tree
Showing 56 changed files with 1,673 additions and 1,103 deletions.
1 change: 1 addition & 0 deletions DEPENDENCIES_BACKEND
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ maven/mavencentral/org.bouncycastle/bcutil-jdk15on/1.69, MIT, approved, clearlyd
maven/mavencentral/org.checkerframework/checker-qual/3.33.0, MIT, approved, clearlydefined
maven/mavencentral/org.codehaus.plexus/plexus-utils/3.2.1, , approved, CQ20774
maven/mavencentral/org.ow2.asm/asm/9.6, BSD-3-Clause, approved, #10776
maven/mavencentral/org.projectlombok/lombok/1.18.32, MIT AND LicenseRef-Public-Domain, approved, CQ23907
maven/mavencentral/org.reactivestreams/reactive-streams/1.0.4, CC0-1.0, approved, CQ16332
maven/mavencentral/org.slf4j/jul-to-slf4j/2.0.13, MIT, approved, #7698
maven/mavencentral/org.slf4j/slf4j-api/2.0.13, MIT, approved, #5915
Expand Down
2 changes: 1 addition & 1 deletion charts/digital-product-pass/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type: application
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)

version: 2.3.3
version: 2.3.6

# 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ data:
transfer: {{ .Values.backend.edc.apis.transfer }}
receiverEndpoint: "https://{{ .Values.backend.hostname }}/endpoint"
delay: {{ .Values.backend.edc.delay }} # -- Negotiation status Delay in milliseconds in between async requests [<= 500]
authorizationKey: {{ .Values.backend.edc.authorizationKey }}
# -- security configuration
security:
# -- authorization configuration about bpn and role checks
Expand Down
6 changes: 5 additions & 1 deletion charts/digital-product-pass/values-int.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#################################################################################

backend:
image:
pullPolicy: Always
ingress:
enabled: true
# className: "nginx"
Expand Down Expand Up @@ -62,12 +64,14 @@ backend:
discovery:
hostname: "semantics.int.demo.catena-x.net/discoveryfinder"

single-api:
singleApi:
maxRetries: 30
delay: 1000


frontend:
image:
pullPolicy: Always
ingress:
enabled: true
#className: ""
Expand Down
1 change: 1 addition & 0 deletions charts/digital-product-pass/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ backend:
rightOperand: "cx.circular.dpp:1"
prohibition: []
obligation: []

digitalTwinRegistry:
endpoints:
search: "/lookup/shells"
Expand Down
19 changes: 19 additions & 0 deletions docs/RELEASE_USER.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@
# Release Notes Digital Product Pass Application
User friendly relase notes without especific technical details.


**May 13 2024 (Version 3.0.0-rc1)**
*13.05.2024*

### Added

#### Data Sovereighty Configuration enabled

Now in the backend configuration it is possible to add the policies required per contract.
The policy configuration guide can be found here: [Policy Configuration Guide](https://github.com/eclipse-tractusx/digital-product-pass/blob/main/docs/data-sovereignty/PolicyConfigGuide.md)

#### Single API functionality enabled

Now the backend allows users to access and retrieve information without pending of a frontend keyclock authentication. With a single api call `/api/data/request` and the API Key configured in the helm charts values, the backend is allowed to be accessed.

#### EDC 0.7.0 integrated in the application

The Digital Product Pass application now supports the latest edc version available. The new models and payloads have been integrated into the application.

**May 06 2024 (Version 2.3.0)**
*06.05.2024*

Expand Down
28 changes: 28 additions & 0 deletions dpp-backend/digitalproductpass/lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#################################################################################
# Tractus-X - Digital Product Passport Application
#
# Copyright (c) 2022, 2024 BMW AG, Henkel AG & Co. KGaA
# Copyright (c) 2023, 2024 CGI Deutschland B.V. & Co. KG
# Copyright (c) 2022, 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 govern in permissions and limitations
# under the License.
#
# SPDX-License-Identifier: Apache-2.0
#################################################################################


config.stopBubbling = true

lombok.copyableAnnotations += com.fasterxml.jackson.annotation.JsonProperty
10 changes: 8 additions & 2 deletions dpp-backend/digitalproductpass/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@
</parent>
<groupId>org.eclipse.tractusx</groupId>
<artifactId>digitalproductpass</artifactId>
<version>2.3.0</version>
<version>3.0.0</version>
<packaging>jar</packaging>
<name>Catena-X Digital Product Passport Backend</name>
<description>Digital Product Passport Consumer Backend Reference Implementation System for Product Passport Consumer Frontend Application
<description>
Digital Product Passport Consumer Backend is a reference implementation system for retrieving aspect models of digital twins in the Catena-X Network.
</description>
<properties>
<java.version>19</java.version>
Expand Down Expand Up @@ -156,6 +157,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,23 +273,17 @@ public Response getDigitalTwin(@RequestBody Object body, @PathVariable String pr
public EndpointDataReference getEndpointData(Object body) throws ControllerException {
EndpointDataReference endpointData = edcUtil.parseDataPlaneEndpoint(body);
if (endpointData == null) {
throw new ControllerException(this.getClass().getName(), "The endpoint data request is empty!");
throw new ControllerException(this.getClass().getName(), "[EDR] The endpoint data request is empty!");
}
if (endpointData.getEndpoint().isEmpty()) {
throw new ControllerException(this.getClass().getName(), "The data plane endpoint address is empty!");
EndpointDataReference.Properties properties = endpointData.getPayload().getDataAddress().getProperties();
if (properties.getEndpoint().isEmpty()) {
throw new ControllerException(this.getClass().getName(), "[EDR] The data plane endpoint address is empty!");
}
if (endpointData.getAuthCode().isEmpty()) {
throw new ControllerException(this.getClass().getName(), "The authorization code is empty!");
if (endpointData.getPayload().getDataAddress().getProperties().getEndpoint().isEmpty()) {
throw new ControllerException(this.getClass().getName(), "[EDR] The authorization code is empty!");
}
if (endpointData.getContractId().isEmpty() && !endpointData.offerIdExists()) {
Jwt token = httpUtil.parseToken(endpointData.getAuthCode());
if (!token.getPayload().containsKey("cid") || token.getPayload().get("cid").equals("")) {
throw new ControllerException(this.getClass().getName(), "The Offer Id is empty!");
}
return endpointData;
}
if (endpointData.getContractId().isEmpty()) {
throw new ControllerException(this.getClass().getName(), "The contractId is empty!");
if (endpointData.getPayload().getContractId().isEmpty()) {
throw new ControllerException(this.getClass().getName(), "[EDR] The contractId is empty!");
}
return endpointData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

package org.eclipse.tractusx.digitalproductpass.http.controllers.api;

import com.fasterxml.jackson.core.type.TypeReference;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -39,6 +40,7 @@
import org.eclipse.tractusx.digitalproductpass.config.PassportConfig;
import org.eclipse.tractusx.digitalproductpass.config.SingleApiConfig;
import org.eclipse.tractusx.digitalproductpass.managers.ProcessManager;
import org.eclipse.tractusx.digitalproductpass.models.general.Selection;
import org.eclipse.tractusx.digitalproductpass.models.http.Response;
import org.eclipse.tractusx.digitalproductpass.models.http.requests.DiscoverySearch;
import org.eclipse.tractusx.digitalproductpass.models.http.requests.Search;
Expand All @@ -47,6 +49,7 @@
import org.eclipse.tractusx.digitalproductpass.models.manager.Process;
import org.eclipse.tractusx.digitalproductpass.models.manager.Status;
import org.eclipse.tractusx.digitalproductpass.models.negotiation.catalog.Dataset;
import org.eclipse.tractusx.digitalproductpass.models.negotiation.policy.Set;
import org.eclipse.tractusx.digitalproductpass.models.passports.PassportResponse;
import org.eclipse.tractusx.digitalproductpass.services.AasService;
import org.eclipse.tractusx.digitalproductpass.services.AuthenticationService;
Expand All @@ -58,10 +61,7 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import utils.HttpUtil;
import utils.JsonUtil;
import utils.LogUtil;
import utils.ThreadUtil;
import utils.*;
import utils.exceptions.UtilException;

import java.util.List;
Expand Down Expand Up @@ -89,6 +89,8 @@ public class ApiController {
private @Autowired AuthenticationService authService;
private @Autowired PassportConfig passportConfig;
private @Autowired HttpUtil httpUtil;
private @Autowired EdcUtil edcUtil;
private @Autowired PolicyUtil policyUtil;
private @Autowired JsonUtil jsonUtil;
private @Autowired ProcessManager processManager;
private @Autowired SingleApiConfig singleApiConfig;
Expand Down Expand Up @@ -176,7 +178,7 @@ public Response singleApi(@Valid @RequestBody SingleApiRequest singleApiRequestB
try {
createResponseData = (Map<String, String>) jsonUtil.toMap(createResponse.getData());
} catch (UtilException e) {
response = httpUtil.getBadRequest("Create Call:\n" + e.getMessage());
response = httpUtil.getInternalError("Failed in creating process: " + e.getMessage());
return httpUtil.buildResponse(response, httpResponse);
}
String processId= createResponseData.get("processId");
Expand All @@ -196,19 +198,31 @@ public Response singleApi(@Valid @RequestBody SingleApiRequest singleApiRequestB
Map<String, Object> searchResponseData;
Map<String, Dataset> contracts;
try {
searchResponseData = (Map<String, Object>) jsonUtil.toMap(searchResponse.getData());
contracts = (Map<String, Dataset>) jsonUtil.toMap(searchResponseData.get("contracts"));
searchResponseData = jsonUtil.bind(searchResponse.getData(), new TypeReference<>() {});
contracts = jsonUtil.bind(searchResponseData.get("contracts"), new TypeReference<>() {});
} catch (UtilException e) {
response = httpUtil.getBadRequest("Search Call:\n" + e.getMessage());
response = httpUtil.getInternalError("Failed to search for digital twin in dtrs: " + e.getMessage());
return httpUtil.buildResponse(response, httpResponse);
}
LogUtil.printMessage("[SINGLE API] [PROCESS "+processId + "] Search for contracts done! Digital Twin and Contracts available!");
//Call sign function
TokenRequest tokenRequest = new TokenRequest();
tokenRequest.setToken(searchResponseData.get("token").toString());
tokenRequest.setProcessId(searchResponseData.get("id").toString());
String contractId = contracts.entrySet().stream().findFirst().get().getKey();
tokenRequest.setContractId(contractId);
// Get valid contract and policy
Selection<Dataset, Set> selection = edcUtil.selectValidContractAndPolicy(contracts, passportConfig.getPolicyCheck());

if(selection == null){
LogUtil.printError("[SINGLE API] [PROCESS "+processId + "] No valid contracts and policies found!");
response = httpUtil.getNotFound("No valid contracts and policies were found in the asset negotiation!");
return httpUtil.buildResponse(response, httpResponse);
}
LogUtil.printMessage("[SINGLE API] [PROCESS "+processId + "] Selected [CONTRACT "+selection.d().getId()+"]:["+this.jsonUtil.toJson(selection.d(), false)+"]!");
LogUtil.printMessage("[SINGLE API] [PROCESS "+processId + "] Selected [POLICY "+selection.s().getId()+"]:["+this.jsonUtil.toJson(selection.s(), false)+"]!");
// Set contract
tokenRequest.setContractId(selection.d().getId());
// Set policy id
tokenRequest.setPolicyId(selection.s().getId());
Response agreeResponse = contractService.doContractAgreement(httpRequest, httpResponse, tokenRequest);
LogUtil.printMessage("[SINGLE API] [PROCESS "+processId + "] Agreed with a contract and started the contract negotiation!");
//The Status from the response must 200 to proceed
Expand All @@ -220,7 +234,7 @@ public Response singleApi(@Valid @RequestBody SingleApiRequest singleApiRequestB
try {
status = (Status) jsonUtil.bindObject(agreeResponse.getData(), Status.class);
} catch (UtilException e) {
response = httpUtil.getBadRequest("Agree Call:\n" + e.getMessage());
response = httpUtil.getInternalError("Failed to agree in the contract policy: " + e.getMessage());
return httpUtil.buildResponse(response, httpResponse);
}
int retry = 1;
Expand All @@ -239,7 +253,7 @@ public Response singleApi(@Valid @RequestBody SingleApiRequest singleApiRequestB
++retry;
ThreadUtil.sleep(singleApiConfig.getDelay());
} catch (Exception e) {
response = httpUtil.getBadRequest("Status Call:\n" + e.getMessage());
response = httpUtil.getBadRequest("Failed to look for process status: " + e.getMessage());
return httpUtil.buildResponse(response, httpResponse);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ public void started() {
LogUtil.printMessage(
"[ EDC Connection Test ] EDC consumer is ready and accessible!");
if(bpnCheck) {
String bpnNumber = dataTransferService.getEdcConnectorBpn();
if (!participantId.equals(bpnNumber)) {
if (!dataTransferService.isApplicationEdc(participantId)) {
throw new Exception("[" + this.getClass().getName()
+ ".onStartUp] Incorrect BPN Number configuration, expected the same participant id as the EDC consumer!");
}
Expand Down Expand Up @@ -217,6 +216,7 @@ public void onStartUp() {
"**********************************************************************\n\n" +
" " + buildProperties.getName() + "\n" +
" Copyright (c) 2022, 2024: BMW AG, Henkel AG & Co. KGaA\n" +
" Copyright (c) 2023, 2024: CGI Deutschland B.V. & Co. KG\n" +
" Copyright (c) 2022, 2024: Contributors to the Eclipse Foundation.\n\n" +
"**********************************************************************\n\n";
System.out.print(serverStartUpMessage);
Expand Down
Loading

0 comments on commit 1c507d2

Please sign in to comment.