From 2fd760113980ed85d14320b770f61bc68409a9f1 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Mon, 10 Sep 2018 01:14:35 +0530 Subject: [PATCH] Refactor and modify storage management logic --- .../exception/RequestValidatingException.java | 34 +++++ .../services/ApplicationStorageManager.java | 5 +- .../GenericApplicationDAOImpl.java | 4 +- .../impl/ApplicationStorageManagerImpl.java | 129 +++++++++--------- .../mgt/core/util/StorageManagementUtil.java | 18 +-- .../impl/ApplicationManagementAPIImpl.java | 18 ++- 6 files changed, 123 insertions(+), 85 deletions(-) create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/RequestValidatingException.java diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/RequestValidatingException.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/RequestValidatingException.java new file mode 100644 index 0000000000..1f331a33ae --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/exception/RequestValidatingException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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 org.wso2.carbon.device.application.mgt.common.exception; + +/** + * Represents the exception thrown during validating the request. + */ +public class RequestValidatingException extends Exception{ + + public RequestValidatingException(String message, Throwable ex) { + super(message, ex); + } + + public RequestValidatingException(String message) { + super(message); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java index 086ce0bfee..7533671586 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationStorageManager.java @@ -22,6 +22,7 @@ package org.wso2.carbon.device.application.mgt.common.services; import org.wso2.carbon.device.application.mgt.common.ApplicationRelease; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException; import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagementException; import java.io.InputStream; @@ -64,7 +65,7 @@ public interface ApplicationStorageManager { * @throws ResourceManagementException Resource Management Exception. */ ApplicationRelease uploadReleaseArtifact(ApplicationRelease applicationRelease, String appType, InputStream binaryFile) - throws ResourceManagementException; + throws ResourceManagementException, RequestValidatingException; /** * To upload release artifacts for an Application. @@ -75,7 +76,7 @@ public interface ApplicationStorageManager { * @throws ApplicationStorageManagementException Resource Management Exception. */ ApplicationRelease updateReleaseArtifacts(ApplicationRelease applicationRelease, String appType, InputStream binaryFile) - throws ApplicationStorageManagementException; + throws ApplicationStorageManagementException, RequestValidatingException; /** * To delete the artifacts related with particular Application Release. diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java index 9956202e00..7e4c574091 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java @@ -142,8 +142,8 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic String sql = "SELECT AP_APP.ID AS APP_ID, AP_APP.NAME AS APP_NAME, AP_APP.TYPE AS APP_TYPE, AP_APP.APP_CATEGORY" + " AS APP_CATEGORY, AP_APP.SUB_TYPE AS SUB_TYPE, AP_APP.CURRENCY AS CURRENCY, " - + "AP_APP.RESTRICTED, AP_APP_TAG.TAG AS APP_TAG, AP_UNRESTRICTED_ROLES.ROLE " - + "AS APP_UNRESTRICTED_ROLES FROM ((AP_APP LEFT JOIN AP_APP_TAG ON AP_APP.ID = AP_APP_TAG.AP_APP_ID) " + + "AP_APP.RESTRICTED AS RESTRICTED, AP_APP_TAG.TAG AS APP_TAG, AP_UNRESTRICTED_ROLES.ROLE " + + "AS ROLE FROM ((AP_APP LEFT JOIN AP_APP_TAG ON AP_APP.ID = AP_APP_TAG.AP_APP_ID) " + "LEFT JOIN AP_UNRESTRICTED_ROLES ON AP_APP.ID = AP_UNRESTRICTED_ROLES.AP_APP_ID) " + "WHERE AP_APP.TENANT_ID = ? AND AP_APP.STATUS != ?"; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java index a4aad2b7bc..20a8ca0922 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationStorageManagerImpl.java @@ -33,6 +33,7 @@ import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.application.mgt.common.ApplicationRelease; import org.wso2.carbon.device.application.mgt.common.ApplicationType; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException; import org.wso2.carbon.device.application.mgt.common.exception.ResourceManagementException; import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager; import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; @@ -47,6 +48,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.text.ParseException; import java.util.HashMap; import java.util.List; @@ -104,9 +106,10 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager saveFile(bannerFileStream, bannerStoredLocation); applicationRelease.setBannerLoc(bannerStoredLocation); } - if (screenShotStreams.size() > screenShotMaxCount) { - throw new ApplicationStorageManagementException("Maximum limit for the screen-shot exceeds"); - } else if (!screenShotStreams.isEmpty() && screenShotStreams.size() <= screenShotMaxCount) { + if (!screenShotStreams.isEmpty()) { + if (screenShotStreams.size() > screenShotMaxCount) { + throw new ApplicationStorageManagementException("Maximum limit for the screen-shot exceeds"); + } int count = 1; for (InputStream screenshotStream : screenShotStreams) { scStoredLocation = artifactDirectoryPath + File.separator + Constants.IMAGE_ARTIFACTS[2] + count; @@ -123,7 +126,6 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager count++; } } - return applicationRelease; } catch (IOException e) { throw new ApplicationStorageManagementException("IO Exception while saving the screens hots for " + @@ -149,9 +151,10 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager if (bannerFileStream != null) { deleteApplicationReleaseArtifacts(applicationRelease.getBannerLoc()); } - if (screenShotStreams.size() > screenShotMaxCount) { - throw new ApplicationStorageManagementException("Maximum limit for the screen-shot exceeds"); - } else if (!screenShotStreams.isEmpty() && screenShotStreams.size() <= screenShotMaxCount) { + if (!screenShotStreams.isEmpty()) { + if (screenShotStreams.size() > screenShotMaxCount) { + throw new ApplicationStorageManagementException("Maximum limit for the screen-shot exceeds"); + } int count = 1; while (count < screenShotStreams.size()) { if (count == 1) { @@ -166,8 +169,7 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager count++; } } - applicationRelease = uploadImageArtifacts(applicationRelease, iconFileStream, bannerFileStream, screenShotStreams); - return applicationRelease; + return uploadImageArtifacts(applicationRelease, iconFileStream, bannerFileStream, screenShotStreams); } catch (ApplicationStorageManagementException e) { ConnectionManagerUtil.rollbackDBTransaction(); throw new ApplicationStorageManagementException("Application Storage exception while trying to" @@ -177,15 +179,15 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager } @Override - public ApplicationRelease uploadReleaseArtifact(ApplicationRelease applicationRelease, String appType, InputStream binaryFile) - throws ResourceManagementException { + public ApplicationRelease uploadReleaseArtifact(ApplicationRelease applicationRelease, String appType, + InputStream binaryFile) throws ResourceManagementException, RequestValidatingException { try { if (ApplicationType.WEB_CLIP.toString().equals(appType)) { applicationRelease.setVersion(Constants.DEFAULT_VERSION); UrlValidator urlValidator = new UrlValidator(); if (applicationRelease.getUrl() == null || !urlValidator.isValid(applicationRelease.getUrl())) { - throw new ApplicationStorageManagementException("Request payload doesn't contains Web Clip URL " + + throw new RequestValidatingException("Request payload doesn't contains Web Clip URL " + "with application release object or Web " + "Clip URL is invalid"); //todo if we throw this we must send BAD REQUEST to end user @@ -208,32 +210,25 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager if (ApplicationType.ANDROID.toString().equals(appType)) { String prefix = "stream2file"; String suffix = ".apk"; - Boolean isTempDelete; - File tempFile = File.createTempFile(prefix, suffix); FileOutputStream out = new FileOutputStream(tempFile); IOUtils.copy(binaryFile, out); - ApkFile apkFile = new ApkFile(tempFile); - ApkMeta apkMeta = apkFile.getApkMeta(); - applicationRelease.setVersion(apkMeta.getVersionName()); - isTempDelete = tempFile.delete(); - if (!isTempDelete) { - log.error("Temporary created APK file deletion failed"); + try (ApkFile apkFile = new ApkFile(tempFile)){ + ApkMeta apkMeta = apkFile.getApkMeta(); + applicationRelease.setVersion(apkMeta.getVersionName()); + Files.delete(tempFile.toPath()); } + } else if (ApplicationType.IOS.toString().equals(appType)) { String prefix = "stream2file"; String suffix = ".ipa"; - Boolean isTempDelete; File tempFile = File.createTempFile(prefix, suffix); FileOutputStream out = new FileOutputStream(tempFile); IOUtils.copy(binaryFile, out); Map plistInfo = getIPAInfo(tempFile); applicationRelease.setVersion(plistInfo.get("CFBundleVersion")); - isTempDelete = tempFile.delete(); - if (!isTempDelete) { - log.error("Temporary created ipa file deletion failed"); - } + Files.delete(tempFile.toPath()); } else { throw new ApplicationStorageManagementException("Application Type doesn't match with supporting " + "application types " + applicationRelease.getUuid()); @@ -262,7 +257,7 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager @Override public ApplicationRelease updateReleaseArtifacts(ApplicationRelease applicationRelease, String appType, - InputStream binaryFile) throws ApplicationStorageManagementException { + InputStream binaryFile) throws ApplicationStorageManagementException, RequestValidatingException { try { deleteApplicationReleaseArtifacts(applicationRelease.getAppStoredLoc()); @@ -284,15 +279,20 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager File artifact = new File(artifactPath); if (artifact.exists()) { - StorageManagementUtil.deleteDir(artifact); + try { + StorageManagementUtil.deleteDir(artifact); + } catch (IOException e) { + throw new ApplicationStorageManagementException( + "Error occured while deleting application release artifacts", e); + } } else { - throw new ApplicationStorageManagementException("Tried to delete application release, but it doesn't exist " + - "in the system"); + throw new ApplicationStorageManagementException( + "Tried to delete application release, but it doesn't exist in the system"); } } - @Override - public void deleteAllApplicationReleaseArtifacts(List directoryPaths) throws ApplicationStorageManagementException { + @Override public void deleteAllApplicationReleaseArtifacts(List directoryPaths) + throws ApplicationStorageManagementException { for (String directoryBasePath : directoryPaths) { deleteApplicationReleaseArtifacts(directoryBasePath); } @@ -346,6 +346,11 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager NSString parameter = (NSString) rootDict.objectForKey(Constants.CF_BUNDLE_VERSION); ipaInfo.put(Constants.CF_BUNDLE_VERSION, parameter.toString()); + if (ipaDirectory != null) { + // remove unzip folder + deleteDir(new File(ipaDirectory + File.separator + Constants.PAYLOAD)); + } + } catch (ParseException e) { String msg = "Error occurred while parsing the plist data"; log.error(msg); @@ -361,11 +366,6 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager String msg = "Error occurred while unzipping the ipa file"; log.error(msg); throw new ApplicationStorageManagementException(msg, e); - } finally { - if (ipaDirectory != null) { - // remove unzip folder - deleteDir(new File(ipaDirectory + File.separator + Constants.PAYLOAD)); - } } return ipaInfo; } @@ -380,7 +380,7 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager private void unzip(String zipFilePath, String destDirectory) throws IOException, ApplicationStorageManagementException { File destDir = new File(destDirectory); - Boolean isDirCreated; + boolean isDirCreated; if (!destDir.exists()) { isDirCreated = destDir.mkdir(); @@ -389,33 +389,31 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager "retrieval"); } } + try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) { + + ZipEntry entry = zipIn.getNextEntry(); + // iterates over entries in the zip file + while (entry != null) { + String filePath = destDirectory + File.separator + entry.getName(); + + if (!entry.isDirectory()) { + // if the entry is a file, extracts it + extractFile(zipIn, filePath); + } else { + // if the entry is a directory, make the directory + File dir = new File(filePath); + isDirCreated = dir.mkdir(); + if (!isDirCreated) { + throw new ApplicationStorageManagementException( + "Directory Creation Is Failed while iOS app vertion " + "retrieval"); + } - ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath)); - ZipEntry entry = zipIn.getNextEntry(); - - // iterates over entries in the zip file - while (entry != null) { - String filePath = destDirectory + File.separator + entry.getName(); - - if (!entry.isDirectory()) { - // if the entry is a file, extracts it - extractFile(zipIn, filePath); - } else { - // if the entry is a directory, make the directory - File dir = new File(filePath); - isDirCreated = dir.mkdir(); - if (!isDirCreated) { - throw new ApplicationStorageManagementException( - "Directory Creation Is Failed while iOS app vertion " + - "retrieval"); } + zipIn.closeEntry(); + entry = zipIn.getNextEntry(); } - - zipIn.closeEntry(); - entry = zipIn.getNextEntry(); } - zipIn.close(); } /** @@ -425,13 +423,12 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager * @param filePath file path */ private void extractFile(ZipInputStream zipIn, String filePath) throws IOException { - BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); - byte[] bytesIn = new byte[BUFFER_SIZE]; - int read; - - while ((read = zipIn.read(bytesIn)) != -1) { - bos.write(bytesIn, 0, read); + try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) { + byte[] bytesIn = new byte[BUFFER_SIZE]; + int read; + while ((read = zipIn.read(bytesIn)) != -1) { + bos.write(bytesIn, 0, read); + } } - bos.close(); } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/StorageManagementUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/StorageManagementUtil.java index 0d3d5a6860..78eec4352a 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/StorageManagementUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/StorageManagementUtil.java @@ -55,14 +55,14 @@ public class StorageManagementUtil { * * @param artifactDirectory Artifact Directory that need to be deleted. */ - public static void deleteDir(File artifactDirectory) { + public static void deleteDir(File artifactDirectory) throws IOException { File[] contents = artifactDirectory.listFiles(); if (contents != null) { for (File file : contents) { deleteDir(file); } } - artifactDirectory.delete(); + Files.delete(artifactDirectory.toPath()); } /** @@ -72,19 +72,13 @@ public class StorageManagementUtil { * @param path Path the file need to be saved in. */ public static void saveFile(InputStream inputStream, String path) throws IOException { - OutputStream outStream = null; - try { + try (OutputStream outStream = new FileOutputStream(new File(path))) { byte[] buffer = new byte[inputStream.available()]; - inputStream.read(buffer); - outStream = new FileOutputStream(new File(path)); - outStream.write(buffer); + if (inputStream.read(buffer) != -1) { + outStream.write(buffer); + } } finally { - inputStream.close(); - - if (outStream != null) { - outStream.close(); - } } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java index bedb342eb1..472d93fb8a 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.api/src/main/java/org/wso2/carbon/device/application/mgt/publisher/api/services/impl/ApplicationManagementAPIImpl.java @@ -24,6 +24,7 @@ import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.wso2.carbon.device.application.mgt.common.*; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; +import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException; import org.wso2.carbon.device.application.mgt.publisher.api.APIUtil; import org.wso2.carbon.device.application.mgt.publisher.api.services.ApplicationManagementAPI; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; @@ -171,6 +172,9 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { log.error(errorMessage, e); return APIUtil.getResponse(new ApplicationManagementException(errorMessage, e), Response.Status.INTERNAL_SERVER_ERROR); + } catch (RequestValidatingException e) { + log.error("Error occured while handling the application creating request"); + return APIUtil.getResponse(e, Response.Status.BAD_REQUEST); } } @@ -252,8 +256,8 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { try { if (binaryFile == null) { - return Response.status(Response.Status.BAD_REQUEST) - .entity("Uploading artifacts for the application is failed " + applicationUuid).build(); + return APIUtil.getResponse("Uploading artifacts for the application is failed " + applicationUuid, + Response.Status.BAD_REQUEST); } applicationRelease = applicationManager.validateApplicationRelease(applicationId, applicationUuid); applicationRelease = applicationStorageManager.updateReleaseArtifacts(applicationRelease, appType, @@ -263,7 +267,7 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { .entity("Successfully uploaded artifacts for the application release. UUID is " + applicationUuid).build(); } catch (IOException e) { String msg = - "Exception while trying to read icon, banner files for the application release" + applicationUuid; + "Error occured while trying to read icon, banner files for the application release" + applicationUuid; log.error(msg); return APIUtil.getResponse(new ApplicationManagementException(msg, e), Response.Status.BAD_REQUEST); @@ -275,6 +279,10 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { log.error("Error occurred while updating the image artifacts of the application with the uuid " + applicationUuid, e); return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } catch (RequestValidatingException e) { + log.error("Error occured while handling the application artifact updating request. application release UUID: " + + applicationUuid); + return APIUtil.getResponse(e, Response.Status.BAD_REQUEST); } } @@ -357,6 +365,10 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { log.error("Error occurred while updating the releases artifacts of the application with the uuid " + applicationUUID + " for the release " + applicationRelease.getVersion(), e); return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR); + } catch (RequestValidatingException e) { + log.error("Error occured while handling the application release updating request. application release UUID: " + + applicationUUID); + return APIUtil.getResponse(e, Response.Status.BAD_REQUEST); } }