diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/controller/EdcController.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/controller/EdcController.java index d832e5d3..e4baf04d 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/controller/EdcController.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/controller/EdcController.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; +import okhttp3.Response; import org.eclipse.tractusx.puris.backend.common.edc.logic.service.EdcAdapterService; import org.eclipse.tractusx.puris.backend.common.util.PatternStore; import org.springframework.beans.factory.annotation.Autowired; @@ -49,6 +50,11 @@ public class EdcController { @Autowired private ObjectMapper objectMapper; + private static final String CATALOG = "catalog"; + private static final String ASSETS = "assets"; + private static final String CONTRACTNEGOTIATIONS = "contractnegotiations"; + private static final String TRANSFERS = "transfers"; + /** * Get the catalog from an EDC. @@ -56,16 +62,30 @@ public class EdcController { * @param dspUrl url of the edc to get catalog from. * @return catalog of the requested edc. */ - @GetMapping("/catalog") + @GetMapping(CATALOG) public ResponseEntity getCatalog(@RequestParam String dspUrl) { try { if (!PatternStore.URL_PATTERN.matcher(dspUrl).matches()) { return ResponseEntity.badRequest().build(); } - var catalog = edcAdapter.getCatalog(dspUrl); - return ResponseEntity.ok(catalog.toPrettyString()); + var catalogResponse = edcAdapter.getCatalogResponse(dspUrl); + if (catalogResponse != null && catalogResponse.isSuccessful()) { + var responseString = catalogResponse.body().string(); + catalogResponse.body().close(); + return ResponseEntity.ok(responseString); + } else { + if (catalogResponse != null) { + log.warn(statusCodeMessageGenerator(CATALOG, catalogResponse.code())); + if (catalogResponse.body() != null) { + catalogResponse.body().close(); + } + } else { + log.warn(noResponseMessageGenerator(CATALOG)); + } + return ResponseEntity.badRequest().build(); + } } catch (IOException e) { - log.warn(e.getMessage()); + log.error(exceptionMessageGenerator(CATALOG), e); return ResponseEntity.internalServerError().build(); } } @@ -76,18 +96,30 @@ public ResponseEntity getCatalog(@RequestParam String dspUrl) { * @param assetId optional parameter if only a specific asset should be retrieved. * @return response from own EDC. */ - @GetMapping("/assets") + @GetMapping(ASSETS) public ResponseEntity getAssets(@RequestParam String assetId) { try { if (!PatternStore.NON_EMPTY_NON_VERTICAL_WHITESPACE_STRING.matches(assetId)) { return ResponseEntity.badRequest().build(); } - var result = edcAdapter.sendGetRequest(List.of("v3", "assets", assetId)); - var stringData = result.body().string(); - result.body().close(); - return ResponseEntity.ok(stringData); + var assetsResponse = edcAdapter.sendGetRequest(List.of("v3", ASSETS, assetId)); + if (assetsResponse != null && assetsResponse.isSuccessful()) { + var stringData = assetsResponse.body().string(); + assetsResponse.body().close(); + return ResponseEntity.ok(stringData); + } else { + if (assetsResponse != null) { + log.warn(statusCodeMessageGenerator(ASSETS, assetsResponse.code())); + if (assetsResponse.body() != null) { + assetsResponse.body().close(); + } + } else { + log.warn(noResponseMessageGenerator(ASSETS)); + } + return ResponseEntity.badRequest().build(); + } } catch (IOException e) { - log.warn(e.getMessage()); + log.error(exceptionMessageGenerator(ASSETS), e); return ResponseEntity.internalServerError().build(); } } @@ -98,13 +130,28 @@ public ResponseEntity getAssets(@RequestParam String assetId) { * * @return contract negotiation data */ - @GetMapping("/contractnegotiations") + @GetMapping(CONTRACTNEGOTIATIONS) public ResponseEntity getContractNegotiations() { try { - String data = edcAdapter.getAllNegotiations(); - return ResponseEntity.ok(data); + Response negotiationsResponse = edcAdapter.getAllNegotiations(); + if (negotiationsResponse != null && negotiationsResponse.isSuccessful()) { + String responseString = negotiationsResponse.body().string(); + negotiationsResponse.body().close(); + return ResponseEntity.ok(responseString); + } else { + if (negotiationsResponse != null) { + log.warn(statusCodeMessageGenerator(CONTRACTNEGOTIATIONS, negotiationsResponse.code())); + if (negotiationsResponse.body() != null) { + negotiationsResponse.body().close(); + } + } else { + log.warn(noResponseMessageGenerator(CONTRACTNEGOTIATIONS)); + } + return ResponseEntity.internalServerError().build(); + } + } catch (Exception e) { - log.warn(e.getMessage()); + log.error(exceptionMessageGenerator(CONTRACTNEGOTIATIONS), e); return ResponseEntity.internalServerError().build(); } } @@ -115,30 +162,53 @@ public ResponseEntity getContractNegotiations() { * * @return transfer data */ - @GetMapping("/transfers") + @GetMapping(TRANSFERS) public ResponseEntity getTransfers() { try { - String data = edcAdapter.getAllTransfers(); - var responseObject = objectMapper.readTree(data); - for (var item : responseObject) { - // The response from the control plane does not contain - // an edc:connectorId field, if your side was involved as PROVIDER - // in a transfer. Because we want to show the other party's - // BPNL in the frontend in any case, we retrieve the BPNL via - // the contractAgreement and insert it into the JSON data. - String myRole = item.get("edc:type").asText(); - if ("PROVIDER".equals(myRole)) { - String contractId = item.get("edc:contractId").asText(); - var contractObject = objectMapper.readTree(edcAdapter.getContractAgreement(contractId)); - String partnerBpnl = contractObject.get("edc:consumerId").asText(); - ((ObjectNode) item).put("edc:connectorId", partnerBpnl); + Response transfersResponse = edcAdapter.getAllTransfers(); + if (transfersResponse != null && transfersResponse.isSuccessful()) { + String data = transfersResponse.body().string(); + var responseObject = objectMapper.readTree(data); + for (var item : responseObject) { + // The response from the control plane does not contain + // an edc:connectorId field, if your side was involved as PROVIDER + // in a transfer. Because we want to show the other party's + // BPNL in the frontend in any case, we retrieve the BPNL via + // the contractAgreement and insert it into the JSON data. + String myRole = item.get("edc:type").asText(); + if ("PROVIDER".equals(myRole)) { + String contractId = item.get("edc:contractId").asText(); + var contractObject = objectMapper.readTree(edcAdapter.getContractAgreement(contractId)); + String partnerBpnl = contractObject.get("edc:consumerId").asText(); + ((ObjectNode) item).put("edc:connectorId", partnerBpnl); + } + } + return ResponseEntity.ok(responseObject); + } else { + if (transfersResponse != null) { + log.warn(statusCodeMessageGenerator(TRANSFERS, transfersResponse.code())); + if (transfersResponse.body() != null) { + transfersResponse.body().close(); + } } + return ResponseEntity.internalServerError().build(); } - return ResponseEntity.ok(responseObject); } catch (Exception e) { - log.warn(e.getMessage()); + log.error(exceptionMessageGenerator(TRANSFERS), e); return ResponseEntity.internalServerError().build(); } } + private String exceptionMessageGenerator(String endpointName) { + return "Exception in " + endpointName + " endpoint "; + } + + private String statusCodeMessageGenerator(String endpointName, int code) { + return endpointName + " endpoint received status code " + code; + } + + private String noResponseMessageGenerator(String endpointName) { + return endpointName + " endpoint received no response"; + } + } diff --git a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/logic/service/EdcAdapterService.java b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/logic/service/EdcAdapterService.java index ddd84fc1..4d49fb37 100644 --- a/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/logic/service/EdcAdapterService.java +++ b/backend/src/main/java/org/eclipse/tractusx/puris/backend/common/edc/logic/service/EdcAdapterService.java @@ -103,20 +103,6 @@ private Response sendPostRequest(JsonNode requestBody, List pathSegments return CLIENT.newCall(request).execute(); } - private Response sendDtrPostRequest(JsonNode requestBody, List pathSegments) throws IOException { - HttpUrl.Builder urlBuilder = HttpUrl.parse(variablesService.getDtrUrl() + "/api/v3.0").newBuilder(); - for (var pathSegment : pathSegments) { - urlBuilder.addPathSegment(pathSegment); - } - RequestBody body = RequestBody.create(requestBody.toString(), MediaType.parse("application/json")); - var request = new Request.Builder() - .post(body) - .url(urlBuilder.build()) - .header("Content-Type", "application/json") - .build(); - return CLIENT.newCall(request).execute(); - } - /** * Call this method at startup to register the necessary request and * response apis. In case you are using the framework agreement feature, @@ -287,6 +273,17 @@ private boolean registerApiAsset(DT_ApiMethodEnum apiMethod) { } } + + /** + * Retrieve the response to an unfiltered catalog request from the partner + * with the given dspUrl + * @param dspUrl The dspUrl of your partner + * @return The response containing the full catalog, if successful + */ + public Response getCatalogResponse(String dspUrl) throws IOException { + return sendPostRequest(edcRequestBodyBuilder.buildBasicCatalogRequestBody(dspUrl, null), List.of("v2", "catalog", "request")); + } + /** * Retrieve an (unfiltered) catalog from the partner with the * given dspUrl @@ -296,7 +293,7 @@ private boolean registerApiAsset(DT_ApiMethodEnum apiMethod) { * @throws IOException If the connection to the partners control plane fails */ public JsonNode getCatalog(String dspUrl) throws IOException { - try (var response = sendPostRequest(edcRequestBodyBuilder.buildBasicCatalogRequestBody(dspUrl, null), List.of("v2", "catalog", "request"))) { + try (var response = getCatalogResponse(dspUrl)) { String stringData = response.body().string(); return objectMapper.readTree(stringData); } @@ -343,11 +340,9 @@ public JsonNode getNegotiationState(String negotiationId) throws IOException { * @return The response body as String * @throws IOException If the connection to your control plane fails */ - public String getAllNegotiations() throws IOException { + public Response getAllNegotiations() throws IOException { var requestBody = edcRequestBodyBuilder.buildNegotiationsRequestBody(); - try (var response = sendPostRequest(requestBody, List.of("v2", "contractnegotiations", "request"))) { - return response.body().string(); - } + return sendPostRequest(requestBody, List.of("v2", "contractnegotiations", "request")); } /** @@ -388,15 +383,12 @@ public JsonNode getTransferState(String transferId) throws IOException { * Sends a request to the own control plane in order to receive * a list of all transfers. * - * @return The response body as String + * @return The response * @throws IOException If the connection to your control plane fails */ - public String getAllTransfers() throws IOException { + public Response getAllTransfers() throws IOException { var requestBody = edcRequestBodyBuilder.buildTransfersRequestBody(); - try (var response = sendPostRequest(requestBody, List.of("v2", "transferprocesses", "request"))) { - String data = response.body().string(); - return data; - } + return sendPostRequest(requestBody, List.of("v2", "transferprocesses", "request")); } /**