From e0e6301496d37e6093d1da4dbb1433c84b13f2b6 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Tue, 25 Jun 2019 23:28:01 +0530 Subject: [PATCH] Add app release updating feature --- .../mgt/common/response/Application.java | 20 +- .../common/services/ApplicationManager.java | 8 + .../common/wrapper/ApplicationWrapper.java | 18 +- .../mgt/core/impl/ApplicationManagerImpl.java | 334 ++++++++++++------ .../application/mgt/core/util/APIUtil.java | 8 +- .../management/ApplicationManagementTest.java | 4 +- .../ApplicationManagementPublisherAPI.java | 146 +++++++- ...ApplicationManagementPublisherAPIImpl.java | 92 +++++ 8 files changed, 498 insertions(+), 132 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java index 91dced53faa..568a6d186bf 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/response/Application.java @@ -35,11 +35,11 @@ public class Application { required = true) private String description; - @ApiModelProperty(name = "appCategories", + @ApiModelProperty(name = "categories", value = "CategoryDTO of the application", required = true, example = "Educational, Gaming, Travel, Entertainment etc") - private List appCategories; + private List categories; @ApiModelProperty(name = "type", value = "Type of the application", @@ -47,11 +47,11 @@ public class Application { example = "ENTERPRISE, PUBLIC, WEB, WEB_CLIP etc") private String type; - @ApiModelProperty(name = "subType", + @ApiModelProperty(name = "subMethod", value = "Subscription type of the application", required = true, example = "PAID, FREE") - private String subType; + private String subMethod; @ApiModelProperty(name = "paymentCurrency", value = "Payment currency of the application", @@ -92,12 +92,12 @@ public class Application { public void setName(String name) { this.name = name; } - public List getAppCategories() { - return appCategories; + public List getCategories() { + return categories; } - public void setAppCategories(List appCategories) { - this.appCategories = appCategories; + public void setCategories(List categories) { + this.categories = categories; } public List getTags() { return tags; } @@ -108,9 +108,9 @@ public class Application { public void setType(String type) { this.type = type; } - public String getSubType() { return subType; } + public String getSubMethod() { return subMethod; } - public void setSubType(String subType) { this.subType = subType; } + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } public String getPaymentCurrency() { return paymentCurrency; } 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 958d613513d..c8ef600e7d1 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 @@ -34,7 +34,9 @@ import org.wso2.carbon.device.application.mgt.common.response.Tag; import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppWrapper; import java.util.List; @@ -196,6 +198,12 @@ public interface ApplicationManager { boolean updateEntAppRelease(String deviceType, String releaseUuid, EntAppReleaseWrapper entAppReleaseWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + boolean updatePubAppRelease(String deviceType, String releaseUuid, PublicAppReleaseWrapper publicAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + + boolean updateWebAppRelease(String deviceType, String releaseUuid, WebAppReleaseWrapper webAppReleaseWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + /*** * To validate the application creating request * diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationWrapper.java index 02ef3a05f32..11ae27b7f2a 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationWrapper.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationWrapper.java @@ -38,20 +38,20 @@ public class ApplicationWrapper { @NotNull private String description; - @ApiModelProperty(name = "appCategories", + @ApiModelProperty(name = "categories", value = "CategoryDTO of the application", required = true, example = "Educational, Gaming, Travel, Entertainment etc") @NotNull - private List appCategories; + private List categories; - @ApiModelProperty(name = "subType", + @ApiModelProperty(name = "subMethod", value = "Subscription type of the application", required = true, example = "PAID, FREE") @NotNull - private String subType; + private String subMethod; @ApiModelProperty(name = "paymentCurrency", value = "Payment currency of the application", @@ -89,19 +89,19 @@ public class ApplicationWrapper { public void setName(String name) { this.name = name; } - public List getAppCategories() { return appCategories; } + public List getCategories() { return categories; } - public void setAppCategories(List appCategories) { - this.appCategories = appCategories; + public void setCategories(List categories) { + this.categories = categories; } public List getTags() { return tags; } public void setTags(List tags) { this.tags = tags; } - public String getSubType() { return subType; } + public String getSubMethod() { return subMethod; } - public void setSubType(String subType) { this.subType = subType; } + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } public String getPaymentCurrency() { return paymentCurrency; } 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 61c4f325b37..2763eb616d6 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 @@ -101,6 +101,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -265,21 +266,23 @@ public class ApplicationManagerImpl implements ApplicationManager { applicationReleaseDTO.setUuid(uuid); // The application executable artifacts such as apks are uploaded. - try { - byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); + try { + byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); - applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName()); + applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName()); - try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) { - ApplicationInstaller applicationInstaller = applicationStorageManager - .getAppInstallerData(binary, deviceType); - String packagename = applicationInstaller.getPackageName(); + try (ByteArrayInputStream binary = new ByteArrayInputStream(content)) { + ApplicationInstaller applicationInstaller = applicationStorageManager + .getAppInstallerData(binary, deviceType); + String packagename = applicationInstaller.getPackageName(); - ConnectionManagerUtil.getDBConnection(); - if (!isNewRelease && applicationReleaseDAO.isActiveReleaseExisitForPackageName(packagename, tenantId, - lifecycleStateManager.getEndState())) { - String msg = "Application release is already exist for the package name: " + packagename + - ". Either you can delete all application releases for package " + packagename + " or " + try { + ConnectionManagerUtil.openDBConnection(); + if (!isNewRelease && applicationReleaseDAO + .isActiveReleaseExisitForPackageName(packagename, tenantId, + lifecycleStateManager.getEndState())) { + String msg = "Application release is already exist for the package name: " + packagename + + ". Either you can delete all application releases for package " + packagename + " or " + "you can add this app release as an new application release, under the existing " + "application."; log.error(msg); @@ -295,36 +298,37 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new ApplicationStorageManagementException(msg); } - if (this.applicationReleaseDAO - .verifyReleaseExistenceByHash(md5OfApp, tenantId)) { - throw new BadRequestException( - "Application release exists for the uploaded binary file. Device Type: " + deviceType); + if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) { + String msg = + "Application release exists for the uploaded binary file. Device Type: " + deviceType; + log.error(msg); + throw new BadRequestException(msg); } - applicationReleaseDTO.setAppHashValue(md5OfApp); try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { applicationReleaseDTO = applicationStorageManager .uploadReleaseArtifact(applicationReleaseDTO, deviceType, binaryDuplicate); } + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection for verifying app release data."; + 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(); } - } 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(); + } + } 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); } return applicationReleaseDTO; } @@ -749,31 +753,30 @@ public class ApplicationManagerImpl implements ApplicationManager { public ApplicationRelease createEntAppRelease(int applicationId, EntAppReleaseWrapper entAppReleaseWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); - ApplicationRelease applicationRelease; if (log.isDebugEnabled()) { log.debug("Application release creating request is received for the application id: " + applicationId); } ApplicationDTO applicationDTO = getApplication(applicationId); + + if (!ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) { + String msg = "It is possible to add new application release for " + ApplicationType.ENTERPRISE.toString() + + " app type. But you are requesting to add new application release for " + applicationDTO.getType() + + " app type."; + log.error(msg); + throw new BadRequestException(msg); + } + DeviceType deviceType = getDeviceTypeData(applicationDTO.getDeviceTypeId()); + if (!isValidOsVersions(entAppReleaseWrapper.getSupportedOsVersions(), deviceType.getName())) { + String msg = "You are trying to add application release which has invalid or unsupported OS versions in " + + "the supportedOsVersions section. Hence, please re-evaluate the request payload."; + log.error(msg); + throw new BadRequestException(msg); + } + ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts( + APIUtil.releaseWrapperToReleaseDTO(entAppReleaseWrapper), applicationArtifact, deviceType.getName(), + true); try { - if (!ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) { - String msg = - "It is possible to add new application release for " + ApplicationType.ENTERPRISE.toString() - + " app type. But you are requesting to add new application release for " - + applicationDTO.getType() + " app type."; - log.error(msg); - throw new BadRequestException(msg); - } - DeviceType deviceType = getDeviceTypeData(applicationDTO.getDeviceTypeId()); - if (!isValidOsVersions(entAppReleaseWrapper.getSupportedOsVersions(), deviceType.getName())){ - String msg = "You are trying to add application release which has invalid or unsupported OS versions in " - + "the supportedOsVersions section. Hence, please re-evaluate the request payload."; - log.error(msg); - throw new BadRequestException(msg); - } - ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts( - APIUtil.releaseWrapperToReleaseDTO(entAppReleaseWrapper), - applicationArtifact, deviceType.getName(), true); ConnectionManagerUtil.beginDBTransaction(); String initialstate = lifecycleStateManager.getInitialState(); applicationReleaseDTO.setCurrentState(initialstate); @@ -782,7 +785,7 @@ public class ApplicationManagerImpl implements ApplicationManager { .createRelease(applicationReleaseDTO, applicationDTO.getId(), tenantId); this.lifecycleStateDAO .addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); - applicationRelease = APIUtil.releaseDtoToRelease(applicationReleaseDTO); + ApplicationRelease applicationRelease = APIUtil.releaseDtoToRelease(applicationReleaseDTO); ConnectionManagerUtil.commitDBTransaction(); return applicationRelease; } catch (TransactionManagementException e) { @@ -2132,67 +2135,145 @@ public class ApplicationManagerImpl implements ApplicationManager { ConnectionManagerUtil.beginDBTransaction(); ApplicationDTO applicationDTO = this.applicationDAO.getApplicationByUUID(releaseUuid, tenantId); - if (applicationDTO == null) { - String msg = "Couldn't found an application which has application release for UUID: " + releaseUuid; - log.error(msg); - throw new NotFoundException(msg); + AtomicReference applicationReleaseDTO = new AtomicReference<>( + applicationDTO.getApplicationReleaseDTOs().get(0)); + validateAppReleaseUpdating(applicationDTO, ApplicationType.ENTERPRISE.toString()); + applicationReleaseDTO.get().setPrice(entAppReleaseWrapper.getPrice()); + applicationReleaseDTO.get().setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); + if (!StringUtils.isEmpty(entAppReleaseWrapper.getSupportedOsVersions())) { + applicationReleaseDTO.get().setSupportedOsVersions(entAppReleaseWrapper.getSupportedOsVersions()); } - if (!ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) { - String msg = "You trying to perform enterprise app release update on non-enterprise app release."; - log.error(msg); - throw new ForbiddenException(msg); + if (!StringUtils.isEmpty(entAppReleaseWrapper.getDescription())) { + applicationReleaseDTO.get().setDescription(entAppReleaseWrapper.getDescription()); } - - ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); - if (!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() - + " to updatable state."; - log.error(msg); - throw new ForbiddenException(msg); + if (!StringUtils.isEmpty(entAppReleaseWrapper.getReleaseType())) { + applicationReleaseDTO.get().setReleaseType(entAppReleaseWrapper.getReleaseType()); + } + if (!StringUtils.isEmpty(entAppReleaseWrapper.getMetaData())) { + applicationReleaseDTO.get().setMetaData(entAppReleaseWrapper.getMetaData()); } - DeviceType deviceTypeObj = getDeviceTypeData(deviceType); - Double price = entAppReleaseWrapper.getPrice(); + if (!StringUtils.isEmpty(applicationArtifact.getInstallerName())&& applicationArtifact.getInstallerStream() != null){ + DeviceType deviceTypeObj = getDeviceTypeData(applicationDTO.getDeviceTypeId()); + applicationReleaseDTO + .set(updateEntAppReleaseArtifact(deviceTypeObj.getName(), applicationReleaseDTO.get(), + applicationArtifact)); + } + applicationReleaseDTO.set(updateImageArtifacts(applicationReleaseDTO.get(), applicationArtifact)); - String applicationSubType = applicationDTO.getSubType(); - 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. ApplicationDTO price is " + price - + " for " + applicationSubType + " application., Application Release UUID " - + releaseUuid + " and supported device type is " + deviceType); + boolean updateStatus = applicationReleaseDAO.updateRelease(applicationReleaseDTO.get(), tenantId) != null; + if (!updateStatus) { + ConnectionManagerUtil.rollbackDBTransaction(); } - applicationReleaseDTO.setPrice(price); - applicationReleaseDTO.setIsSharedWithAllTenants(applicationReleaseDTO.getIsSharedWithAllTenants()); + ConnectionManagerUtil.commitDBTransaction(); + return updateStatus; + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured when updating Ent Application release of UUID: " + releaseUuid; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (ResourceManagementException e) { + String msg = "Error occured when updating application release artifact in the file system. Ent App release " + + "UUID:" + releaseUuid; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } - String supportedOSVersions = entAppReleaseWrapper.getSupportedOsVersions(); - if (!StringUtils.isEmpty(supportedOSVersions)) { - if (!isValidOsVersions(supportedOSVersions, deviceType)){ - 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."; - log.error(msg); - throw new BadRequestException(msg); } - applicationReleaseDTO.setSupportedOsVersions(supportedOSVersions); + @Override + public boolean updatePubAppRelease(String deviceType, String releaseUuid, + PublicAppReleaseWrapper publicAppReleaseWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationDTO applicationDTO = this.applicationDAO.getApplicationByUUID(releaseUuid, tenantId); + validateAppReleaseUpdating(applicationDTO, ApplicationType.PUBLIC.toString()); + AtomicReference applicationReleaseDTO = new AtomicReference<>( + applicationDTO.getApplicationReleaseDTOs().get(0)); + + applicationReleaseDTO.get().setPrice(publicAppReleaseWrapper.getPrice()); + applicationReleaseDTO.get().setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); + + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getPackageName())) { + applicationReleaseDTO.get().setVersion(publicAppReleaseWrapper.getVersion()); } - if (!StringUtils.isEmpty(entAppReleaseWrapper.getDescription())) { - applicationReleaseDTO.setDescription(entAppReleaseWrapper.getDescription()); + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getVersion())) { + applicationReleaseDTO.get().setVersion(publicAppReleaseWrapper.getVersion()); } - if (!StringUtils.isEmpty(entAppReleaseWrapper.getReleaseType())) { - applicationReleaseDTO.setReleaseType(entAppReleaseWrapper.getReleaseType()); + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getSupportedOsVersions())) { + applicationReleaseDTO.get().setSupportedOsVersions(publicAppReleaseWrapper.getSupportedOsVersions()); } - if (!StringUtils.isEmpty(entAppReleaseWrapper.getMetaData())) { - applicationReleaseDTO.setMetaData(entAppReleaseWrapper.getMetaData()); + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getDescription())) { + applicationReleaseDTO.get().setDescription(publicAppReleaseWrapper.getDescription()); + } + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getReleaseType())) { + applicationReleaseDTO.get().setReleaseType(publicAppReleaseWrapper.getReleaseType()); + } + if (!StringUtils.isEmpty(publicAppReleaseWrapper.getMetaData())) { + applicationReleaseDTO.get().setMetaData(publicAppReleaseWrapper.getMetaData()); } - if (!StringUtils.isEmpty(applicationArtifact.getInstallerName())&& applicationArtifact.getInstallerStream() != null){ - applicationReleaseDTO = updateEntAppReleaseArtifact(deviceTypeObj.getName(), - applicationReleaseDTO, applicationArtifact); + applicationReleaseDTO.set(updateImageArtifacts(applicationReleaseDTO.get(), applicationArtifact)); + + boolean updateStatus = applicationReleaseDAO.updateRelease(applicationReleaseDTO.get(), tenantId) != null; + if (!updateStatus) { + ConnectionManagerUtil.rollbackDBTransaction(); + } + ConnectionManagerUtil.commitDBTransaction(); + return updateStatus; + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occured when updating public app release of UUID: " + releaseUuid; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (ResourceManagementException e) { + String msg = "Error occured when updating public app release artifact in the file system. Public app " + + "release UUID:" + releaseUuid; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public boolean updateWebAppRelease(String deviceType, String releaseUuid, + WebAppReleaseWrapper webAppReleaseWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException { + + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.beginDBTransaction(); + ApplicationDTO applicationDTO = this.applicationDAO.getApplicationByUUID(releaseUuid, tenantId); + validateAppReleaseUpdating(applicationDTO, ApplicationType.WEB_CLIP.toString()); + AtomicReference applicationReleaseDTO = new AtomicReference<>( + applicationDTO.getApplicationReleaseDTOs().get(0)); + + applicationReleaseDTO.get().setPrice(webAppReleaseWrapper.getPrice()); + applicationReleaseDTO.get().setIsSharedWithAllTenants(applicationReleaseDTO.get().getIsSharedWithAllTenants()); + + if (!StringUtils.isEmpty(webAppReleaseWrapper.getVersion())) { + applicationReleaseDTO.get().setVersion(webAppReleaseWrapper.getVersion()); + } + if (!StringUtils.isEmpty(webAppReleaseWrapper.getVersion())) { + applicationReleaseDTO.get().setVersion(webAppReleaseWrapper.getVersion()); + } + if (!StringUtils.isEmpty(webAppReleaseWrapper.getDescription())) { + applicationReleaseDTO.get().setDescription(webAppReleaseWrapper.getDescription()); + } + if (!StringUtils.isEmpty(webAppReleaseWrapper.getReleaseType())) { + applicationReleaseDTO.get().setReleaseType(webAppReleaseWrapper.getReleaseType()); + } + if (!StringUtils.isEmpty(webAppReleaseWrapper.getMetaData())) { + applicationReleaseDTO.get().setMetaData(webAppReleaseWrapper.getMetaData()); } - applicationReleaseDTO = updateImageArtifacts(applicationReleaseDTO, applicationArtifact); - boolean updateStatus = applicationReleaseDAO.updateRelease(applicationReleaseDTO, tenantId) != null; + applicationReleaseDTO.set(updateImageArtifacts(applicationReleaseDTO.get(), applicationArtifact)); + boolean updateStatus = applicationReleaseDAO.updateRelease(applicationReleaseDTO.get(), tenantId) != null; if (!updateStatus) { ConnectionManagerUtil.rollbackDBTransaction(); } @@ -2200,12 +2281,11 @@ public class ApplicationManagerImpl implements ApplicationManager { return updateStatus; } catch (ApplicationManagementDAOException e) { ConnectionManagerUtil.rollbackDBTransaction(); - String msg = "Error occured when updating Application release. ApplicationDTO ID ApplicationDTO Release " - + "UUID: " + releaseUuid; + String msg = "Error occured when updating web app release for web app Release UUID: " + releaseUuid; log.error(msg); throw new ApplicationManagementException(msg, e); } catch (ResourceManagementException e) { - String msg = "Error occured when updating application release artifact in the file system. Application " + String msg = "Error occured when updating web app release artifact in the file system. Web app " + "release UUID:" + releaseUuid; log.error(msg); throw new ApplicationManagementException(msg, e); @@ -2214,6 +2294,50 @@ public class ApplicationManagerImpl implements ApplicationManager { } } + private void validateAppReleaseUpdating(ApplicationDTO applicationDTO, String appType) throws ApplicationManagementException { + + if (applicationDTO == null) { + String msg = "Couldn't found an application for requested UUID."; + log.error(msg); + throw new NotFoundException(msg); + } + if (!appType.equals(applicationDTO.getType())) { + String msg = "You trying to perform " + appType + " app release update on " + applicationDTO.getType() + + " app release."; + log.error(msg); + throw new ForbiddenException(msg); + } + + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + if (!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() + + " to updatable state."; + log.error(msg); + throw new ForbiddenException(msg); + } + + 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."); + } + + DeviceType deviceTypeObj = getDeviceTypeData(applicationDTO.getDeviceTypeId()); + String supportedOSVersions = applicationReleaseDTO.getSupportedOsVersions(); + if (!ApplicationType.WEB_CLIP.toString().equals(appType) && !ApplicationType.WEB_APP.toString().equals(appType) + && !StringUtils.isEmpty(supportedOSVersions) && !isValidOsVersions( + 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."; + log.error(msg); + throw new BadRequestException(msg); + } + } + @Override public void validateAppCreatingRequest(T param) throws ApplicationManagementException { @@ -2232,7 +2356,7 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new BadRequestException(msg); } - appCategories = applicationWrapper.getAppCategories(); + appCategories = applicationWrapper.getCategories(); if (appCategories == null) { String msg = "Application category can't be null."; log.error(msg); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java index ac5431be788..5cb40626431 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/APIUtil.java @@ -229,9 +229,9 @@ public class APIUtil { DeviceType deviceType = getDeviceTypeData(applicationWrapper.getDeviceType()); applicationDTO.setName(applicationWrapper.getName()); applicationDTO.setDescription(applicationWrapper.getDescription()); - applicationDTO.setAppCategories(applicationWrapper.getAppCategories()); + applicationDTO.setAppCategories(applicationWrapper.getCategories()); applicationDTO.setType(ApplicationType.ENTERPRISE.toString()); - applicationDTO.setSubType(applicationWrapper.getSubType()); + applicationDTO.setSubType(applicationWrapper.getSubMethod()); applicationDTO.setPaymentCurrency(applicationWrapper.getPaymentCurrency()); applicationDTO.setTags(applicationWrapper.getTags()); applicationDTO.setUnrestrictedRoles(applicationWrapper.getUnrestrictedRoles()); @@ -319,9 +319,9 @@ public class APIUtil { application.setId(applicationDTO.getId()); application.setName(applicationDTO.getName()); application.setDescription(applicationDTO.getDescription()); - application.setAppCategories(applicationDTO.getAppCategories()); + application.setCategories(applicationDTO.getAppCategories()); application.setType(applicationDTO.getType()); - application.setSubType(applicationDTO.getSubType()); + application.setSubMethod(applicationDTO.getSubType()); application.setPaymentCurrency(applicationDTO.getPaymentCurrency()); application.setTags(applicationDTO.getTags()); application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles()); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/management/ApplicationManagementTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/management/ApplicationManagementTest.java index cd5cc13e588..eae1997cdd6 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/management/ApplicationManagementTest.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/management/ApplicationManagementTest.java @@ -58,12 +58,12 @@ public class ApplicationManagementTest extends BaseTestCase { List categories = new ArrayList<>(); categories.add("Test Category"); - applicationWrapper.setAppCategories(categories); + applicationWrapper.setCategories(categories); applicationWrapper.setDescription("Test Description"); applicationWrapper.setDeviceType("android"); applicationWrapper.setName("Test Application"); - applicationWrapper.setSubType("Test Sub type"); + applicationWrapper.setSubMethod("Test Sub type"); List tags = new ArrayList<>(); tags.add("abc"); 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 08dfc42d4b9..c3bf7fe9eb9 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 @@ -42,7 +42,9 @@ import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppWrapper; import java.util.List; @@ -747,8 +749,78 @@ public interface ApplicationManagementPublisherAPI { @Multipart(value = "binaryFile") Attachment binaryFile, @ApiParam( name = "icon", - value = "Icon file of the application release.", + value = "Icon file of the application release.") + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "banner file of the application release.") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "First screenshot of the uploading application") + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Second screenshot 2 of the uploading application") + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Third screenshot of the uploading application") + @Multipart(value = "screenshot3") Attachment screenshot3); + + @PUT + @Path("/pub-app-release/{deviceType}/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + @ApiOperation( + consumes = MediaType.MULTIPART_FORM_DATA, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update an public app release", + notes = "This will update the public app release", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully update an app release.", + response = ApplicationReleaseDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Public app release updating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + Response updatePubAppRelease( + @ApiParam( + name = "deviceType", + value = "Supported device type of the application", + required = true) + @PathParam("deviceType") String deviceType, + @ApiParam( + name = "UUID", + value = "Unique identifier of the ApplicationDTO Release", required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "pubAppReleaseWrapper", + value = "Application release wrapper which is going to update.", + required = true) + @Multipart( + value = "pubAppReleaseWrapper", + type = "application/json") PublicAppReleaseWrapper publicAppReleaseWrapper, + @ApiParam( + name = "icon", + value = "Icon file of the application release.") @Multipart(value = "icon") Attachment iconFile, @ApiParam( name = "banner", @@ -756,8 +828,78 @@ public interface ApplicationManagementPublisherAPI { @Multipart(value = "banner") Attachment bannerFile, @ApiParam( name = "screenshot1", - value = "First screenshot of the uploading application", + value = "First screenshot of the uploading application") + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Second screenshot 2 of the uploading application") + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Third screenshot of the uploading application") + @Multipart(value = "screenshot3") Attachment screenshot3); + + @PUT + @Path("/web-app-release/{deviceType}/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + @ApiOperation( + consumes = MediaType.MULTIPART_FORM_DATA, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update an public app release", + notes = "This will update the public app release", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully update an app release.", + response = ApplicationReleaseDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Public app release updating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while releasing the application.", + response = ErrorResponse.class) + }) + Response updateWebAppRelease( + @ApiParam( + name = "deviceType", + value = "Supported device type of the application", + required = true) + @PathParam("deviceType") String deviceType, + @ApiParam( + name = "UUID", + value = "Unique identifier of the ApplicationDTO Release", required = true) + @PathParam("uuid") String applicationUUID, + @ApiParam( + name = "pubAppReleaseWrapper", + value = "Application release wrapper which is going to update.", + required = true) + @Multipart( + value = "pubAppReleaseWrapper", + type = "application/json") WebAppReleaseWrapper webAppReleaseWrapper, + @ApiParam( + name = "icon", + value = "Icon file of the application release.") + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "banner file of the application release.") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "First screenshot of the uploading application") @Multipart(value = "screenshot1") Attachment screenshot1, @ApiParam( name = "screenshot2", 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 05ab98ee3aa..9d4fd2b46c4 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 @@ -32,7 +32,9 @@ import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; import org.wso2.carbon.device.application.mgt.common.wrapper.EntAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationUpdateWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.PublicAppWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppReleaseWrapper; import org.wso2.carbon.device.application.mgt.common.wrapper.WebAppWrapper; import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; @@ -454,6 +456,96 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem } } + @Override + @PUT + @Path("/public-app-release/{deviceType}/{uuid}") + public Response updatePubAppRelease( + @PathParam("deviceType") String deviceType, + @PathParam("uuid") String applicationUUID, + @Multipart("applicationRelease") PublicAppReleaseWrapper publicAppReleaseWrapper, + @Multipart(value = "icon", required = false) Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart(value = "screenshot1", required = false) Attachment screenshot1, + @Multipart(value = "screenshot2", required = false) Attachment screenshot2, + @Multipart(value = "screenshot3", required = false) Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + if (!applicationManager.updatePubAppRelease(deviceType, applicationUUID, publicAppReleaseWrapper, + constructApplicationArtifact(null, iconFile, bannerFile, screenshots))) { + String msg ="Application release updating is failed. Please contact the administrator. " + + "ApplicationDTO release UUID: " + applicationUUID + ", Supported device type: " + deviceType; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity("Application release is successfully updated.").build(); + } catch (BadRequestException e) { + String msg = + "Invalid request to update application release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (NotFoundException e) { + String msg = + "Couldn't found application or application release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to update the application release which has UUID " + + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error while updating the application release of the application with UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + @PUT + @Path("/web-app-release/{deviceType}/{uuid}") + public Response updateWebAppRelease( + @PathParam("deviceType") String deviceType, + @PathParam("uuid") String applicationUUID, + @Multipart("applicationRelease") WebAppReleaseWrapper webAppReleaseWrapper, + @Multipart(value = "icon", required = false) Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart(value = "screenshot1", required = false) Attachment screenshot1, + @Multipart(value = "screenshot2", required = false) Attachment screenshot2, + @Multipart(value = "screenshot3", required = false) Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List screenshots = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + if (!applicationManager.updateWebAppRelease(deviceType, applicationUUID, webAppReleaseWrapper, + constructApplicationArtifact(null, iconFile, bannerFile, screenshots))) { + String msg ="Application release updating is failed. Please contact the administrator. " + + "ApplicationDTO release UUID: " + applicationUUID + ", Supported device type: " + deviceType; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity("Application release is successfully updated.").build(); + } catch (BadRequestException e) { + String msg = + "Invalid request to update application release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (NotFoundException e) { + String msg = + "Couldn't found application or application release for application release UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (ForbiddenException e) { + String msg = "You don't have require permission to update the application release which has UUID " + + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.FORBIDDEN).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error while updating the application release of the application with UUID " + applicationUUID; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + @PUT @Path("/retire/{appId}")