diff --git a/backend/Dockerfile b/backend/Dockerfile
index 2dbe81c6..4b18cce4 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -18,7 +18,7 @@
#
# SPDX-License-Identifier: Apache-2.0
#
-FROM maven:3.9.6-eclipse-temurin-21 as build
+FROM maven:3.9.6-eclipse-temurin-21 AS build
RUN mkdir -p /app/legal
WORKDIR /app
COPY pom.xml .
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/DataInjectionCommandLineRunner.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/DataInjectionCommandLineRunner.java
index ef6793ab..4e87cbb7 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/DataInjectionCommandLineRunner.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/DataInjectionCommandLineRunner.java
@@ -24,9 +24,8 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
+import org.eclipse.tractusx.puris.backend.common.domain.model.measurement.ItemUnitEnumeration;
import org.eclipse.tractusx.puris.backend.common.util.VariablesService;
-import org.eclipse.tractusx.puris.backend.erpadapter.domain.model.ErpAdapterRequest;
-import org.eclipse.tractusx.puris.backend.erpadapter.logic.service.ErpAdapterRequestService;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Material;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.MaterialPartnerRelation;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner;
@@ -38,8 +37,6 @@
import org.eclipse.tractusx.puris.backend.stock.domain.model.ProductItemStock;
import org.eclipse.tractusx.puris.backend.stock.domain.model.ReportedMaterialItemStock;
import org.eclipse.tractusx.puris.backend.stock.domain.model.ReportedProductItemStock;
-import org.eclipse.tractusx.puris.backend.common.domain.model.measurement.ItemUnitEnumeration;
-import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic;
import org.eclipse.tractusx.puris.backend.stock.logic.service.MaterialItemStockService;
import org.eclipse.tractusx.puris.backend.stock.logic.service.ProductItemStockService;
import org.eclipse.tractusx.puris.backend.stock.logic.service.ReportedMaterialItemStockService;
@@ -78,8 +75,6 @@ public class DataInjectionCommandLineRunner implements CommandLineRunner {
@Autowired
private VariablesService variablesService;
- @Autowired
- private ErpAdapterRequestService erpAdapterRequestService;
private ObjectMapper objectMapper;
@@ -246,20 +241,6 @@ private void setupCustomerRole() throws JsonProcessingException {
.locationBpna(supplierPartner.getSites().first().getAddresses().first().getBpna())
.build();
reportedProductItemStockService.create(reportedProductItemStock);
-
- // TODO: remove mock
- ErpAdapterRequest mockRequest = ErpAdapterRequest
- .builder()
- .partnerBpnl(supplierPartner.getBpnl())
- .requestDate(new Date(System.currentTimeMillis()-3*60*60*1000))
- .ownMaterialNumber(semiconductorMaterial.getOwnMaterialNumber())
- .directionCharacteristic(DirectionCharacteristic.INBOUND)
- .requestType("ItemStock")
- .sammVersion("2.0")
- .responseCode(201)
- .build();
- mockRequest = erpAdapterRequestService.create(mockRequest);
- log.info("Created mocked ErpAdapterRequest: \n{}", mockRequest);
}
/**
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/domain/model/AssetType.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/domain/model/AssetType.java
index f9be1cc3..4e435b28 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/domain/model/AssetType.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/domain/model/AssetType.java
@@ -21,19 +21,23 @@
package org.eclipse.tractusx.puris.backend.common.edc.domain.model;
public enum AssetType {
- DTR("none", "none"),
- ITEM_STOCK_SUBMODEL("urn:samm:io.catenax.item_stock:2.0.0#ItemStock", "$value"),
- PRODUCTION_SUBMODEL("urn:samm:io.catenax.planned_production_output:2.0.0#PlannedProductionOutput", "$value"),
- DEMAND_SUBMODEL("urn:samm:io.catenax.short_term_material_demand:1.0.0#ShortTermMaterialDemand", "$value"),
- DELIVERY_SUBMODEL("urn:samm:io.catenax.delivery_information:2.0.0#DeliveryInformation", "$value"),
- NOTIFICATION("urn:samm:io.catenax.demand_and_capacity_notification:2.0.0#DemandAndCapacityNotification", "none"),
- PART_TYPE_INFORMATION_SUBMODEL("urn:samm:io.catenax.part_type_information:1.0.0#PartTypeInformation", "$value");
+ DTR("none", "none", "none", "none"),
+ ITEM_STOCK_SUBMODEL("urn:samm:io.catenax.item_stock:2.0.0#ItemStock", "$value", "ItemStock", "2.0"),
+ PRODUCTION_SUBMODEL("urn:samm:io.catenax.planned_production_output:2.0.0#PlannedProductionOutput", "$value", "PlannedProductionOutput", "2.0"),
+ DEMAND_SUBMODEL("urn:samm:io.catenax.short_term_material_demand:1.0.0#ShortTermMaterialDemand", "$value", "ShortTermMaterialDemand", "1.0"),
+ DELIVERY_SUBMODEL("urn:samm:io.catenax.delivery_information:2.0.0#DeliveryInformation", "$value", "DeliveryInformation", "2.0"),
+ NOTIFICATION("urn:samm:io.catenax.demand_and_capacity_notification:2.0.0#DemandAndCapacityNotification", "none", "none", "2.0"),
+ PART_TYPE_INFORMATION_SUBMODEL("urn:samm:io.catenax.part_type_information:1.0.0#PartTypeInformation", "$value", "none", "1.0");
public final String URN_SEMANTIC_ID;
public final String REPRESENTATION;
+ public final String ERP_KEYWORD;
+ public final String ERP_SAMMVERSION;
- AssetType(String URN_SEMANTIC_ID, String REPRESENTATION) {
+ AssetType(String URN_SEMANTIC_ID, String REPRESENTATION, String ERP_KEYWORD, String ERP_SAMMVERSION) {
this.URN_SEMANTIC_ID = URN_SEMANTIC_ID;
this.REPRESENTATION = REPRESENTATION;
+ this.ERP_KEYWORD = ERP_KEYWORD;
+ this.ERP_SAMMVERSION = ERP_SAMMVERSION;
}
}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/ErpAdapterConfiguration.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/ErpAdapterConfiguration.java
index edcc6871..fd99682c 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/ErpAdapterConfiguration.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/ErpAdapterConfiguration.java
@@ -1,5 +1,6 @@
package org.eclipse.tractusx.puris.backend.erpadapter;
+import lombok.AccessLevel;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@@ -40,4 +41,58 @@ public class ErpAdapterConfiguration {
*/
@Value("${puris.erpadapter.authsecret}")
private String erpAdapterAuthSecret;
+
+ @Value("${puris.erpadapter.refreshinterval}")
+ @Getter(AccessLevel.NONE)
+ private long refreshInterval;
+
+ @Value("${puris.erpadapter.timelimit}")
+ @Getter(AccessLevel.NONE)
+ private long refreshTimeLimit;
+
+ /**
+ * Period since last received partner request after which no more new update requests to the
+ * erp adapter will be sent (milliseconds).
+ * That means: Adding this period to the date and time of the last received request results in that
+ * point in time, when the ErpAdapterTriggerService assumes, that this specific kind of request
+ * is no longer relevant and will stop issuing scheduled update requests to the ErpAdapter.
+ *
+ *
+ * Example: Let's assume we have set this variable to the equivalent of seven days (in milliseconds).
+ * Let's also assume that we have received a request from a specific partner for a specific material
+ * and a specific submodel (and possibly also a specific direction characteristic) on May 15 10:39:21 GMT 2024.
+ *
+ *
+ * Then the ErpAdapterTriggerService will issue scheduled requests for new updates from the ErpAdapter, for at least seven days.
+ *
+ * After seven days (i.e. at or a few seconds after May 22 10:39:21 GMT 2024), and, of course
+ * assuming that we didn't receive any requests with the exact same specifics from the same partner in the meantime,
+ * then no more scheduled requests with these specifics will be sent out to the ErpAdapter.
+ *
+ *
+ * @return the time period
+ */
+ public long getRefreshTimeLimit() {
+ // translate days to milliseconds
+ return refreshTimeLimit * 24 * 60 * 60 * 1000;
+ }
+
+ /**
+ * Interval between two scheduled requests to the erp adapter for the same issue (milliseconds)
+ *
+ * Example: Let's assume, that this variable is set to the equivalent of 3 hours (in milliseconds)
+ * Let's also assume that we have received a request from a specific partner for a specific material
+ * and a specific submodel (and possibly also a specific direction characteristic) on May 15 10:39:21 GMT 2024.
+ *
+ * Then ErpAdapterTriggerService will schedule the next request to the ErpAdapter with the specifics of that aforementioned
+ * request at or a few seconds after May 15 13:39:21 GMT 2024.
+ *
+ * These update requests will perpetuate with the given interval, for as long as the refreshTimeLimit has not expired.
+ *
+ * @return the interval
+ */
+ public long getRefreshInterval() {
+ // translate minutes to milliseconds
+ return refreshInterval * 60 * 1000;
+ }
}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/controller/ErpAdapterController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/controller/ErpAdapterController.java
index 3214296e..595e4cf6 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/controller/ErpAdapterController.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/controller/ErpAdapterController.java
@@ -28,12 +28,16 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import lombok.extern.slf4j.Slf4j;
+import org.eclipse.tractusx.puris.backend.common.edc.domain.model.AssetType;
+import org.eclipse.tractusx.puris.backend.erpadapter.logic.service.ErpAdapterTriggerService;
import org.eclipse.tractusx.puris.backend.erpadapter.logic.service.ItemStockErpAdapterService;
+import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialPartnerRelationService;
+import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
+import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
@@ -48,11 +52,43 @@ public class ErpAdapterController {
@Autowired
private ItemStockErpAdapterService itemStockErpAdapterService;
+ @Autowired
+ private ErpAdapterTriggerService erpAdapterTriggerService;
+
+ @Autowired
+ private MaterialPartnerRelationService mprService;
+
+ @Operation(description = "This endpoint is used to trigger scheduled updates from the ErpAdapter. This is useful " +
+ "if you are expecting a specific request from a partner in the near future and want to make a best-effort attempt to ensure " +
+ "that your PURIS backend has already obtained current data to respond to that expected request, when it arrives. " +
+ "Please note, that calling this endpoint has no significant effect, if a request with the exact same specifics is already " +
+ "currently in place. In that case, a call to this endpoint will only extend the period, after which the scheduled request will " +
+ "be assumed to be irrelevant (see the puris.erpadapter.timelimit property and its documentation for details in this regard). ")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "201", description = "accepted"),
+ @ApiResponse(responseCode = "400", description = "bad request")
+ })
+ @PostMapping("/trigger")
+ public ResponseEntity> scheduleErpUpdate(
+ @RequestParam("partner-bpnl") String bpnl,
+ @RequestParam("own-materialnumber") String materialNumber,
+ @RequestParam("asset-type") AssetType assetType,
+ @RequestParam(required = false, value = "direction") DirectionCharacteristic directionCharacteristic
+ ) {
+ boolean valid = BPNL_PATTERN.matcher(bpnl).matches()
+ && NON_EMPTY_NON_VERTICAL_WHITESPACE_PATTERN.matcher(materialNumber).matches();
+ if (valid && mprService.find(bpnl, materialNumber) != null) {
+ erpAdapterTriggerService.notifyPartnerRequest(bpnl, materialNumber, assetType, directionCharacteristic);
+ return ResponseEntity.status(201).build();
+ } else {
+ return ResponseEntity.badRequest().build();
+ }
+ }
+
+
+
@Operation(description = "This endpoint accepts responses from the ERP adapter. Incoming messages are expected to " +
- "carry a SAMM of the previously requested type. \n\nPlease note that this version currently accepts multiple responses " +
- "addressing the same request-id for testing purposes. However, in the near future, this will be enforced strictly. " +
- "I.e. only the first response for a given request-id will be accepted. All later responses addressing the same request-id" +
- " will be rejected (status code 409)\n\n" +
+ "carry a SAMM of the previously requested type. \n\n" +
"Currently supported: \n\n" +
"| response-type | samm-version |\n" +
"|---------------|--------------|\n" +
@@ -73,24 +109,25 @@ public ResponseEntity> putMethod(
@RequestParam("response-type") String responseType,
@RequestParam("samm-version") String sammVersion,
@RequestParam(value = "response-timestamp")
- @Parameter(example = "2024-05-28T15:00:00")
- @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") Date responseTimestamp,
+ @Parameter(example = "1719295545654", description = "Represented as the number of milliseconds since January 1, 1970, 00:00:00 GMT")
+ long responseTimestamp,
@io.swagger.v3.oas.annotations.parameters.RequestBody(content = {@Content(examples = {
@ExampleObject(itemStock20Sample)
})})
@RequestBody JsonNode requestBody
) {
- boolean valid = BPNL_PATTERN.matcher(partnerBpnl).matches();
- valid = valid && NON_EMPTY_NON_VERTICAL_WHITESPACE_PATTERN.matcher(responseType).matches();
- valid = valid && NON_EMPTY_NON_VERTICAL_WHITESPACE_PATTERN.matcher(sammVersion).matches();
+ boolean valid = BPNL_PATTERN.matcher(partnerBpnl).matches()
+ && NON_EMPTY_NON_VERTICAL_WHITESPACE_PATTERN.matcher(responseType).matches()
+ && NON_EMPTY_NON_VERTICAL_WHITESPACE_PATTERN.matcher(sammVersion).matches();
if (!valid) {
return ResponseEntity.badRequest().build();
}
- Dto dto = new Dto(requestId, partnerBpnl, responseType, sammVersion, responseTimestamp, requestBody);
+ Dto dto = new Dto(requestId, partnerBpnl, responseType, sammVersion, new Date(responseTimestamp), requestBody);
+ AssetType assetType = Arrays.stream(AssetType.values()).filter(type -> type.ERP_KEYWORD.equals(responseType)).findFirst().orElse(null);
int responseCode = 501;
- switch (responseType) {
- case "ItemStock" -> responseCode = itemStockErpAdapterService.receiveItemStockUpdate(dto);
- default -> {
+ switch (assetType) {
+ case ITEM_STOCK_SUBMODEL -> responseCode = itemStockErpAdapterService.receiveItemStockUpdate(dto);
+ case null, default -> {
return ResponseEntity.status(responseCode).body("Unsupported response type: " + responseType);
}
}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/domain/model/ErpAdapterTriggerDataset.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/domain/model/ErpAdapterTriggerDataset.java
new file mode 100644
index 00000000..f2e9c4a4
--- /dev/null
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/domain/model/ErpAdapterTriggerDataset.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2024 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
+ * (represented by Fraunhofer ISST)
+ * 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.puris.backend.erpadapter.domain.model;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.IdClass;
+import lombok.*;
+import org.eclipse.tractusx.puris.backend.common.edc.domain.model.AssetType;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Entity
+@IdClass(ErpAdapterTriggerDataset.Key.class)
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@EqualsAndHashCode
+public class ErpAdapterTriggerDataset {
+
+ @Id
+ private String partnerBpnl;
+
+ @Id
+ private String ownMaterialNumber;
+
+ @Id
+ private AssetType assetType;
+
+ @Id
+ private String directionCharacteristic;
+
+ private long lastPartnerRequest;
+
+ private long nextErpRequestScheduled;
+
+ @Override
+ public String toString() {
+ return "ErpAdapterTriggerDataset{" +
+ "partnerBpnl='" + partnerBpnl + '\'' +
+ ", ownMaterialNumber='" + ownMaterialNumber + '\'' +
+ ", assetType=" + assetType +
+ ", directionCharacteristic='" + directionCharacteristic + '\'' +
+ ", lastPartnerRequest=" + new Date(lastPartnerRequest) +
+ ", nextErpRequestScheduled=" + new Date(nextErpRequestScheduled) +
+ '}';
+ }
+
+ @Getter
+ @Setter
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @EqualsAndHashCode
+ @ToString
+ public static class Key implements Serializable {
+ private String partnerBpnl;
+ private String ownMaterialNumber;
+ private AssetType assetType;
+ private String directionCharacteristic;
+
+ }
+}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/domain/repository/ErpAdapterTriggerDatasetRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/domain/repository/ErpAdapterTriggerDatasetRepository.java
new file mode 100644
index 00000000..02fc1d88
--- /dev/null
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/domain/repository/ErpAdapterTriggerDatasetRepository.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
+ * (represented by Fraunhofer ISST)
+ * 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.puris.backend.erpadapter.domain.repository;
+
+import org.eclipse.tractusx.puris.backend.erpadapter.domain.model.ErpAdapterTriggerDataset;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ErpAdapterTriggerDatasetRepository extends JpaRepository {
+}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ErpAdapterRequestService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ErpAdapterRequestService.java
index 3c7ec974..7595f902 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ErpAdapterRequestService.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ErpAdapterRequestService.java
@@ -50,13 +50,13 @@ public void createAndSend(ErpAdapterRequest erpAdapterRequest) {
if (erpAdapterRequest != null) {
Integer responseCode = erpAdapterRequestClient.sendRequest(erpAdapterRequest);
if (responseCode != null) {
+ erpAdapterRequest.setResponseCode(responseCode);
+ update(erpAdapterRequest);
if (responseCode >= 200 && responseCode < 400) {
log.info("Successfully sent request to ERP Adapter, got status code {} for request:\n{}", responseCode, erpAdapterRequest);
} else {
log.warn("Received status code {} from ERP Adapter for request:\n{}", responseCode, erpAdapterRequest);
}
- erpAdapterRequest.setResponseCode(responseCode);
- update(erpAdapterRequest);
} else {
log.error("Failed to send request to ERP Adapter:\n{}", erpAdapterRequest);
}
@@ -64,9 +64,7 @@ public void createAndSend(ErpAdapterRequest erpAdapterRequest) {
}
public ErpAdapterRequest get(UUID id) {
- // TODO: Remove when mock is removed
- return repository.findById(id).orElse(repository.findAll().getFirst());
-// return repository.findById(id).orElse(null);
+ return repository.findById(id).orElse(null);
}
public ErpAdapterRequest update(ErpAdapterRequest erpAdapterRequest) {
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ErpAdapterTriggerService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ErpAdapterTriggerService.java
new file mode 100644
index 00000000..a4aa6729
--- /dev/null
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ErpAdapterTriggerService.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2024 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
+ * (represented by Fraunhofer ISST)
+ * 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.puris.backend.erpadapter.logic.service;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.tractusx.puris.backend.common.edc.domain.model.AssetType;
+import org.eclipse.tractusx.puris.backend.erpadapter.ErpAdapterConfiguration;
+import org.eclipse.tractusx.puris.backend.erpadapter.domain.model.ErpAdapterRequest;
+import org.eclipse.tractusx.puris.backend.erpadapter.domain.model.ErpAdapterTriggerDataset;
+import org.eclipse.tractusx.puris.backend.erpadapter.domain.repository.ErpAdapterTriggerDatasetRepository;
+import org.eclipse.tractusx.puris.backend.stock.logic.dto.itemstocksamm.DirectionCharacteristic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class ErpAdapterTriggerService {
+
+ @Autowired
+ private ErpAdapterTriggerDatasetRepository repository;
+ @Autowired
+ private ErpAdapterConfiguration erpAdapterConfiguration;
+ @Autowired
+ private ErpAdapterRequestService erpAdapterRequestService;
+ @Autowired
+ private ExecutorService executorService;
+
+ private final long daemonActivityInterval = 1 * 60 * 1000; // daemon wakes up every minute
+
+ private Future> daemonObject;
+
+ private final List datasets = new ArrayList<>();
+
+ /**
+ * protect accesses to the datasets list
+ */
+ private final Lock lock = new ReentrantLock();
+
+ private final Runnable daemon = () -> {
+ log.info("Daemon thread started");
+ while (true) {
+ lock.lock();
+ try {
+ repository.saveAll(datasets);
+ datasets.clear();
+ } finally {
+ lock.unlock();
+ }
+
+ long timeLimit = erpAdapterConfiguration.getRefreshTimeLimit();
+ var allDatasets = repository.findAll();
+ long now = new Date().getTime();
+ log.info("Daemon waking up, found {} datasets", allDatasets.size());
+ for (var dataset : allDatasets) {
+ if (dataset.getLastPartnerRequest() + timeLimit <= now) {
+ // too much time has passed since last request of this kind, so
+ // we will stop triggering further updates from the erp adapter
+ repository.delete(dataset);
+ log.info("Stopped scheduling further requests for : {}", dataset);
+ } else {
+ if (dataset.getNextErpRequestScheduled() <= now) {
+ // the time has come for a new erp adapter request
+ ErpAdapterRequest request = new ErpAdapterRequest();
+ request.setOwnMaterialNumber(dataset.getOwnMaterialNumber());
+ request.setPartnerBpnl(dataset.getPartnerBpnl());
+ request.setRequestDate(new Date(now));
+ DirectionCharacteristic directionCharacteristic = dataset.getDirectionCharacteristic().isEmpty() ?
+ null : DirectionCharacteristic.valueOf(dataset.getDirectionCharacteristic());
+ request.setDirectionCharacteristic(directionCharacteristic);
+ request.setRequestType(dataset.getAssetType().ERP_KEYWORD);
+ request.setSammVersion(dataset.getAssetType().ERP_SAMMVERSION);
+ executorService.submit(() -> erpAdapterRequestService.createAndSend(request));
+
+ // schedule next request
+ dataset.setNextErpRequestScheduled(now + erpAdapterConfiguration.getRefreshInterval());
+ dataset = repository.save(dataset);
+ log.info("Scheduled next erp adapter request: {}", dataset);
+ }
+ }
+ }
+ try {
+ // sleep for the defined interval
+ Thread.sleep(daemonActivityInterval);
+ } catch (InterruptedException ignore) {
+ }
+ }
+ };
+
+ /**
+ * Send a notification about a just received request from a partner via this
+ * method in order to schedule regular updates from the erp adapter.
+ *
+ * @param partnerBpnl the BPNL of the requesting partner
+ * @param ownMaterialNumber the material number of the requested material
+ * @param type the Asset/Submodel type of the request
+ * @param direction the direction characteristic (if applicable for the given asset type, may be null)
+ */
+ public void notifyPartnerRequest(String partnerBpnl, String ownMaterialNumber, AssetType type, DirectionCharacteristic direction) {
+ if (!erpAdapterConfiguration.isErpAdapterEnabled()) {
+ return;
+ }
+ String directionString = direction != null ? direction.name() : "";
+
+ ErpAdapterTriggerDataset dataset = repository.findById(new ErpAdapterTriggerDataset.Key(partnerBpnl,
+ ownMaterialNumber, type, directionString))
+ .orElse(null);
+
+ long now = new Date().getTime();
+ if (dataset == null) {
+ // unknown request specifics, so we trigger a new request right now
+ ErpAdapterRequest erpAdapterRequest = new ErpAdapterRequest();
+ erpAdapterRequest.setRequestDate(new Date(now));
+ erpAdapterRequest.setPartnerBpnl(partnerBpnl);
+ erpAdapterRequest.setOwnMaterialNumber(ownMaterialNumber);
+ erpAdapterRequest.setDirectionCharacteristic(direction);
+ erpAdapterRequest.setRequestType(type.ERP_KEYWORD);
+ erpAdapterRequest.setSammVersion(type.ERP_SAMMVERSION);
+ executorService.submit(() -> erpAdapterRequestService.createAndSend(erpAdapterRequest));
+
+ // create dataset for the daemon thread to schedule future erp adapter requests
+ dataset = new ErpAdapterTriggerDataset(partnerBpnl, ownMaterialNumber, type, directionString, now,
+ now + erpAdapterConfiguration.getRefreshInterval());
+ // it seems safer when only the Daemon thread writes to the repository
+ lock.lock();
+ try {
+ datasets.add(dataset);
+ } finally {
+ lock.unlock();
+ }
+ log.info("Created {}", dataset);
+ } else {
+ // we had previous requests of that kind, so we just store the timestamp of this latest request
+ dataset.setLastPartnerRequest(now);
+ lock.lock();
+ try {
+ datasets.add(dataset);
+ } finally {
+ lock.unlock();
+ }
+ }
+ if (daemonObject == null) {
+ daemonObject = executorService.submit(daemon);
+ }
+ }
+
+}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterService.java
index 4de30753..1ea34bb1 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterService.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/erpadapter/logic/service/ItemStockErpAdapterService.java
@@ -85,11 +85,10 @@ public int receiveItemStockUpdate(ErpAdapterController.Dto dto) {
log.error("Unknown request-id {}", dto.requestId());
return 404;
}
- // TODO: uncomment the following block when removing mock request, also edit swagger description in ErpAdapterController
-// if (request.getResponseReceivedDate() != null) {
-// log.error("Received duplicate response for messageId {}", request.getId());
-// return 409;
-// }
+ if (request.getResponseReceivedDate() != null) {
+ log.error("Received duplicate response for messageId {}", request.getId());
+ return 409;
+ }
if (request.getResponseCode() == null || request.getResponseCode() < 200 || request.getResponseCode() >= 400) {
log.error("Unexpected response, erp adapter had not confirmed request");
return 404;
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/domain/repository/MaterialPartnerRelationRepository.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/domain/repository/MaterialPartnerRelationRepository.java
index aab3f8a1..09bf6ca7 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/domain/repository/MaterialPartnerRelationRepository.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/domain/repository/MaterialPartnerRelationRepository.java
@@ -55,4 +55,6 @@ public interface MaterialPartnerRelationRepository extends JpaRepository findAllByPartnerAndPartnerMaterialNumberAndPartnerBuysMaterialIsTrue(Partner partner, String partnerMaterialNumber);
List findAllByPartnerAndAndPartnerCXNumber(Partner partner, String partnerCXNumber);
+
+ List findAllByPartner_BpnlAndMaterial_OwnMaterialNumber(String bpnl, String ownMaterialNumber);
}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/logic/service/MaterialPartnerRelationService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/logic/service/MaterialPartnerRelationService.java
index df03d0d7..3d457d2f 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/logic/service/MaterialPartnerRelationService.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/logic/service/MaterialPartnerRelationService.java
@@ -70,4 +70,6 @@ public interface MaterialPartnerRelationService {
List findAllByCustomerPartnerAndPartnerMaterialNumber(Partner partner, String partnerMaterialNumber);
MaterialPartnerRelation findByPartnerAndPartnerCXNumber(Partner partner, String partnerCXNumber);
+
+ MaterialPartnerRelation find(String bpnl, String ownMaterialNumber);
}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/logic/service/MaterialPartnerRelationServiceImpl.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/logic/service/MaterialPartnerRelationServiceImpl.java
index 35bfb431..8c489b06 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/logic/service/MaterialPartnerRelationServiceImpl.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/masterdata/logic/service/MaterialPartnerRelationServiceImpl.java
@@ -619,4 +619,16 @@ public MaterialPartnerRelation findByPartnerAndPartnerCXNumber(Partner partner,
return null;
}
}
+
+ @Override
+ public MaterialPartnerRelation find(String bpnl, String ownMaterialNumber) {
+ var results = mprRepository.findAllByPartner_BpnlAndMaterial_OwnMaterialNumber(bpnl, ownMaterialNumber);
+ if (results.isEmpty()) {
+ return null;
+ }
+ if (results.size() > 1) {
+ log.warn("Found more than one MPR for {} and ownMaterialNumber {}", bpnl, ownMaterialNumber);
+ }
+ return results.getFirst();
+ }
}
diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/ItemStockRequestApiService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/ItemStockRequestApiService.java
index 185aa0c9..dbea6832 100644
--- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/ItemStockRequestApiService.java
+++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/stock/logic/service/ItemStockRequestApiService.java
@@ -24,6 +24,7 @@
import lombok.extern.slf4j.Slf4j;
import org.eclipse.tractusx.puris.backend.common.edc.domain.model.AssetType;
import org.eclipse.tractusx.puris.backend.common.edc.logic.service.EdcAdapterService;
+import org.eclipse.tractusx.puris.backend.erpadapter.logic.service.ErpAdapterTriggerService;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Material;
import org.eclipse.tractusx.puris.backend.masterdata.domain.model.Partner;
import org.eclipse.tractusx.puris.backend.masterdata.logic.service.MaterialPartnerRelationService;
@@ -56,6 +57,8 @@ public class ItemStockRequestApiService {
@Autowired
private ReportedMaterialItemStockService reportedMaterialItemStockService;
@Autowired
+ private ErpAdapterTriggerService erpAdapterTriggerService;
+ @Autowired
private EdcAdapterService edcAdapterService;
@Autowired
private ItemStockSammMapper sammMapper;
@@ -76,6 +79,9 @@ public ItemStockSamm handleItemStockSubmodelRequest(String bpnl, String material
if (material != null && mprService.find(material, partner).isPartnerBuysMaterial()) {
// only send an answer if partner is registered as customer
var currentStocks = productItemStockService.findByPartnerAndMaterial(partner, material);
+
+ erpAdapterTriggerService.notifyPartnerRequest(bpnl, material.getOwnMaterialNumber(), AssetType.ITEM_STOCK_SUBMODEL, direction);
+
return sammMapper.productItemStocksToItemStockSamm(currentStocks, partner, material);
}
return null;
@@ -105,8 +111,10 @@ public ItemStockSamm handleItemStockSubmodelRequest(String bpnl, String material
return null;
}
- // only send an answer if partner is registered as supplier
+ // request looks valid
+ erpAdapterTriggerService.notifyPartnerRequest(bpnl, material.getOwnMaterialNumber(), AssetType.ITEM_STOCK_SUBMODEL, direction);
var currentStocks = materialItemStockService.findByPartnerAndMaterial(partner, material);
+
return sammMapper.materialItemStocksToItemStockSamm(currentStocks, partner, material);
}
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index fd6faaae..841b89f2 100755
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -23,9 +23,18 @@ puris.dtr.idp.edc-client.secret.alias=${PURIS_DTR_IDP_EDC-CLIENT_SECRET_ALIAS}
puris.dtr.idp.puris-client.id=${PURIS_DTR_IDP_PURIS-CLIENT_ID:FOSS-DTR-CLIENT}
puris.dtr.idp.puris-client.secret=${PURIS_DTR_IDP_PURIS-CLIENT_SECRET}
puris.erpadapter.enabled=${PURIS_ERPADAPTER_ENABLED:false}
-puris.erpadapter.url=${PURIS_ERPADAPTER_URL:http://my-erpadapter:8080}
+puris.erpadapter.url=${PURIS_ERPADAPTER_URL:http://host.docker.internal:5555/}
puris.erpadapter.authkey=${PURIS_ERPADAPTER_AUTHKEY:x-api-key}
puris.erpadapter.authsecret=${PURIS_ERPADAPTER_AUTHSECRET:erp-password}
+
+# Interval between two requests to the erp adapter for the same issue (minutes)
+puris.erpadapter.refreshinterval=${PURIS_ERPADAPTER_REFRESHINTERVAL:1}
+
+# Period since last received partner request after which no more new update requests to the
+# erp adapter will be sent (days)
+puris.erpadapter.timelimit=${PURIS_ERPADAPTER_TIMELIMIT:7}
+
+
# Flag that decides whether the auto-generation feature of the puris backend is enabled.
# Since all Material entities are required to have a CatenaX-Id, you must enter any pre-existing CatenaX-Id
# via the materials-API of the backend, when you are inserting a new Material entity to the backend's
diff --git a/backend/src/test/resources/application.properties b/backend/src/test/resources/application.properties
index b778d19b..751d490b 100755
--- a/backend/src/test/resources/application.properties
+++ b/backend/src/test/resources/application.properties
@@ -23,9 +23,18 @@ puris.dtr.idp.puris-client.id=${PURIS_DTR_IDP_PURIS-CLIENT_ID:FOSS-DTR-CLIENT}
puris.dtr.idp.puris-client.secret=${PURIS_DTR_IDP_PURIS-CLIENT_SECRET:test}
puris.erpadapter.enabled=${PURIS_ERPADAPTER_ENABLED:false}
-puris.erpadapter.url=${PURIS_ERPADAPTER_URL:http://my-erpadapter:8080}
+puris.erpadapter.url=${PURIS_ERPADAPTER_URL:http://host.docker.internal:5555/}
puris.erpadapter.authkey=${PURIS_ERPADAPTER_AUTHKEY:x-api-key}
puris.erpadapter.authsecret=${PURIS_ERPADAPTER_AUTHSECRET:erp-password}
+
+# Interval between two requests to the erp adapter for the same issue (minutes)
+puris.erpadapter.refreshinterval=${PURIS_ERPADAPTER_REFRESHINTERVAL:1}
+
+# Period since last received partner request after which no more new update requests to the
+# erp adapter will be sent (days)
+puris.erpadapter.timelimit=${PURIS_ERPADAPTER_TIMELIMIT:7}
+
+
puris.generatematerialcatenaxid=${PURIS_GENERATEMATERIALCATENAXID:true}
# DB Configuration
diff --git a/charts/puris/Chart.yaml b/charts/puris/Chart.yaml
index d79e0ccc..de95772b 100644
--- a/charts/puris/Chart.yaml
+++ b/charts/puris/Chart.yaml
@@ -35,7 +35,7 @@ dependencies:
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 2.6.4
+version: 2.7.0
# 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
diff --git a/charts/puris/README.md b/charts/puris/README.md
index 0bd3fac5..781bac80 100644
--- a/charts/puris/README.md
+++ b/charts/puris/README.md
@@ -1,6 +1,6 @@
# puris
-![Version: 2.6.4](https://img.shields.io/badge/Version-2.6.4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.0.2](https://img.shields.io/badge/AppVersion-2.0.2-informational?style=flat-square)
+![Version: 2.7.0](https://img.shields.io/badge/Version-2.7.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.0.2](https://img.shields.io/badge/AppVersion-2.0.2-informational?style=flat-square)
A helm chart for Kubernetes deployment of PURIS
@@ -96,10 +96,11 @@ dependencies:
| backend.puris.edc.controlplane.management.url | string | `"https:/your-edc-address:8181/management"` | Url to the EDC controlplane management of the edc |
| backend.puris.edc.controlplane.protocol.url | string | `"https://your-edc-address:8184/api/v1/dsp"` | Url to the EDC controlplane protocol API of the edc |
| backend.puris.edc.dataplane.public.url | string | `"https://your-data-plane:8285/api/public/"` | Url of one of your data plane's public api |
-| backend.puris.erpadapter.authkey | string | `"x-api-key"` | |
-| backend.puris.erpadapter.authsecret | string | `"erp-password"` | |
-| backend.puris.erpadapter.enabled | bool | `false` | |
-| backend.puris.erpadapter.url | string | `"http://my-erpadapter:8080"` | |
+| backend.puris.erpadapter.authkey | string | `"x-api-key"` | The auth key to be used on your ERP adapter's request api |
+| backend.puris.erpadapter.enabled | bool | `false` | Toggles usage of the ERP adapter |
+| backend.puris.erpadapter.refreshinterval | int | `720` | Interval between two requests to the erp adapter for the same issue (minutes) |
+| backend.puris.erpadapter.timelimit | int | `7` | Period since last received partner request after which no more new update requests to the erp adapter will be sent (days) |
+| backend.puris.erpadapter.url | string | `"http://my-erpadapter:8080"` | The url of your ERP adapter's request api |
| backend.puris.existingSecret | string | `"secret-puris-backend"` | Secret for backend passwords. For more information look into 'backend-secrets.yaml' file. |
| backend.puris.frameworkagreement.credential | string | `"Puris"` | The name of the framework agreement. Starting with Uppercase and using CamelCase. |
| backend.puris.frameworkagreement.version | string | `"1.0"` | The version of the framework agreement, NEEDS TO BE PUT AS "STRING"! |
@@ -221,9 +222,6 @@ dependencies:
| postgresql.service | object | `{"ports":{"postgresql":5432}}` | Possibility to override the name nameOverride: "" |
| postgresql.service.ports.postgresql | int | `5432` | Port of postgres database. |
-----------------------------------------------
-Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1)
-
## NOTICE
This work is licensed under the [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0).
diff --git a/charts/puris/templates/backend-deployment.yaml b/charts/puris/templates/backend-deployment.yaml
index d4327dd9..3d4d59a8 100644
--- a/charts/puris/templates/backend-deployment.yaml
+++ b/charts/puris/templates/backend-deployment.yaml
@@ -175,12 +175,16 @@ spec:
- name: PURIS_ERPADAPTER_URL
value: "{{ .Values.backend.puris.erpadapter.url}}"
- name: PURIS_ERPADAPTER_AUTHKEY
- value: {{ .Values.backend.puris.erpadapter.authkey }}
+ value: "{{ .Values.backend.puris.erpadapter.authkey }}"
- name: PURIS_ERPADAPTER_AUTHSECRET
valueFrom:
secretKeyRef:
name: "{{ .Values.backend.puris.existingSecret }}"
key: "puris-erpadapter-authsecret"
+ - name: PURIS_ERPADAPTER_TIMELIMIT
+ value: "{{ .Values.backend.puris.erpadapter.timelimit }}"
+ - name: PURIS_ERPADAPTER_REFRESHINTERVAL
+ value: "{{ .Values.backend.puris.erpadapter.refreshinterval }}"
######################################
## Additional environment variables ##
diff --git a/charts/puris/values.yaml b/charts/puris/values.yaml
index 17221463..455d30fc 100644
--- a/charts/puris/values.yaml
+++ b/charts/puris/values.yaml
@@ -475,14 +475,17 @@ backend:
# Material entity.
generatematerialcatenaxid: true
erpadapter:
- # Toggles usage of the ERP adapter
+ # -- Toggles usage of the ERP adapter
enabled: false
- # The url of your ERP adapter's request api
+ # -- The url of your ERP adapter's request api
url: http://my-erpadapter:8080
- # The auth key to be used on your ERP adapter's request api
+ # -- The auth key to be used on your ERP adapter's request api
authkey: x-api-key
- # The auth secret to be used on your ERP adapter's request api
- authsecret: erp-password
+ # -- Interval between two requests to the erp adapter for the same issue (minutes)
+ refreshinterval: 720
+ # -- Period since last received partner request after which no more new update requests to the
+ # erp adapter will be sent (days)
+ timelimit: 7
# -- Extra environment variables that will be passed onto the backend deployment pods
env: {}
diff --git a/local/tractus-x-edc/config/customer/puris-backend.properties b/local/tractus-x-edc/config/customer/puris-backend.properties
index af4d7c6d..0731a0be 100644
--- a/local/tractus-x-edc/config/customer/puris-backend.properties
+++ b/local/tractus-x-edc/config/customer/puris-backend.properties
@@ -24,7 +24,8 @@ puris.dtr.idp.edc-client.secret.alias=${CUSTOMER_KC_DTR_PURIS_CLIENT_ALIAS}
puris.dtr.idp.puris-client.id=${KC_MANAGE_CLIENT_ID}
puris.dtr.idp.puris-client.secret=${CUSTOMER_KC_DTR_PURIS_CLIENT_SECRET}
-puris.erpadapter.url=http://my-erpadapter:8080
+puris.erpadapter.enabled=false
+puris.erpadapter.url=http://host.docker.internal:5555/
puris.erpadapter.authkey=x-api-key
puris.erpadapter.authsecret=erp-password
#
diff --git a/local/tractus-x-edc/config/supplier/puris-backend.properties b/local/tractus-x-edc/config/supplier/puris-backend.properties
index 2c0a9bd4..7f672909 100644
--- a/local/tractus-x-edc/config/supplier/puris-backend.properties
+++ b/local/tractus-x-edc/config/supplier/puris-backend.properties
@@ -24,7 +24,8 @@ puris.dtr.idp.edc-client.secret.alias=${SUPPLIER_KC_DTR_PURIS_CLIENT_ALIAS}
puris.dtr.idp.puris-client.id=${KC_MANAGE_CLIENT_ID}
puris.dtr.idp.puris-client.secret=${SUPPLIER_KC_DTR_PURIS_CLIENT_SECRET}
-puris.erpadapter.url=http://my-erpadapter:8080
+puris.erpadapter.enabled=false
+puris.erpadapter.url=http://host.docker.internal:5555/
puris.erpadapter.authkey=x-api-key
puris.erpadapter.authsecret=erp-password
#