Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/irs: Make IRS compatible to the dpp-backend #328

Merged
merged 9 commits into from
Jun 7, 2024
5 changes: 5 additions & 0 deletions charts/digital-product-pass/templates/deployment-backend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#################################################################################

apiVersion: apps/v1
kind: Deployment

Check warning on line 26 in charts/digital-product-pass/templates/deployment-backend.yaml

View workflow job for this annotation

GitHub Actions / Analyze

[MEDIUM] Using Unrecommended Namespace

Namespaces like 'default', 'kube-system' or 'kube-public' should not be used
metadata:
name: {{ .Values.backend.name }}
labels:
Expand All @@ -40,14 +40,14 @@
labels:
{{- include "chart.selectorLabels" . | nindent 8 }}
component: backend
spec:

Check warning on line 43 in charts/digital-product-pass/templates/deployment-backend.yaml

View workflow job for this annotation

GitHub Actions / Analyze

[MEDIUM] Service Account Token Automount Not Disabled

Service Account Tokens are automatically mounted even if not necessary
{{- with .Values.backend.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.backend.podSecurityContext | nindent 8 }}
containers:

Check warning on line 50 in charts/digital-product-pass/templates/deployment-backend.yaml

View workflow job for this annotation

GitHub Actions / Analyze

[MEDIUM] Container Running With Low UID

Check if containers are running with low UID, which might cause conflicts with the host's user table.

Check warning on line 50 in charts/digital-product-pass/templates/deployment-backend.yaml

View workflow job for this annotation

GitHub Actions / Analyze

[MEDIUM] Readiness Probe Is Not Configured

Check if Readiness Probe is not configured.
- name: {{ .Values.backend.name }}
image: "{{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.backend.image.pullPolicy }}
Expand Down Expand Up @@ -84,6 +84,11 @@
secretKeyRef:
key: xApiKey
name: {{ .Release.Name }}-backend-auth
- name: "irs.apiKey"
valueFrom:
secretKeyRef:
key: irsApiKey
name: {{ .Release.Name }}-backend-auth
volumeMounts:
{{- toYaml .Values.backend.volumeMounts | nindent 12 }}
ports:
Expand Down
2 changes: 1 addition & 1 deletion charts/digital-product-pass/templates/secret-backend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-backend-auth

Check warning on line 28 in charts/digital-product-pass/templates/secret-backend.yaml

View workflow job for this annotation

GitHub Actions / Analyze

[MEDIUM] Using Unrecommended Namespace

Namespaces like 'default', 'kube-system' or 'kube-public' should not be used
labels:
{{- include "chart.labels" . | nindent 4 }}
namespace: {{ .Values.namespace }}
Expand All @@ -35,13 +35,13 @@
clientId: {{ .Values.oauth.techUser.clientId }}
clientSecret: {{ .Values.oauth.techUser.clientSecret }}
xApiKey: {{ .Values.oauth.apiKey.secret }}

irsApiKey: {{ .Values.backend.irs.apiKey }}
---

apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-backend-edc-oauth

Check warning on line 44 in charts/digital-product-pass/templates/secret-backend.yaml

View workflow job for this annotation

GitHub Actions / Analyze

[MEDIUM] Using Unrecommended Namespace

Namespaces like 'default', 'kube-system' or 'kube-public' should not be used
labels:
{{- include "chart.labels" . | nindent 4 }}
namespace: {{ .Values.namespace }}
Expand Down
1 change: 1 addition & 0 deletions charts/digital-product-pass/values-int.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ backend:
irs:
enabled: true
hostname: "materialpass-irs.int.demo.catena-x.net"
apiKey: "<path:material-pass/data/int/irs/apiKey#apiKeyRegular>"

process:
encryptionKey: "<path:material-pass/data/int/backend/#signKey>"
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 @@ -172,6 +172,7 @@ backend:
irs:
enabled: false
hostname: ""
apiKey: "<Add API Key>"

# -- digital twin registry configuration
process:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.eclipse.tractusx.digitalproductpass.config.PassportConfig;
import org.eclipse.tractusx.digitalproductpass.exceptions.ManagerException;
import org.eclipse.tractusx.digitalproductpass.models.dtregistry.DigitalTwin;
import org.eclipse.tractusx.digitalproductpass.models.irs.IrsShell;
import org.eclipse.tractusx.digitalproductpass.models.irs.JobHistory;
import org.eclipse.tractusx.digitalproductpass.models.irs.JobResponse;
import org.eclipse.tractusx.digitalproductpass.models.irs.Relationship;
Expand Down Expand Up @@ -236,9 +237,9 @@ public List<NodeComponent> getTreeComponents(String processId){
* @return a {@code DigitalTwin} from the search result OR {@code null} if not found
*
*/
public DigitalTwin searchDigitalTwin(List<DigitalTwin> digitalTwinList, String digitalTwinId){
public IrsShell searchDigitalTwin(List<IrsShell> digitalTwinList, String digitalTwinId){
// Use a parallel search to make the search faster
return digitalTwinList.parallelStream().filter(digitalTwin -> digitalTwin.getGlobalAssetId().equals(digitalTwinId)).findFirst().orElse(new DigitalTwin());
return digitalTwinList.parallelStream().filter(digitalTwin -> digitalTwin.getPayload().getGlobalAssetId().equals(digitalTwinId)).findFirst().orElse(new IrsShell());
}
/**
* Populates a tree with the Job content and the relationships from an specific data model
Expand All @@ -264,9 +265,9 @@ public String populateTree(Map<String, Node> treeDataModel, String processId, Jo
String parentPath = jobHistory.getPath();
Node parent = this.getNodeByPath(treeDataModel, parentPath);
// All the relationships will be of depth one, so we just need to add them in the parent
List<DigitalTwin> digitalTwinList = null;
List<IrsShell> digitalTwinList = null;
try {
digitalTwinList = (List<DigitalTwin>) jsonUtil.bindReferenceType(job.getShells(), new TypeReference<List<DigitalTwin>>() {});
digitalTwinList = (List<IrsShell>) jsonUtil.bindReferenceType(job.getShells(), new TypeReference<List<IrsShell>>() {});
} catch (Exception e) {
throw new ManagerException(this.getClass().getName(), e, "Could not bind the reference type for the Digital Twin!");
}
Expand All @@ -280,7 +281,9 @@ public String populateTree(Map<String, Node> treeDataModel, String processId, Jo
for(Relationship relationship : relationships){
String childId = relationship.getLinkedItem().getChildCatenaXId();
// Search for the Digital Twin from the child or a new instance
DigitalTwin childDigitalTwin = this.searchDigitalTwin(digitalTwinList, childId);
IrsShell shell = this.searchDigitalTwin(digitalTwinList, childId);
DigitalTwin childDigitalTwin = shell.getPayload();
// DigitalTwin childDigitalTwin = jsonUtil.bindReferenceType(this.searchDigitalTwin(digitalTwinList, childId).getPayload(),new DigitalTwin());
if(childDigitalTwin.getGlobalAssetId().isEmpty()){
childDigitalTwin.setGlobalAssetId(childId);
}
Expand Down Expand Up @@ -495,9 +498,4 @@ public String setChild(String processId, String parentPath, Node childNode, Stri
throw new ManagerException(this.getClass().getName()+".setChild()", e, "It was not possible to get the node from the tree");
}
}





}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*********************************************************************************
*
* 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
********************************************************************************/

package org.eclipse.tractusx.digitalproductpass.models.irs;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import org.eclipse.tractusx.digitalproductpass.models.dtregistry.DigitalTwin;

import java.util.ArrayList;

/**
* This class consists exclusively to define attributes related to the Job Response coming from the IRS.
**/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class IrsShell {

/**
* ATTRIBUTES
**/
@JsonProperty("contractAgreementId")
public String contractAgreementId;
@JsonProperty("payload")
public DigitalTwin payload;


/**
* CONSTRUCTORS
**/
public IrsShell() {
}

public IrsShell(String contractAgreementId, DigitalTwin payload) {
this.contractAgreementId = contractAgreementId;
this.payload = payload;
}

/**
* GETTERS AND SETTERS
**/
public String getContractAgreementId() {
return contractAgreementId;
}

public void setContractAgreementId(String contractAgreementId) {
this.contractAgreementId = contractAgreementId;
}

public DigitalTwin getPayload() {
return payload;
}

public void setPayload(DigitalTwin payload) {
this.payload = payload;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import org.eclipse.tractusx.digitalproductpass.models.dtregistry.DigitalTwin;

import java.util.ArrayList;

Expand All @@ -47,7 +46,7 @@ public class JobResponse {
@JsonProperty("relationships")
public ArrayList<Relationship> relationships;
@JsonProperty("shells")
public ArrayList<DigitalTwin> shells;
public ArrayList<IrsShell> shells;
@JsonProperty("tombstones")
public Object tombstones;
@JsonProperty("submodels")
Expand All @@ -56,7 +55,7 @@ public class JobResponse {
public ArrayList<String> bpns;

/** CONSTRUCTOR(S) **/
public JobResponse(Job job, ArrayList<Relationship> relationships, ArrayList<DigitalTwin> shells, Object tombstones, ArrayList<JsonNode> submodels, ArrayList<String> bpns) {
public JobResponse(Job job, ArrayList<Relationship> relationships, ArrayList<IrsShell> shells, Object tombstones, ArrayList<JsonNode> submodels, ArrayList<String> bpns) {
this.job = job;
this.relationships = relationships;
this.shells = shells;
Expand Down Expand Up @@ -85,11 +84,11 @@ public void setRelationships(ArrayList<Relationship> relationships) {
this.relationships = relationships;
}

public ArrayList<DigitalTwin> getShells() {
public ArrayList<IrsShell> getShells() {
return shells;
}

public void setShells(ArrayList<DigitalTwin> shells) {
public void setShells(ArrayList<IrsShell> shells) {
this.shells = shells;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class IrsService extends BaseService {
String irsEndpoint;
String irsJobPath;
String callbackUrl;
String apiKey;
AuthenticationService authService;
IrsConfig irsConfig;
ProcessManager processManager;
Expand Down Expand Up @@ -96,6 +97,7 @@ public void init(Environment env) {
this.irsEndpoint = this.irsConfig.getEndpoint();
this.irsJobPath = this.irsConfig.getPaths().getJob();
this.callbackUrl = this.irsConfig.getCallbackUrl();
this.apiKey = (String) this.vaultService.getLocalSecret("irs.apiKey");
}
/**
* Creates a List of missing variables needed to proceed with the request.
Expand All @@ -116,6 +118,9 @@ public List<String> getEmptyVariables() {
if (this.callbackUrl.isEmpty()) {
missingVariables.add("irs.callbackUrl");
}
if (this.apiKey.isEmpty()) {
missingVariables.add("irs.apiKey");
}
return missingVariables;
}
/**
Expand Down Expand Up @@ -163,7 +168,7 @@ public Map<String, String> startJob(String processId, String globalAssetId, Stri
public Map<String, String> startJob(String processId, String globalAssetId, String searchId, String bpn) {
try {
this.checkEmptyVariables();
String url = this.irsEndpoint + "/" + this.irsJobPath;
String url = this.irsEndpoint + this.irsJobPath;
// Build the Job request for the IRS

String backendUrl = this.callbackUrl + "/" + processId + "/" + searchId; // Add process id and search id
Expand All @@ -183,7 +188,7 @@ public Map<String, String> startJob(String processId, String globalAssetId, Str
callbackUrl
);
body.setKey(globalAssetId, bpn);
HttpHeaders headers = httpUtil.getHeadersWithToken(this.authService.getToken().getAccessToken());
HttpHeaders headers = httpUtil.getHeadersWithApiKey(this.apiKey);
headers.add("Content-Type", "application/json");

ResponseEntity<?> response = httpUtil.doPost(url, JsonNode.class, headers, httpUtil.getParams(), body, false, false);
Expand Down Expand Up @@ -283,7 +288,7 @@ public JobResponse getJob(String jobId) {
try {
String url = this.irsEndpoint + "/" + this.irsJobPath + "/" + jobId;
Map<String, Object> params = httpUtil.getParams();
HttpHeaders headers = httpUtil.getHeadersWithToken(this.authService.getToken().getAccessToken());
HttpHeaders headers = httpUtil.getHeadersWithApiKey(this.apiKey);
ResponseEntity<?> response = httpUtil.doGet(url, String.class, headers, params, true, false);
String responseBody = (String) response.getBody();
return (JobResponse) jsonUtil.bindJsonNode(jsonUtil.toJsonNode(responseBody), JobResponse.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,11 @@ public HttpHeaders getHeadersWithToken(String accessToken) {
headers.add("Authorization", "Bearer " + accessToken);
return headers;
}
public HttpHeaders getHeadersWithApiKey(String apiKey) {
HttpHeaders headers = new HttpHeaders();
headers.add("X-Api-Key", apiKey);
return headers;
}
public Map<String, Object> getParams() {
return new HashMap<String, Object>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ configuration:
- "edc.apiKey"
- "edc.participantId"
- "oauth.apiKey"
- "irs.apiKey"

server:
error:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ void setUpAll() throws ServiceInitializationException {
when(vaultService.getLocalSecret("client.id")).thenReturn(mockClientId);
when(vaultService.getLocalSecret("client.secret")).thenReturn(mockClientTestReturn);

when(vaultService.getLocalSecret("edc.apiKey")).thenReturn(mockApiKey);
when(vaultService.getLocalSecret("irs.apiKey")).thenReturn(mockApiKey);
when(vaultService.getLocalSecret("edc.participantId")).thenReturn(mockBpn);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ configuration:
- "edc.apiKey"
- "edc.participantId"
- "oauth.apiKey"
- "irs.apiKey"

server:
error:
Expand Down
Loading
Loading