From c5944f6602066e3734edf96f75c1e9cd02042538 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Thu, 7 Nov 2019 19:45:49 +0530 Subject: [PATCH 1/2] Fix app installing issue if uninstall operation trigger twice at same time --- .../core/impl/SubscriptionManagerImpl.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java index ec5c532475..dee1b7a6d1 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java @@ -637,15 +637,21 @@ public class SubscriptionManagerImpl implements SubscriptionManager { DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()); DeviceSubscriptionDTO deviceSubscriptionDTO = deviceSubscriptions.get(device.getId()); if (deviceSubscriptionDTO != null) { - if (!deviceSubscriptionDTO.isUnsubscribed() && Operation.Status.COMPLETED.toString() - .equals(deviceSubscriptionDTO.getStatus())) { - subscribingDeviceIdHolder.getAppInstalledDevices().put(deviceIdentifier, device.getId()); - } else if (deviceSubscriptionDTO.isUnsubscribed() && !Operation.Status.COMPLETED.toString() - .equals(deviceSubscriptionDTO.getStatus())) { - subscribingDeviceIdHolder.getAppReUnInstallableDevices().put(deviceIdentifier, device.getId()); - } else if (Operation.Status.PENDING.toString().equals(deviceSubscriptionDTO.getStatus()) + if (Operation.Status.PENDING.toString().equals(deviceSubscriptionDTO.getStatus()) || Operation.Status.IN_PROGRESS.toString().equals(deviceSubscriptionDTO.getStatus())) { subscribingDeviceIdHolder.getSkippedDevices().put(deviceIdentifier, device.getId()); + } else if (deviceSubscriptionDTO.isUnsubscribed()) { + if (Operation.Status.COMPLETED.toString().equals(deviceSubscriptionDTO.getStatus())) { + subscribingDeviceIdHolder.getAppReInstallableDevices().put(deviceIdentifier, device.getId()); + } else { + /*We can't ensure whether app is uninstalled successfully or not hence allow to perform both + install and uninstall operations*/ + subscribingDeviceIdHolder.getAppReUnInstallableDevices().put(deviceIdentifier, device.getId()); + subscribingDeviceIdHolder.getAppReInstallableDevices().put(deviceIdentifier, device.getId()); + } + } else if (!deviceSubscriptionDTO.isUnsubscribed() && Operation.Status.COMPLETED.toString() + .equals(deviceSubscriptionDTO.getStatus())) { + subscribingDeviceIdHolder.getAppInstalledDevices().put(deviceIdentifier, device.getId()); } else { subscribingDeviceIdHolder.getAppReInstallableDevices().put(deviceIdentifier, device.getId()); } From 09a10f44dd7ca2b67e137155626f22144ee3d355 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Thu, 14 Nov 2019 05:31:04 +0530 Subject: [PATCH 2/2] Improve APP subscribing functionality --- .../common/services/ApplicationManager.java | 13 +- .../common/wrapper/EntAppReleaseWrapper.java | 2 +- .../mgt/core/dao/ApplicationDAO.java | 23 ++- .../mgt/core/dao/ApplicationReleaseDAO.java | 10 +- .../GenericApplicationDAOImpl.java | 75 +++++++++ .../mgt/core/impl/ApplicationManagerImpl.java | 150 ++++++++++++++---- .../ApplicationManagementPublisherAPI.java | 4 - ...ApplicationManagementPublisherAPIImpl.java | 8 +- 8 files changed, 244 insertions(+), 41 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java index 3344356422..1b1a318689 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/ApplicationManager.java @@ -110,6 +110,16 @@ public interface ApplicationManager { */ ApplicationList getApplications(Filter filter) throws ApplicationManagementException; + /** + * To get list of applications that application releases has given package names. + * + * @param packageNames List of package names. + * @return List of applications {@link Application} + * @throws ApplicationManagementException if error occurred while getting application data from DB or error + * occurred while accessing user store. + */ + List getApplications(List packageNames) throws ApplicationManagementException; + /** * To get the Application for given Id. * @@ -166,7 +176,8 @@ public interface ApplicationManager { * @param applicationArtifact Application artifact that contains names and input streams of the application artifacts. * @throws ApplicationManagementException ApplicationDTO Management Exception. */ - void updateApplicationImageArtifact(String uuid, ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + void updateApplicationImageArtifact(String uuid, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException; /** diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/EntAppReleaseWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/EntAppReleaseWrapper.java index 5a8bcce737..ad79d9e7f3 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/EntAppReleaseWrapper.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/EntAppReleaseWrapper.java @@ -43,7 +43,7 @@ public class EntAppReleaseWrapper { private Double price; @ApiModelProperty(name = "isSharedWithAllTenants", - value = "If application release is shared with all tenants it is eqal to 1 otherwise 0", + value = "If application release is shared with all tenants it is equal to true otherwise false", required = true) @NotNull private boolean isSharedWithAllTenants; diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java index 2fc936d4a2..73784e4813 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationDAO.java @@ -133,8 +133,29 @@ public interface ApplicationDAO { */ ApplicationDTO getApplication(String releaseUuid, int tenantId) throws ApplicationManagementDAOException; + /** + * To get application with a specific application release which has given application release UUID + * + * @param releaseUuid Applicatioon Release UUID + * @param tenantId Tenant Id + * @return {@link ApplicationDTO} + * @throws ApplicationManagementDAOException if error occurred while getting application and + * application release data from the DB. + */ ApplicationDTO getAppWithRelatedRelease(String releaseUuid, int tenantId) throws ApplicationManagementDAOException; + /** + * To get list of applications with a specific application releases which has given package names. + * + * @param packageNames List of package names + * @param tenantId Tenant Id + * @return List of {@link ApplicationDTO} + * @throws ApplicationManagementDAOException if error occurred while getting application and + * application release data from the DB. + */ + List getAppWithRelatedReleases(List packageNames, int tenantId) + throws ApplicationManagementDAOException; + /** * Verify whether application exist for given application name and device type. Because a name and device type is * unique for an application. @@ -179,6 +200,4 @@ public interface ApplicationDAO { int getApplicationCount(Filter filter, int deviceTypeId, int tenantId) throws ApplicationManagementDAOException; void deleteApplication(int appId, int tenantId) throws ApplicationManagementDAOException; - } - diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java index ad5d0c4006..28af63f2ed 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/ApplicationReleaseDAO.java @@ -116,7 +116,15 @@ public interface ApplicationReleaseDAO { boolean hasExistInstallableAppRelease(String releaseUuid, String installableStateName, int tenantId) throws ApplicationManagementDAOException; + /** + * This method is responsible to return list of application releases which contains one of the + * providing package name. + * + * @param packages List of package names + * @param tenantId Tenant Id + * @return List of application releases {@link ApplicationReleaseDTO} + * @throws ApplicationManagementDAOException if error occurred while getting application releases from the DB. + */ List getReleaseByPackages(List packages, int tenantId) throws ApplicationManagementDAOException; - } 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 f860273228..57fdd4021a 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 @@ -487,6 +487,81 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic } } + @Override + public List getAppWithRelatedReleases(List packageNames, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting application and related application releases which has package names: " + packageNames + + " from the database"); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + StringJoiner joiner = new StringJoiner(",", + "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "INNER JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + + "WHERE " + + "AP_APP_RELEASE.PACKAGE_NAME IN (", + ") AND AP_APP.TENANT_ID = ?"); + packageNames.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String packageName : packageNames) { + ps.setObject(index++, packageName); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved basic details of the application and related application " + + "release for the application release which has package names: " + packageNames); + } + return DAOUtil.loadApplications(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get application and related application " + + "releases which has package names: " + packageNames; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting application and related app release details of releases which " + + "has package names " + packageNames + " while executing query."; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + @Override public ApplicationDTO getApplication(int applicationId, int tenantId) throws ApplicationManagementDAOException { 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 f5b7882659..142ee4dfe5 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 @@ -484,7 +484,6 @@ public class ApplicationManagerImpl implements ApplicationManager { } } } - } } catch (IOException e) { String msg = "Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact @@ -697,6 +696,60 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + @Override + public List getApplications(List packageNames) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + try { + ConnectionManagerUtil.openDBConnection(); + List appDTOs = applicationDAO.getAppWithRelatedReleases(packageNames, tenantId); + List filteredApplications = new ArrayList<>(); + for (ApplicationDTO applicationDTO : appDTOs) { + if (!lifecycleStateManager.getEndState().equals(applicationDTO.getStatus())) { + //Set application categories, tags and unrestricted roles to the application DTO. + applicationDTO + .setUnrestrictedRoles(visibilityDAO.getUnrestrictedRoles(applicationDTO.getId(), tenantId)); + applicationDTO.setAppCategories(applicationDAO.getAppCategories(applicationDTO.getId(), tenantId)); + applicationDTO.setTags(applicationDAO.getAppTags(applicationDTO.getId(), tenantId)); + if (applicationDTO.getUnrestrictedRoles().isEmpty() || hasUserRole( + applicationDTO.getUnrestrictedRoles(), userName)) { + filteredApplications.add(applicationDTO); + } + } + + List filteredApplicationReleaseDTOs = new ArrayList<>(); + for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) { + if (!applicationReleaseDTO.getCurrentState().equals(lifecycleStateManager.getEndState())) { + filteredApplicationReleaseDTOs.add(applicationReleaseDTO); + } + } + applicationDTO.setApplicationReleaseDTOs(filteredApplicationReleaseDTOs); + } + + List applications = new ArrayList<>(); + for (ApplicationDTO appDTO : filteredApplications) { + applications.add(APIUtil.appDtoToAppResponse(appDTO)); + } + return applications; + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection to get applications by filtering from " + + "requested filter."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "User-store exception while checking whether the user " + userName + " of tenant " + tenantId + + " has the publisher permission"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "DAO exception while getting applications for the user " + userName + " of tenant " + tenantId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + /** * Check whether at least one filtering role is in app unrestricted roles. * @@ -1471,13 +1524,6 @@ public class ApplicationManagerImpl implements ApplicationManager { throw new NotFoundException(msg); } - String currentState = applicationReleaseDTO.getCurrentState(); - if (!lifecycleStateManager.isUpdatableState(currentState)){ - throw new ForbiddenException( - "Can't Update the application release. Application release is in " + currentState - + " and it is not an release updatable state. Hence please move the application release" - + " into updatable state and retry the operation."); - } applicationReleaseDTO = this.applicationReleaseDAO .updateRelease(updateImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId), tenantId); if (applicationReleaseDTO == null) { @@ -1498,7 +1544,7 @@ public class ApplicationManagerImpl implements ApplicationManager { + "UUID: " + uuid; log.error(msg, e); throw new ApplicationManagementException(msg, e); - }catch (ApplicationManagementDAOException e) { + } catch (ApplicationManagementDAOException e) { ConnectionManagerUtil.rollbackDBTransaction(); String msg = "Error occured while getting application release data for updating image artifacts of the application release uuid " @@ -1828,8 +1874,8 @@ public class ApplicationManagerImpl implements ApplicationManager { } if (!isExistingAppRestricted) { - visibilityDAO - .addUnrestrictedRoles(applicationUpdateWrapper.getUnrestrictedRoles(), applicationId, tenantId); + visibilityDAO.addUnrestrictedRoles(applicationUpdateWrapper.getUnrestrictedRoles(), applicationId, + tenantId); appUnrestrictedRoles = applicationUpdateWrapper.getUnrestrictedRoles(); } else { List addingRoleList = getDifference(applicationUpdateWrapper.getUnrestrictedRoles(), @@ -1854,21 +1900,23 @@ public class ApplicationManagerImpl implements ApplicationManager { .collect(Collectors.toList()); if (!getDifference(updatingAppCategries, allCategoryName).isEmpty()){ - String msg = "Application update request contains invalid category names. Hence please verify the request payload"; + String msg = "Application update request contains invalid category names. Hence please verify the " + + "request payload"; log.error(msg); throw new BadRequestException(msg); } - List addingAppCategories = getDifference(updatingAppCategries, appCategories); List removingAppCategories = getDifference(appCategories, updatingAppCategries); if (!addingAppCategories.isEmpty()) { - List categoryIds = this.applicationDAO.getCategoryIdsForCategoryNames(addingAppCategories, tenantId); + List categoryIds = this.applicationDAO + .getCategoryIdsForCategoryNames(addingAppCategories, tenantId); this.applicationDAO.addCategoryMapping(categoryIds, applicationId, tenantId); appCategories.addAll(addingAppCategories); } if (!removingAppCategories.isEmpty()) { - List categoryIds = this.applicationDAO.getCategoryIdsForCategoryNames(removingAppCategories, tenantId); + List categoryIds = this.applicationDAO + .getCategoryIdsForCategoryNames(removingAppCategories, tenantId); this.applicationDAO.deleteAppCategories(categoryIds, applicationId, tenantId); appCategories.removeAll(removingAppCategories); } @@ -2466,7 +2514,8 @@ public class ApplicationManagerImpl implements ApplicationManager { ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); AtomicReference applicationReleaseDTO = new AtomicReference<>( applicationDTO.getApplicationReleaseDTOs().get(0)); - validateAppReleaseUpdating(applicationDTO, ApplicationType.ENTERPRISE.toString()); + validateAppReleaseUpdating(entAppReleaseWrapper, applicationDTO, applicationArtifact, + ApplicationType.ENTERPRISE.toString()); applicationReleaseDTO.get().setPrice(entAppReleaseWrapper.getPrice()); applicationReleaseDTO.get().setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); if (!StringUtils.isEmpty(entAppReleaseWrapper.getSupportedOsVersions())) { @@ -2530,7 +2579,8 @@ public class ApplicationManagerImpl implements ApplicationManager { try { ConnectionManagerUtil.beginDBTransaction(); ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); - validateAppReleaseUpdating(applicationDTO, ApplicationType.PUBLIC.toString()); + validateAppReleaseUpdating(publicAppReleaseWrapper, applicationDTO, applicationArtifact, + ApplicationType.PUBLIC.toString()); AtomicReference applicationReleaseDTO = new AtomicReference<>( applicationDTO.getApplicationReleaseDTOs().get(0)); @@ -2598,7 +2648,8 @@ public class ApplicationManagerImpl implements ApplicationManager { try { ConnectionManagerUtil.beginDBTransaction(); ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); - validateAppReleaseUpdating(applicationDTO, ApplicationType.WEB_CLIP.toString()); + validateAppReleaseUpdating(webAppReleaseWrapper, applicationDTO, applicationArtifact, + ApplicationType.WEB_CLIP.toString()); AtomicReference applicationReleaseDTO = new AtomicReference<>( applicationDTO.getApplicationReleaseDTOs().get(0)); @@ -2665,7 +2716,8 @@ public class ApplicationManagerImpl implements ApplicationManager { ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUuid, tenantId); AtomicReference applicationReleaseDTO = new AtomicReference<>( applicationDTO.getApplicationReleaseDTOs().get(0)); - validateAppReleaseUpdating(applicationDTO, ApplicationType.ENTERPRISE.toString()); + validateAppReleaseUpdating(customAppReleaseWrapper, applicationDTO, applicationArtifact, + ApplicationType.ENTERPRISE.toString()); applicationReleaseDTO.get().setPrice(customAppReleaseWrapper.getPrice()); applicationReleaseDTO.get() .setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); @@ -2700,7 +2752,6 @@ public class ApplicationManagerImpl implements ApplicationManager { throw new ApplicationStorageManagementException(msg); } if (!applicationReleaseDTO.get().getAppHashValue().equals(md5OfApp)) { - applicationReleaseDTO.get().setInstallerName(applicationArtifact.getInstallerName()); try { ConnectionManagerUtil.getDBConnection(); if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) { @@ -2713,6 +2764,7 @@ public class ApplicationManagerImpl implements ApplicationManager { throw new BadRequestException(msg); } + applicationReleaseDTO.get().setInstallerName(applicationArtifact.getInstallerName()); String deletingAppHashValue = applicationReleaseDTO.get().getAppHashValue(); applicationReleaseDTO.get().setAppHashValue(md5OfApp); try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { @@ -2778,7 +2830,18 @@ public class ApplicationManagerImpl implements ApplicationManager { } } - private void validateAppReleaseUpdating(ApplicationDTO applicationDTO, String appType) + /** + * To validate app release updating request + * + * @param param either {@link EntAppReleaseWrapper} or {@link PublicAppReleaseWrapper} + * or {@link WebAppReleaseWrapper} or {@link CustomAppReleaseWrapper} + * @param applicationDTO Existing application {@link ApplicationDTO} + * @param applicationArtifact Application release artifacts which contains either icon or screenshots or artifact + * @param appType Application Type + * @throws ApplicationManagementException if invalid application release updating payload received. + */ + private void validateAppReleaseUpdating(T param, ApplicationDTO applicationDTO, + ApplicationArtifact applicationArtifact, String appType) throws ApplicationManagementException { if (applicationDTO == null) { String msg = "Couldn't found an application for requested UUID."; @@ -2792,8 +2855,38 @@ public class ApplicationManagerImpl implements ApplicationManager { throw new ForbiddenException(msg); } + boolean requireToCheckUpdatability = false; + double price = 0.0; + String supportedOsVersions = null; + + if (param instanceof EntAppReleaseWrapper) { + EntAppReleaseWrapper entAppReleaseWrapper = (EntAppReleaseWrapper) param; + if (!StringUtils.isEmpty(applicationArtifact.getInstallerName()) + && applicationArtifact.getInstallerStream() != null) { + requireToCheckUpdatability = true; + } + price = entAppReleaseWrapper.getPrice(); + supportedOsVersions = entAppReleaseWrapper.getSupportedOsVersions(); + } else if (param instanceof PublicAppReleaseWrapper) { + PublicAppReleaseWrapper publicAppReleaseWrapper = (PublicAppReleaseWrapper) param; + if (!StringUtils.isBlank(publicAppReleaseWrapper.getPackageName())) { + requireToCheckUpdatability = true; + } + price = publicAppReleaseWrapper.getPrice(); + supportedOsVersions = publicAppReleaseWrapper.getSupportedOsVersions(); + } else if (param instanceof WebAppReleaseWrapper) { + WebAppReleaseWrapper webAppReleaseWrapper = (WebAppReleaseWrapper) param; + if (!StringUtils.isBlank(webAppReleaseWrapper.getUrl())) { + requireToCheckUpdatability = true; + } + } else if (param instanceof CustomAppReleaseWrapper && !StringUtils + .isEmpty(applicationArtifact.getInstallerName()) && applicationArtifact.getInstallerStream() != null) { + requireToCheckUpdatability = true; + } + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); - if (!lifecycleStateManager.isUpdatableState(applicationReleaseDTO.getCurrentState())) { + if (requireToCheckUpdatability && !lifecycleStateManager + .isUpdatableState(applicationReleaseDTO.getCurrentState())) { String msg = "Application release in " + applicationReleaseDTO.getCurrentState() + " state. Therefore you are not allowed to update the application release. Hence, " + "please move application release from " + applicationReleaseDTO.getCurrentState() @@ -2803,18 +2896,19 @@ public class ApplicationManagerImpl implements ApplicationManager { } String applicationSubType = applicationDTO.getSubType(); - double price = applicationReleaseDTO.getPrice(); if (price < 0.0 || (price == 0.0 && ApplicationSubscriptionType.PAID.toString().equals(applicationSubType)) || ( price > 0.0 && ApplicationSubscriptionType.FREE.toString().equals(applicationSubType))) { - throw new BadRequestException("Invalid app release payload for updating application release. Application " - + "price is " + price + " for " + applicationSubType + " application."); + String msg = + "Invalid app release payload for updating application release. Application " + "price is " + price + + " for " + applicationSubType + " application."; + log.error(msg); + throw new BadRequestException(msg); } - if (!ApplicationType.WEB_CLIP.toString().equals(appType) && !ApplicationType.WEB_APP.toString() + if (ApplicationType.ENTERPRISE.toString().equals(appType) || ApplicationType.PUBLIC.toString() .equals(appType)) { DeviceType deviceTypeObj = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); - String supportedOSVersions = applicationReleaseDTO.getSupportedOsVersions(); - if (!StringUtils.isEmpty(supportedOSVersions) && isInvalidOsVersionRange(supportedOSVersions, + if (!StringUtils.isEmpty(supportedOsVersions) && isInvalidOsVersionRange(supportedOsVersions, deviceTypeObj.getName())) { String msg = "You are trying to update application release which has invalid or unsupported OS " + "versions in the supportedOsVersions section. Hence, please re-evaluate the request payload."; 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/ApplicationManagementPublisherAPI.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/ApplicationManagementPublisherAPI.java index f157e98cba..870ad616ec 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/ApplicationManagementPublisherAPI.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/ApplicationManagementPublisherAPI.java @@ -679,10 +679,6 @@ public interface ApplicationManagementPublisherAPI { @ApiResponse( code = 200, message = "OK. \n Successfully updated artifacts."), - @ApiResponse( - code = 403, - message = "FORBIDDEN. \n Can't Update the application release in PUBLISHED or DEPRECATED " - + "state. Hence please demote the application and update the application release"), @ApiResponse( code = 404, message = "NOT FOUND. \n Error occurred while updating the application."), 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/ApplicationManagementPublisherAPIImpl.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/ApplicationManagementPublisherAPIImpl.java index ae864cb52e..9dfcde4f73 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/ApplicationManagementPublisherAPIImpl.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/ApplicationManagementPublisherAPIImpl.java @@ -404,11 +404,11 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem return Response.status(Response.Status.OK) .entity("Successfully uploaded artifacts for the application " + applicationReleaseUuid).build(); } catch (NotFoundException e) { - log.error(e.getMessage(), e); + String msg = "Couldn't found an application release which has application release UUID " + + applicationReleaseUuid + ". HEnce please verify the application release UUID again and execute " + + "the operation"; + log.error(msg, e); return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build(); - } catch (ForbiddenException e) { - log.error(e.getMessage(), e); - return Response.status(Response.Status.FORBIDDEN).entity(e.getMessage()).build(); } catch (ApplicationManagementException e) { String msg = "Error occurred while updating the application image artifacts for application release uuid: " + applicationReleaseUuid;