From 071ef71c862db3568872d15aae977aa780f51cf6 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Mon, 8 Apr 2019 16:48:04 +0530 Subject: [PATCH] Fix app installing issue for same package name If we add same installer as a new app by giving different name, it was able to add as new application. But, if there is application release for same package name, the application adding should be blocked. Therefore verify if there is an application release for same package name before adding an application. --- .../mgt/common/ApplicationArtifact.java | 10 +-- .../mgt/common/ApplicationInstaller.java | 45 ++++++++++++ .../services/ApplicationStorageManager.java | 5 ++ .../mgt/core/impl/ApplicationManagerImpl.java | 72 +++++++++++++++---- .../impl/ApplicationStorageManagerImpl.java | 69 +++++++++--------- .../impl/ApplicationManagementAPIImpl.java | 2 +- 6 files changed, 149 insertions(+), 54 deletions(-) create mode 100644 components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstaller.java diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationArtifact.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationArtifact.java index 0a934b8cd9..1b44fb9e7f 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationArtifact.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationArtifact.java @@ -24,7 +24,7 @@ public class ApplicationArtifact { private InputStream installerStream; - private String bannername; + private String bannerName; private InputStream bannerStream; @@ -50,12 +50,12 @@ public class ApplicationArtifact { this.installerStream = installerStream; } - public String getBannername() { - return bannername; + public String getBannerName() { + return bannerName; } - public void setBannername(String bannername) { - this.bannername = bannername; + public void setBannerName(String bannerName) { + this.bannerName = bannerName; } public InputStream getBannerStream() { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstaller.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstaller.java new file mode 100644 index 0000000000..3fad303be9 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/ApplicationInstaller.java @@ -0,0 +1,45 @@ +package org.wso2.carbon.device.application.mgt.common;/* Copyright (c) 2019, 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. + */ + +public class ApplicationInstaller { + + /*** + * Package name of the Installer + */ + private String packageName; + + /*** + * Version of the Installer. + */ + private String version; + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} 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 879e06b3d9..ba4dde5ca5 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 @@ -19,6 +19,7 @@ package org.wso2.carbon.device.application.mgt.common.services; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstaller; import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException; import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException; @@ -54,6 +55,10 @@ public interface ApplicationStorageManager { ApplicationReleaseDTO updateImageArtifacts(ApplicationReleaseDTO applicationRelease, InputStream iconFile, InputStream bannerFile, List screenshots) throws ResourceManagementException; + ApplicationInstaller getAppInstallerData(InputStream binaryFile, String deviceType) + throws ApplicationStorageManagementException; + + /** * To upload release artifacts for an ApplicationDTO. * diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index 342d172153..d9ac61f4f4 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -18,6 +18,7 @@ */ package org.wso2.carbon.device.application.mgt.core.impl; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.validator.routines.UrlValidator; import org.apache.cxf.jaxrs.ext.multipart.Attachment; @@ -28,6 +29,7 @@ import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.application.mgt.common.AppLifecycleState; import org.wso2.carbon.device.application.mgt.common.ApplicationArtifact; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstaller; import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO; import org.wso2.carbon.device.application.mgt.common.ApplicationList; import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; @@ -75,6 +77,8 @@ import org.wso2.carbon.user.api.UserRealm; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; @@ -317,25 +321,70 @@ public class ApplicationManagerImpl implements ApplicationManager { } private ApplicationDTO addApplicationReleaseArtifacts(ApplicationDTO applicationDTO, - ApplicationArtifact applicationArtifact) throws ResourceManagementException { + ApplicationArtifact applicationArtifact) throws ResourceManagementException, + ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); ApplicationStorageManager applicationStorageManager = Util.getApplicationStorageManager(); List applicationReleaseEntities = new ArrayList<>(); ApplicationReleaseDTO applicationReleaseDTO; applicationReleaseDTO = applicationDTO.getApplicationReleases().get(0); + + String uuid = UUID.randomUUID().toString(); + applicationReleaseDTO.setUuid(uuid); + // The application executable artifacts such as apks are uploaded. - if (!ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) { - applicationReleaseDTO = applicationStorageManager - .uploadReleaseArtifact(applicationReleaseDTO, applicationDTO.getType(), - applicationDTO.getDeviceTypeName(), null); - } else { - applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName()); - applicationReleaseDTO = applicationStorageManager - .uploadReleaseArtifact(applicationReleaseDTO, applicationDTO.getType(), - applicationDTO.getDeviceTypeName(), applicationArtifact.getInstallerStream()); + if (ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) { + try { + byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); + + applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName()); + + try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) { + ApplicationInstaller applicationInstaller = applicationStorageManager + .getAppInstallerData(binary, applicationDTO.getDeviceTypeName()); + String packagename = applicationInstaller.getPackageName(); + + ConnectionManagerUtil.getDBConnection(); + if (applicationReleaseDAO.isAppExisitForPackageName(packagename, tenantId)) { + String msg = "Application release is already exist for the package name: " + packagename; + log.error(msg); + throw new ApplicationManagementException(msg); + } + applicationReleaseDTO.setVersion(applicationInstaller.getVersion()); + applicationReleaseDTO.setPackageName(packagename); + try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { + applicationReleaseDTO = applicationStorageManager + .uploadReleaseArtifact(applicationReleaseDTO, applicationDTO.getType(), + applicationDTO.getDeviceTypeName(), binaryDuplicate); + } + } + } catch (IOException e) { + String msg = + "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact + .getInstallerName(); + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection for verifying application package existence."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred when executing the query for verifying application release existence for " + + "the package."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } else if (ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType())) { + applicationReleaseDTO.setVersion(Constants.DEFAULT_VERSION); + applicationReleaseDTO.setInstallerName(applicationReleaseDTO.getUrl()); + // Since WEB CLIP doesn't have an installer, set uuid as has value for WEB CLIP + applicationReleaseDTO.setAppHashValue(uuid); } applicationReleaseDTO.setIconName(applicationArtifact.getIconName()); - applicationReleaseDTO.setBannerName(applicationArtifact.getBannername()); + applicationReleaseDTO.setBannerName(applicationArtifact.getBannerName()); Map screenshots = applicationArtifact.getScreenshots(); List screenshotNames = new ArrayList<>(screenshots.keySet()); @@ -357,7 +406,6 @@ public class ApplicationManagerImpl implements ApplicationManager { applicationReleaseDTO = applicationStorageManager .uploadImageArtifacts(applicationReleaseDTO, applicationArtifact.getIconStream(), applicationArtifact.getBannerStream(), new ArrayList<>(screenshots.values())); - applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); applicationReleaseEntities.add(applicationReleaseDTO); applicationDTO.setApplicationReleases(applicationReleaseEntities); return applicationDTO; 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 20e9e5d892..4549e2b177 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 @@ -30,6 +30,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.validator.routines.UrlValidator; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.application.mgt.common.ApplicationInstaller; import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO; import org.wso2.carbon.device.application.mgt.common.ApplicationType; import org.wso2.carbon.device.application.mgt.common.DeviceTypes; @@ -175,17 +176,37 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager } } + public ApplicationInstaller getAppInstallerData(InputStream binaryFile, String deviceType) + throws ApplicationStorageManagementException { + ApplicationInstaller applicationInstaller = new ApplicationInstaller(); + try { + if (DeviceTypes.ANDROID.toString().equalsIgnoreCase(deviceType)) { + ApkMeta apkMeta = ArtifactsParser.readAndroidManifestFile(binaryFile); + applicationInstaller.setVersion(apkMeta.getVersionName()); + applicationInstaller.setPackageName(apkMeta.getPackageName()); + } else if (DeviceTypes.IOS.toString().equalsIgnoreCase(deviceType)) { + NSDictionary plistInfo = ArtifactsParser.readiOSManifestFile(binaryFile); + applicationInstaller + .setVersion(plistInfo.objectForKey(ArtifactsParser.IPA_BUNDLE_VERSION_KEY).toString()); + applicationInstaller + .setPackageName(plistInfo.objectForKey(ArtifactsParser.IPA_BUNDLE_IDENTIFIER_KEY).toString()); + } else { + String msg = "Application Type doesn't match with supporting application types " + deviceType; + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } + } catch (ParsingException e){ + String msg = "Application Type doesn't match with supporting application types " + deviceType; + log.error(msg); + throw new ApplicationStorageManagementException(msg); + } + return applicationInstaller; + } + @Override public ApplicationReleaseDTO uploadReleaseArtifact(ApplicationReleaseDTO applicationReleaseDTO, String appType, String deviceType, InputStream binaryFile) throws ResourceManagementException { try { - // move version and package getting code into separate method and check whether package exist in db - if (ApplicationType.WEB_CLIP.toString().equals(appType)) { - applicationReleaseDTO.setVersion(Constants.DEFAULT_VERSION); - applicationReleaseDTO.setInstallerName(applicationReleaseDTO.getUrl()); - applicationReleaseDTO.setAppHashValue(null); - return applicationReleaseDTO; - } String artifactDirectoryPath; String md5OfApp; String artifactPath; @@ -199,29 +220,11 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager throw new ApplicationStorageManagementException(msg); } - artifactDirectoryPath = storagePath + md5OfApp; - if (DeviceTypes.ANDROID.toString().equalsIgnoreCase(deviceType)) { - ApkMeta apkMeta = ArtifactsParser.readAndroidManifestFile(new ByteArrayInputStream(content)); - applicationReleaseDTO.setVersion(apkMeta.getVersionName()); - applicationReleaseDTO.setPackageName(apkMeta.getPackageName()); - } else if (DeviceTypes.IOS.toString().equalsIgnoreCase(deviceType)) { - NSDictionary plistInfo = ArtifactsParser.readiOSManifestFile(binaryFile); - applicationReleaseDTO - .setVersion(plistInfo.objectForKey(ArtifactsParser.IPA_BUNDLE_VERSION_KEY).toString()); - applicationReleaseDTO - .setPackageName(plistInfo.objectForKey(ArtifactsParser.IPA_BUNDLE_IDENTIFIER_KEY).toString()); - } else { - String msg = "Application Type doesn't match with supporting application types " + applicationReleaseDTO - .getUuid(); - log.error(msg); - throw new ApplicationStorageManagementException(msg); - } - if (log.isDebugEnabled()) { - log.debug("Artifact Directory Path for saving the application release related artifacts related with " - + "application UUID " + applicationReleaseDTO.getUuid() + " is " + artifactDirectoryPath); + log.debug("Artifact Directory Path for saving the application release is " + artifactDirectoryPath + + ". ApplicationUUID: " + applicationReleaseDTO.getUuid()); } - + artifactDirectoryPath = storagePath + md5OfApp; StorageManagementUtil.createArtifactDirectory(artifactDirectoryPath); artifactPath = artifactDirectoryPath + File.separator + applicationReleaseDTO.getInstallerName(); saveFile(new ByteArrayInputStream(content), artifactPath); @@ -231,19 +234,13 @@ public class ApplicationStorageManagerImpl implements ApplicationStorageManager + applicationReleaseDTO.getUuid(); log.error(msg); throw new ApplicationStorageManagementException( msg, e); - } catch (ParsingException e) { - String msg = "Error occurred while parsing the artifact file. Application release UUID is " - + applicationReleaseDTO.getUuid(); - log.error(msg); - throw new ApplicationStorageManagementException(msg, e); } return applicationReleaseDTO; } @Override - public ApplicationReleaseDTO updateReleaseArtifacts(ApplicationReleaseDTO applicationRelease, String appType, - String deviceType, InputStream binaryFile) throws ApplicationStorageManagementException, - RequestValidatingException { + public ApplicationReleaseDTO updateReleaseArtifacts(ApplicationReleaseDTO applicationRelease, + String appType, String deviceType, InputStream binaryFile) throws ApplicationStorageManagementException { try { deleteApplicationReleaseArtifacts(applicationRelease.getInstallerName()); 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 17017f85d2..04c04f144d 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 @@ -655,7 +655,7 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { log.error(msg); throw new BadRequestException(msg); } - applicationArtifact.setBannername(bannerFileName); + applicationArtifact.setBannerName(bannerFileName); applicationArtifact.setBannerStream(bannerStream); Map scrrenshotData = new HashMap<>();