From 16b7c4f3e7a956b7487aaa77b91e7e291e646847 Mon Sep 17 00:00:00 2001 From: nipuni Date: Tue, 29 Oct 2024 17:27:46 +0530 Subject: [PATCH 1/3] Fix error response formatting issue. --- .../interceptor/beans/ErrorResponse.java | 55 +++++++++++++++++++ .../request/interceptor/util/HandlerUtil.java | 32 ++++++++--- 2 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 components/ui-request-interceptor/io.entgra.device.mgt.core.ui.request.interceptor/src/main/java/io/entgra/device/mgt/core/ui/request/interceptor/beans/ErrorResponse.java diff --git a/components/ui-request-interceptor/io.entgra.device.mgt.core.ui.request.interceptor/src/main/java/io/entgra/device/mgt/core/ui/request/interceptor/beans/ErrorResponse.java b/components/ui-request-interceptor/io.entgra.device.mgt.core.ui.request.interceptor/src/main/java/io/entgra/device/mgt/core/ui/request/interceptor/beans/ErrorResponse.java new file mode 100644 index 0000000000..febfa20df0 --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.device.mgt.core.ui.request.interceptor/src/main/java/io/entgra/device/mgt/core/ui/request/interceptor/beans/ErrorResponse.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://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. + */ +package io.entgra.device.mgt.core.ui.request.interceptor.beans; + +public class ErrorResponse { + private int code; + private String data; + private int status; + + public ErrorResponse(int code, String data, int status) { + this.code = code; + this.data = data; + this.status = status; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } +} + diff --git a/components/ui-request-interceptor/io.entgra.device.mgt.core.ui.request.interceptor/src/main/java/io/entgra/device/mgt/core/ui/request/interceptor/util/HandlerUtil.java b/components/ui-request-interceptor/io.entgra.device.mgt.core.ui.request.interceptor/src/main/java/io/entgra/device/mgt/core/ui/request/interceptor/util/HandlerUtil.java index 98d8e42c64..f1a33fb2f7 100644 --- a/components/ui-request-interceptor/io.entgra.device.mgt.core.ui.request.interceptor/src/main/java/io/entgra/device/mgt/core/ui/request/interceptor/util/HandlerUtil.java +++ b/components/ui-request-interceptor/io.entgra.device.mgt.core.ui.request.interceptor/src/main/java/io/entgra/device/mgt/core/ui/request/interceptor/util/HandlerUtil.java @@ -20,17 +20,16 @@ package io.entgra.device.mgt.core.ui.request.interceptor.util; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.node.TextNode; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import io.entgra.device.mgt.core.ui.request.interceptor.beans.AuthData; +import io.entgra.device.mgt.core.ui.request.interceptor.beans.ErrorResponse; import io.entgra.device.mgt.core.ui.request.interceptor.cache.LoginCache; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; @@ -227,16 +226,37 @@ public class HandlerUtil { proxyResponse.setExecutorResponse(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX + HandlerUtil .getStatusKey(HandlerConstants.INTERNAL_ERROR_CODE)); } + JsonNode dataNode = proxyResponse.getData(); + String responseData = extractDataAsString(dataNode); resp.setStatus(proxyResponse.getCode()); resp.setContentType(ContentType.APPLICATION_JSON.getMimeType()); resp.setCharacterEncoding(Consts.UTF_8.name()); proxyResponse.setExecutorResponse(null); + proxyResponse.setData(null); + ErrorResponse errorResponse = new ErrorResponse( + proxyResponse.getCode(), + responseData, + proxyResponse.getStatus() + ); try (PrintWriter writer = resp.getWriter()) { - writer.write(gson.toJson(proxyResponse)); + writer.write(gson.toJson(errorResponse)); } } + /** + * Extracts a string representation from the given JsonNode. + * + * @param dataNode the JsonNode from which to extract the string representation (can be null). + * @return the string representation of the JsonNode, or null if the dataNode is null. + */ + private static String extractDataAsString(JsonNode dataNode) { + if (dataNode == null) { + return null; + } + return dataNode.isTextual() ? dataNode.asText() : dataNode.toString(); + } + /** * Handle error requests with custom error codes. * @@ -772,9 +792,7 @@ public class HandlerUtil { try { finalNode = objectMapper.readTree(content); } catch (JsonProcessingException e) { - ObjectNode objectNode = objectMapper.createObjectNode(); - objectNode.put("message", content); - finalNode = objectMapper.valueToTree(objectNode); + finalNode = new TextNode(content); } } return finalNode; From 5853e529c7bba778ac60058a86f84d23a223f570 Mon Sep 17 00:00:00 2001 From: nipuni Date: Tue, 29 Oct 2024 21:46:03 +0530 Subject: [PATCH 2/3] Fix throwing NullPointerException when getting a fileName with a query param. --- .../impl/FileDownloaderServiceProvider.java | 53 +++++++++++++------ .../util/FileTransferServiceHelperUtil.java | 10 +++- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/FileDownloaderServiceProvider.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/FileDownloaderServiceProvider.java index f8fe6f2f94..7c8ad99533 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/FileDownloaderServiceProvider.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/FileDownloaderServiceProvider.java @@ -132,9 +132,21 @@ public class FileDownloaderServiceProvider { } /** - * Extracting file name segments by parsing the URL - * @param url Remote URL to extract file name segments - * @return Array containing file name segments or null when failed to extract + * Extracts file name segments (name and extension) by parsing the given URL. + * This method handles two types of URL formats: + * - If the URL includes a query parameter in the format `?fileName=`, the file name + * is extracted from this query parameter (ex: when referencing an existing + * screenshot or icon from the main release) + * - If the URL does not have the `fileName` query parameter, the method attempts to + * extract the file name from the URL path. (ex: this applies to cases where new files are + * uploaded, and only a path-based URL is provided) + * After locating the file name (from either the query parameter or path), the method + * splits the name into segments based on the last dot (`.`), returning the base name and + * extension as a two-element array. If file name cannot be extracted, `null` is returned. + * + * @param url Remote URL to extract file name segments from, which may contain a file name + * as either a query parameter (`fileName=...`) or in the path. + * @return An array containing the file name and extension segments, or null if extraction fails. */ public static String[] extractFileNameSegmentsFromUrl(URL url) { if (url == null) { @@ -143,24 +155,35 @@ public class FileDownloaderServiceProvider { } return null; } - - String []urlSegments = url.toString().split("/"); - if (urlSegments.length < 1) { - if (log.isDebugEnabled()) { - log.debug("Cannot determine the file name for the remote file"); + String fullQualifiedName = null; + String query = url.getQuery(); + if (query != null && query.startsWith("fileName=")) { + String[] queryParts = query.split("=", 2); + if (queryParts.length > 1 && !queryParts[1].isEmpty()) { + fullQualifiedName = queryParts[1]; } - return null; } - - String fullQualifiedName = urlSegments[urlSegments.length - 1]; - String []fileNameSegments = fullQualifiedName.split("\\.(?=[^.]+$)"); - if (fileNameSegments.length != 2) { + if (fullQualifiedName == null) { + String[] urlSegments = url.getPath().split("/"); + if (urlSegments.length > 0) { + fullQualifiedName = urlSegments[urlSegments.length - 1]; + } + } + if (fullQualifiedName != null) { + String[] fileNameSegments = fullQualifiedName.split("\\.(?=[^.]+$)"); + if (fileNameSegments.length == 2) { + return fileNameSegments; + } else { + if (log.isDebugEnabled()) { + log.debug("Error encountered when constructing file name"); + } + } + } else { if (log.isDebugEnabled()) { log.debug("Error encountered when constructing file name"); } - return null; } - return fileNameSegments; + return null; } /** diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/FileTransferServiceHelperUtil.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/FileTransferServiceHelperUtil.java index 856faf4944..0542aba5a6 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/FileTransferServiceHelperUtil.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/util/FileTransferServiceHelperUtil.java @@ -183,6 +183,15 @@ public class FileTransferServiceHelperUtil { return fileDescriptorResolvedFromRelease; } + String file = urlPathSegments[urlPathSegments.length - 1]; + String query = downloadUrl.getQuery(); + if (query != null && query.startsWith("fileName=")) { + String[] queryParts = query.split("=", 2); + if (queryParts.length > 1 && !queryParts[1].isEmpty()) { + file = queryParts[1]; + } + } + if (urlPathSegments.length < 2) { if (log.isDebugEnabled()) { log.debug("URL patch segments contain less than 2 segments"); @@ -190,7 +199,6 @@ public class FileTransferServiceHelperUtil { return null; } - String file = urlPathSegments[urlPathSegments.length - 1]; String artifactHolder = urlPathSegments[urlPathSegments.length - 2]; try { FileDescriptor fileDescriptor = new FileDescriptor(); From ba3e4623df0ee4c130e158ec691e5313a52c41eb Mon Sep 17 00:00:00 2001 From: nipuni Date: Tue, 12 Nov 2024 20:28:09 +0530 Subject: [PATCH 3/3] Fix NullPointerException in getFileMetaEntry method for URLs with chunked transfer encoding. --- .../mgt/core/impl/FileDownloaderServiceProvider.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/FileDownloaderServiceProvider.java b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/FileDownloaderServiceProvider.java index 7c8ad99533..d0ca149bcb 100644 --- a/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/FileDownloaderServiceProvider.java +++ b/components/application-mgt/io.entgra.device.mgt.core.application.mgt.core/src/main/java/io/entgra/device/mgt/core/application/mgt/core/impl/FileDownloaderServiceProvider.java @@ -122,7 +122,10 @@ public class FileDownloaderServiceProvider { } FileMetaEntry fileMetaEntry = new FileMetaEntry(); - fileMetaEntry.setSize(Long.parseLong(Objects.requireNonNull(response.header("Content-Length")))); + String contentLength = response.header("Content-Length"); + if (contentLength != null) { + fileMetaEntry.setSize(Long.parseLong(contentLength)); + } fileMetaEntry.setFileName(fileNameSegments[0]); fileMetaEntry.setExtension(fileNameSegments[1]); return fileMetaEntry;