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 cf49bf2a326..a0979e449c0 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 @@ -35,6 +35,7 @@ import org.wso2.carbon.device.application.mgt.common.response.Tag; import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper; 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.WebClipWrapper; import java.util.List; @@ -53,6 +54,9 @@ public interface ApplicationManager { Application createApplication(ApplicationWrapper applicationWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException, RequestValidatingException; + Application createWebClip(WebClipWrapper webClipWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException; + /** * Updates an already existing application. * @@ -203,19 +207,14 @@ public interface ApplicationManager { /*** * To validate the application creating request * - * @param applicationWrapper {@link ApplicationDTO} - * @throws RequestValidatingException if the payload contains invalid inputs. */ - void validateAppCreatingRequest(ApplicationWrapper applicationWrapper) throws RequestValidatingException; + void validateAppCreatingRequest(T param) throws ApplicationManagementException; /*** * - * @param applicationReleaseWrapper {@link ApplicationReleaseDTO} - * @param applicationType Type of the application * @throws RequestValidatingException throws if payload does not satisfy requrements. */ - void validateReleaseCreatingRequest(ApplicationReleaseWrapper applicationReleaseWrapper, String applicationType) - throws RequestValidatingException; + void validateReleaseCreatingRequest(T param) 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/ApplicationReleaseWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationReleaseWrapper.java index 3d991776474..b220ab7d917 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationReleaseWrapper.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/ApplicationReleaseWrapper.java @@ -47,10 +47,6 @@ public class ApplicationReleaseWrapper { required = true) private String metaData; - @ApiModelProperty(name = "url", - value = "URL which is used for WEB-CLIP") - private String url; - @ApiModelProperty(name = "supportedOsVersions", value = "ApplicationDTO release supported OS versions") private String supportedOsVersions; @@ -87,14 +83,6 @@ public class ApplicationReleaseWrapper { return metaData; } - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebClipReleaseWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebClipReleaseWrapper.java new file mode 100644 index 00000000000..8187eda76b2 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebClipReleaseWrapper.java @@ -0,0 +1,97 @@ +/* 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. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store") +public class WebClipReleaseWrapper { + + @ApiModelProperty(name = "description", + value = "Description of the web clip release") + private String description; + + @ApiModelProperty(name = "releaseType", + value = "Release type of the web clip release", + required = true, + example = "alpha, beta etc") + private String releaseType; + + @ApiModelProperty(name = "price", + value = "Price of the web clip release", + required = true) + private Double price; + + @ApiModelProperty(name = "isSharedWithAllTenants", + value = "If web clip release is shared with all tenants it is equal to 1 otherwise 0", + required = true) + private boolean isSharedWithAllTenants; + + @ApiModelProperty(name = "metaData", + value = "Meta data of the web clip release", + required = true) + private String metaData; + + @ApiModelProperty(name = "url", + value = "URL which is used for WEB-CLIP") + private String url; + + public String getReleaseType() { + return releaseType; + } + + public void setReleaseType(String releaseType) { + this.releaseType = releaseType; + } + + public void setIsSharedWithAllTenants(boolean isSharedWithAllTenants) { + this.isSharedWithAllTenants = isSharedWithAllTenants; + } + + public void setMetaData(String metaData) { + this.metaData = metaData; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public boolean getIsSharedWithAllTenants() { + return isSharedWithAllTenants; + } + + public String getMetaData() { + return metaData; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebClipWrapper.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebClipWrapper.java new file mode 100644 index 00000000000..b5c1b5ce420 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/wrapper/WebClipWrapper.java @@ -0,0 +1,102 @@ +/* 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. + */ +package org.wso2.carbon.device.application.mgt.common.wrapper; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "WebClipWrapper", description = "WebClipWrapper represents an ApplicationDTO in ApplicationDTO Store") +public class WebClipWrapper { + + @ApiModelProperty(name = "name", + value = "Name of the web clip", + required = true) + private String name; + + @ApiModelProperty(name = "description", + value = "Description of the web clip", + required = true) + private String description; + + @ApiModelProperty(name = "categories", + value = "List of Categories", + required = true, + example = "Educational, Gaming, Travel, Entertainment etc") + private List categories; + + @ApiModelProperty(name = "subType", + value = "Subscription method of the web clip", + required = true, + example = "PAID, FREE") + private String subMethod; + + @ApiModelProperty(name = "paymentCurrency", + value = "Payment currency of the web clip", + required = true, + example = "$") + private String paymentCurrency; + + @ApiModelProperty(name = "tags", + value = "List of tags") + private List tags; + + @ApiModelProperty(name = "unrestrictedRoles", + value = "List of roles that users should have to view the web clip") + private List unrestrictedRoles; + + @ApiModelProperty(name = "applicationReleaseWrappers", + value = "List of web clip releases", + required = true) + private List webClipReleaseWrappers; + + public String getName() { + return name; + } + + public void setName(String name) { this.name = name; } + + public List getTags() { return tags; } + + public void setTags(List tags) { this.tags = tags; } + + public String getPaymentCurrency() { return paymentCurrency; } + + public void setPaymentCurrency(String paymentCurrency) { this.paymentCurrency = paymentCurrency; } + + public List getUnrestrictedRoles() { return unrestrictedRoles; } + + public void setUnrestrictedRoles(List unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; } + + public String getDescription() { return description; } + + public void setDescription(String description) { this.description = description; } + + public List getWebClipReleaseWrappers() { return webClipReleaseWrappers; } + + public void setWebClipReleaseWrappers(List webClipReleaseWrappers) { + this.webClipReleaseWrappers = webClipReleaseWrappers; } + + public List getCategories() { return categories; } + + public void setCategories(List categories) { this.categories = categories; } + + public String getSubMethod() { return subMethod; } + + public void setSubMethod(String subMethod) { this.subMethod = subMethod; } +} 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 7e24b9ac367..30d7beb3e3c 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 @@ -83,6 +83,9 @@ public interface ApplicationDAO { List getAllCategories(int tenantId) throws ApplicationManagementDAOException; + List getCategoryIdsForCategoryNames(List CatgeoryNames, int tenantId) + throws ApplicationManagementDAOException; + List getDistinctCategoryIdsInCategoryMapping() throws ApplicationManagementDAOException; CategoryDTO getCategoryForCategoryName(String categoryName, 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 4840cf1e5cc..e98096d865f 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 @@ -805,6 +805,40 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic } } + @Override + public List getCategoryIdsForCategoryNames(List categoryNames, int tenantId) + throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to get tag ids for given tag names"); + } + try { + Connection conn = this.getDBConnection(); + int index = 1; + List tagIds = new ArrayList<>(); + StringJoiner joiner = new StringJoiner(",", + "SELECT AP_APP_CATEGORY.ID AS ID FROM AP_APP_CATEGORY WHERE AP_APP_CATEGORY.CATEGORY IN (", ") AND TENANT_ID = ?"); + categoryNames.stream().map(ignored -> "?").forEach(joiner::add); + String query = joiner.toString(); + try (PreparedStatement ps = conn.prepareStatement(query)) { + for (String categoryName : categoryNames) { + ps.setObject(index++, categoryName); + } + ps.setInt(index, tenantId); + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + tagIds.add(rs.getInt("ID")); + } + } + } + return tagIds; + } catch (DBConnectionException e) { + throw new ApplicationManagementDAOException( + "Error occurred while obtaining the DB connection when getting categories", e); + } catch (SQLException e) { + throw new ApplicationManagementDAOException("Error occurred while getting categories", e); + } + } + @Override public List getDistinctCategoryIdsInCategoryMapping() throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { 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 01909c468a6..a0152321d3f 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 @@ -17,6 +17,7 @@ package org.wso2.carbon.device.application.mgt.core.impl; +import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.validator.routines.UrlValidator; @@ -57,6 +58,8 @@ import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorage import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper; 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.WebClipReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebClipWrapper; import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; import org.wso2.carbon.device.application.mgt.core.dao.ApplicationReleaseDAO; @@ -64,6 +67,7 @@ import org.wso2.carbon.device.application.mgt.core.dao.LifecycleStateDAO; import org.wso2.carbon.device.application.mgt.core.dao.SubscriptionDAO; import org.wso2.carbon.device.application.mgt.core.dao.VisibilityDAO; import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import org.wso2.carbon.device.application.mgt.core.util.APIUtil; import org.wso2.carbon.device.application.mgt.core.util.DAOUtil; import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; @@ -149,7 +153,7 @@ public class ApplicationManagerImpl implements ApplicationManager { //validating and verifying application data try { ConnectionManagerUtil.openDBConnection(); - applicationDTO = appWrapperToAppDTO(applicationWrapper); + applicationDTO = APIUtil.convertToAppDTO(applicationWrapper); unrestrictedRoles = applicationWrapper.getUnrestrictedRoles(); tags = applicationWrapper.getTags(); @@ -316,7 +320,7 @@ public class ApplicationManagerImpl implements ApplicationManager { .addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); applicationReleaseEntities.add(applicationReleaseDTO); applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); - Application application = appDtoToAppResponse(applicationDTO); + Application application = APIUtil.appDtoToAppResponse(applicationDTO); ConnectionManagerUtil.commitDBTransaction(); return application; } @@ -617,6 +621,182 @@ public class ApplicationManagerImpl implements ApplicationManager { return applicationReleaseDTO; } + @Override + public Application createWebClip(WebClipWrapper webClipWrapper, ApplicationArtifact applicationArtifact) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (log.isDebugEnabled()) { + log.debug("Application create request is received for the tenant : " + tenantId + " From" + " the user : " + + userName); + } + + List categoryIds; + ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(webClipWrapper); + List unrestrictedRoles = applicationDTO.getUnrestrictedRoles(); + List tags = applicationDTO.getTags(); + List categories = applicationDTO.getAppCategories(); + try { + ConnectionManagerUtil.openDBConnection(); + categoryIds = applicationDAO.getCategoryIdsForCategoryNames(categories, tenantId); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting data which is related to application. application name: " + + webClipWrapper.getName() + "."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + + ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + String uuid = UUID.randomUUID().toString(); + applicationReleaseDTO.setUuid(uuid); + String md5 = DigestUtils.md5Hex(applicationReleaseDTO.getInstallerName()); + applicationReleaseDTO.setAppHashValue(md5); + applicationDTO.setType(ApplicationType.WEB_CLIP.toString()); + + //uploading application artifacts + try { + applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact); + applicationDTO.getApplicationReleaseDTOs().clear(); + applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); + } catch (ResourceManagementException e) { + String msg = "Error Occured when uploading artifacts of the application: " + webClipWrapper.getName(); + log.error(msg); + throw new ApplicationManagementException(msg, e); + } + + //insert application data into database + ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager(); + try { + List applicationReleaseEntities = new ArrayList<>(); + + ConnectionManagerUtil.beginDBTransaction(); + // Insert to application table + int appId = this.applicationDAO.createApplication(applicationDTO, tenantId); + if (appId == -1) { + log.error("Application data storing is Failed."); + ConnectionManagerUtil.rollbackDBTransaction(); + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue())); + return null; + } else { + if (log.isDebugEnabled()) { + log.debug("New ApplicationDTO entry added to AP_APP table. App Id:" + appId); + } + //add application categories + this.applicationDAO.addCategoryMapping(categoryIds, appId, tenantId); + + //adding application unrestricted roles + if (unrestrictedRoles != null && !unrestrictedRoles.isEmpty()) { + this.visibilityDAO.addUnrestrictedRoles(unrestrictedRoles, appId, tenantId); + if (log.isDebugEnabled()) { + log.debug("New restricted roles to app ID mapping added to AP_UNRESTRICTED_ROLE table." + + " App Id:" + appId); + } + } + + //adding application tags + if (tags != null && !tags.isEmpty()) { + List registeredTags = applicationDAO.getAllTags(tenantId); + List registeredTagNames = new ArrayList<>(); + List tagIds = new ArrayList<>(); + + for (TagDTO tagDTO : registeredTags) { + registeredTagNames.add(tagDTO.getTagName()); + } + List newTags = getDifference(tags, registeredTagNames); + if (!newTags.isEmpty()) { + this.applicationDAO.addTags(newTags, tenantId); + if (log.isDebugEnabled()) { + log.debug("New tags entry added to AP_APP_TAG table. App Id:" + appId); + } + tagIds = this.applicationDAO.getTagIdsForTagNames(tags, tenantId); + } else { + for (TagDTO tagDTO : registeredTags) { + for (String tagName : tags) { + if (tagName.equals(tagDTO.getTagName())) { + tagIds.add(tagDTO.getId()); + break; + } + } + } + } + this.applicationDAO.addTagMapping(tagIds, appId, tenantId); + } + + if (log.isDebugEnabled()) { + log.debug("Creating a new release. App Id:" + appId); + } + String initialLifecycleState = lifecycleStateManager.getInitialState(); + applicationReleaseDTO.setCurrentState(initialLifecycleState); + applicationReleaseDTO = this.applicationReleaseDAO + .createRelease(applicationReleaseDTO, appId, tenantId); + LifecycleState lifecycleState = getLifecycleStateInstance(initialLifecycleState, + initialLifecycleState); + this.lifecycleStateDAO + .addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); + applicationReleaseEntities.add(applicationReleaseDTO); + applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); + Application application = APIUtil.appDtoToAppResponse(applicationDTO); + ConnectionManagerUtil.commitDBTransaction(); + return application; + } + } catch (LifeCycleManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "Error occurred while adding lifecycle state. application name: " + webClipWrapper.getName() + "."; + log.error(msg); + try { + applicationStorageManager.deleteAllApplicationReleaseArtifacts( + Collections.singletonList(applicationReleaseDTO.getAppHashValue())); + } catch (ApplicationStorageManagementException ex) { + String errorLog = + "Error occurred when deleting application artifacts. Application artifacts are tried to " + + "delete because of lifecycle state adding issue in the application creating operation."; + log.error(errorLog); + throw new ApplicationManagementException(errorLog, e); + } + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while adding application or application release. application name: " + + webClipWrapper.getName() + "."; + log.error(msg); + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue())); + throw new ApplicationManagementException(msg, e); + } catch (LifecycleManagementException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when getting initial lifecycle state. application name: " + webClipWrapper + .getName() + "."; + log.error(msg); + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue())); + throw new ApplicationManagementException(msg, e); + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (VisibilityManagementDAOException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "Error occurred while adding unrestricted roles. application name: " + webClipWrapper.getName() + + "."; + log.error(msg); + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue())); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + + } + @Override public ApplicationList getApplications(Filter filter) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); @@ -688,7 +868,7 @@ public class ApplicationManagerImpl implements ApplicationManager { } for (ApplicationDTO appDTO : filteredApplications) { - applications.add(appDtoToAppResponse(appDTO)); + applications.add(APIUtil.appDtoToAppResponse(appDTO)); } Pagination pagination = new Pagination(); @@ -752,7 +932,7 @@ public class ApplicationManagerImpl implements ApplicationManager { .createRelease(applicationReleaseDTO, applicationDTO.getId(), tenantId); this.lifecycleStateDAO .addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); - applicationRelease = releaseDtoToRelease(applicationReleaseDTO); + applicationRelease = APIUtil.releaseDtoToRelease(applicationReleaseDTO); ConnectionManagerUtil.commitDBTransaction(); return applicationRelease; } catch (TransactionManagementException e) { @@ -807,7 +987,7 @@ public class ApplicationManagerImpl implements ApplicationManager { try { DeviceType deviceType = getDeviceTypeData(applicationDTO.getDeviceTypeId()); ApplicationReleaseDTO applicationReleaseDTO = addApplicationReleaseArtifacts(applicationDTO.getType(), - deviceType.getName(), releaseWrapperToReleaseDTO(applicationReleaseWrapper), applicationArtifact, + deviceType.getName(), APIUtil.releaseWrapperToReleaseDTO(applicationReleaseWrapper), applicationArtifact, true); return addImageArtifacts(applicationReleaseDTO, applicationArtifact); } catch (ResourceManagementException e) { @@ -861,7 +1041,7 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new ForbiddenException(msg); } - return appDtoToAppResponse(applicationDTO); + return APIUtil.appDtoToAppResponse(applicationDTO); } catch (LifecycleManagementException e){ String msg = "Error occurred when getting the last state of the application lifecycle flow"; log.error(msg); @@ -911,7 +1091,7 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new ForbiddenException(msg); } - return releaseDtoToRelease(applicationReleaseDTO); + return APIUtil.releaseDtoToRelease(applicationReleaseDTO); } catch (LifecycleManagementException e) { String msg = "Error occurred when getting the end state of the application lifecycle flow"; log.error(msg); @@ -977,7 +1157,7 @@ public class ApplicationManagerImpl implements ApplicationManager { log.error(msg); throw new ForbiddenException(msg); } - return appDtoToAppResponse(applicationDTO); + return APIUtil.appDtoToAppResponse(applicationDTO); } catch (LifecycleManagementException e) { String msg = "Error occurred when getting the last state of the application lifecycle flow"; log.error(msg); @@ -1542,7 +1722,7 @@ public class ApplicationManagerImpl implements ApplicationManager { } this.lifecycleStateDAO.addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); ConnectionManagerUtil.commitDBTransaction(); - return releaseDtoToRelease(applicationReleaseDTO); + return APIUtil.releaseDtoToRelease(applicationReleaseDTO); } else { String msg = "Invalid lifecycle state transition from '" + applicationReleaseDTO.getCurrentState() + "'" + " to '" + lifecycleChanger.getAction() + "'"; @@ -2267,78 +2447,188 @@ public class ApplicationManagerImpl implements ApplicationManager { @Override - public void validateAppCreatingRequest(ApplicationWrapper applicationWrapper) throws RequestValidatingException { + public void validateAppCreatingRequest(T param) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); - String applicationType = applicationWrapper.getType(); + if (param instanceof ApplicationWrapper){ + ApplicationWrapper applicationWrapper = (ApplicationWrapper) param; + if (StringUtils.isEmpty(applicationWrapper.getName())) { + String msg = "Application name cannot be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (applicationWrapper.getAppCategories() == null) { + String msg = "Application category can't be null."; + log.error(msg); + throw new BadRequestException(msg); + } + if (applicationWrapper.getAppCategories().isEmpty()) { + String msg = "Application category can't be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(applicationWrapper.getType())) { + String msg = "Application type can't be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (StringUtils.isEmpty(applicationWrapper.getDeviceType())) { + String msg = "Device type can't be empty for the application."; + log.error(msg); + throw new BadRequestException(msg); + } - if (StringUtils.isEmpty(applicationWrapper.getName())) { - String msg = "Application name cannot be empty."; - log.error(msg); - throw new RequestValidatingException(msg); - } - if (applicationWrapper.getAppCategories() == null) { - String msg = "Application category can't be null."; - log.error(msg); - throw new RequestValidatingException(msg); - } - if (applicationWrapper.getAppCategories().isEmpty()) { - String msg = "Application category can't be empty."; - log.error(msg); - throw new RequestValidatingException(msg); - } - if (StringUtils.isEmpty(applicationType)) { - String msg = "Application type can't be empty."; - log.error(msg); - throw new RequestValidatingException(msg); - } - if (StringUtils.isEmpty(applicationWrapper.getDeviceType())) { - String msg = "Device type can't be empty for the application."; - log.error(msg); - throw new RequestValidatingException(msg); - } + List applicationReleaseWrappers; + applicationReleaseWrappers = applicationWrapper.getApplicationReleaseWrappers(); - List applicationReleaseWrappers; - applicationReleaseWrappers = applicationWrapper.getApplicationReleaseWrappers(); + if (applicationReleaseWrappers == null || applicationReleaseWrappers.size() != 1) { + String msg = "Invalid application creating request. Application creating request must have single " + + "application release. Application name:" + applicationWrapper.getName() + " and type: " + + applicationWrapper.getType(); + log.error(msg); + throw new BadRequestException(msg); + } + } else if (param instanceof WebClipWrapper) { + WebClipWrapper webClipWrapper = (WebClipWrapper) param; + if (StringUtils.isEmpty(webClipWrapper.getName())) { + String msg = "Web Clip name cannot be empty."; + log.error(msg); + throw new BadRequestException(msg); + } + if (webClipWrapper.getCategories() == null) { + String msg = "Web Clip category can't be null."; + log.error(msg); + throw new BadRequestException(msg); + } + if (webClipWrapper.getCategories().isEmpty()) { + String msg = "Web clip category can't be empty."; + log.error(msg); + throw new BadRequestException(msg); + } - if (applicationReleaseWrappers == null || applicationReleaseWrappers.size() != 1) { - String msg = - "Invalid application creating request. ApplicationDTO creating request must have single application " - + "release. ApplicationDTO name:" + applicationWrapper.getName() + " and type: " + applicationWrapper - .getType(); - log.error(msg); - throw new RequestValidatingException(msg); + List webClipReleaseWrappers; + webClipReleaseWrappers = webClipWrapper.getWebClipReleaseWrappers(); + + if (webClipReleaseWrappers == null || webClipReleaseWrappers.size() != 1) { + String msg = "Invalid web clip creating request. Web clip creating request must have single " + + "web clip release. Web clip name:" + webClipWrapper.getName() + "."; + log.error(msg); + throw new BadRequestException(msg); + } + + try { + ConnectionManagerUtil.openDBConnection(); + List unrestrictedRoles = webClipWrapper.getUnrestrictedRoles(); + + if (unrestrictedRoles != null && !unrestrictedRoles.isEmpty()) { + if (!isValidRestrictedRole(unrestrictedRoles)) { + String msg = "Unrestricted role list contain role/roles which are not in the user store."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + if (!hasUserRole(unrestrictedRoles, userName)) { + String msg = "You are trying to restrict the visibility of the application for a role set, but " + + "in order to perform the action at least one role should be assigned to user: " + + userName; + log.error(msg); + throw new BadRequestException(msg); + } + } + + Filter filter = new Filter(); + filter.setFullMatch(true); + filter.setAppName(webClipWrapper.getName().trim()); + filter.setOffset(0); + filter.setLimit(1); + List applicationList = applicationDAO.getApplications(filter, -1, tenantId); + if (!applicationList.isEmpty()) { + String msg = + "Already an application registered with same name - " + applicationList.get(0).getName() + + "."; + log.error(msg); + throw new BadRequestException(msg); + } + + List registeredCategories = this.applicationDAO.getAllCategories(tenantId); + List appCategories = webClipWrapper.getCategories(); + + if (registeredCategories.isEmpty()) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "Registered application category set is empty. Since it is mandatory to add application " + + "category when adding new application, registered application category list shouldn't be null."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + for (String cat : appCategories) { + boolean isValidCategory = false; + for (CategoryDTO obj : registeredCategories) { + if (cat.equals(obj.getCategoryName())) { + isValidCategory = true; + break; + } + } + if (!isValidCategory) { + String msg = + "Application Creating request contains invalid categories. Hence please verify the " + + "application creating payload."; + log.error(msg); + throw new BadRequestException(msg); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while getting data which is related to web clip. web clip name: " + + webClipWrapper.getName() + "."; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } catch (UserStoreException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred when validating the unrestricted roles given for the web clip"; + log.error(msg); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } } } @Override - public void validateReleaseCreatingRequest(ApplicationReleaseWrapper applicationReleaseWrapper, - String applicationType) throws RequestValidatingException { + public void validateReleaseCreatingRequest(T param) throws ApplicationManagementException { - if (applicationReleaseWrapper == null){ - String msg = "Application Release shouldn't be null."; + if (param == null){ + String msg = "In order to validate release creating request param shouldn't be null."; log.error(msg); - throw new RequestValidatingException(msg); + throw new BadRequestException(msg); } - if (ApplicationType.WEB_CLIP.toString().equals(applicationType)) { + if (param instanceof ApplicationReleaseWrapper){ + ApplicationReleaseWrapper applicationReleaseWrapper = (ApplicationReleaseWrapper) param; + + if (StringUtils.isEmpty(applicationReleaseWrapper.getSupportedOsVersions())){ + String msg = "Supported OS Version shouldn't be null or empty."; + log.error(msg); + throw new BadRequestException(msg); + } + } if (param instanceof WebClipReleaseWrapper){ + WebClipReleaseWrapper webClipReleaseWrapper = (WebClipReleaseWrapper) param; UrlValidator urlValidator = new UrlValidator(); if (StringUtils - .isEmpty(applicationReleaseWrapper.getUrl())){ + .isEmpty(webClipReleaseWrapper.getUrl())){ String msg = "URL should't be null for the application release creating request for application type WEB_CLIP"; log.error(msg); - throw new RequestValidatingException(msg); + throw new BadRequestException(msg); } - if (!urlValidator.isValid(applicationReleaseWrapper.getUrl())){ + if (!urlValidator.isValid(webClipReleaseWrapper.getUrl())){ String msg = "Request payload contains an invalid Web Clip URL."; log.error(msg); - throw new RequestValidatingException(msg); + throw new BadRequestException(msg); } } - if (StringUtils.isEmpty(applicationReleaseWrapper.getSupportedOsVersions())){ - String msg = "Supported OS Version shouldn't be null or empty."; - log.error(msg); - throw new RequestValidatingException(msg); - } } @@ -2383,98 +2673,6 @@ public class ApplicationManagerImpl implements ApplicationManager { } } - - private ApplicationDTO appWrapperToAppDTO(ApplicationWrapper applicationWrapper) - throws BadRequestException, UnexpectedServerErrorException { - - DeviceType deviceType = getDeviceTypeData(applicationWrapper.getDeviceType()); - ApplicationDTO applicationDTO = new ApplicationDTO(); - applicationDTO.setName(applicationWrapper.getName()); - applicationDTO.setDescription(applicationWrapper.getDescription()); - applicationDTO.setAppCategories(applicationWrapper.getAppCategories()); - applicationDTO.setType(applicationWrapper.getType()); - applicationDTO.setSubType(applicationWrapper.getSubType()); - applicationDTO.setPaymentCurrency(applicationWrapper.getPaymentCurrency()); - applicationDTO.setTags(applicationWrapper.getTags()); - applicationDTO.setUnrestrictedRoles(applicationWrapper.getUnrestrictedRoles()); - applicationDTO.setDeviceTypeId(deviceType.getId()); - List applicationReleaseEntities = applicationWrapper.getApplicationReleaseWrappers() - .stream().map(this::releaseWrapperToReleaseDTO).collect(Collectors.toList()); - applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); - return applicationDTO; - } - - private ApplicationReleaseDTO releaseWrapperToReleaseDTO(ApplicationReleaseWrapper applicationReleaseWrapper){ - ApplicationReleaseDTO applicationReleaseDTO = new ApplicationReleaseDTO(); - applicationReleaseDTO.setDescription(applicationReleaseWrapper.getDescription()); - applicationReleaseDTO.setReleaseType(applicationReleaseWrapper.getReleaseType()); - applicationReleaseDTO.setPrice(applicationReleaseWrapper.getPrice()); - applicationReleaseDTO.setIsSharedWithAllTenants(applicationReleaseWrapper.getIsSharedWithAllTenants()); - applicationReleaseDTO.setMetaData(applicationReleaseWrapper.getMetaData()); - applicationReleaseDTO.setUrl(applicationReleaseWrapper.getUrl()); - applicationReleaseDTO.setSupportedOsVersions(applicationReleaseWrapper.getSupportedOsVersions()); - return applicationReleaseDTO; - } - - private Application appDtoToAppResponse(ApplicationDTO applicationDTO) - throws BadRequestException, UnexpectedServerErrorException { - - Application application = new Application(); - DeviceType deviceType = getDeviceTypeData(applicationDTO.getDeviceTypeId()); - application.setId(applicationDTO.getId()); - application.setName(applicationDTO.getName()); - application.setDescription(applicationDTO.getDescription()); - application.setAppCategories(applicationDTO.getAppCategories()); - application.setType(applicationDTO.getType()); - application.setSubType(applicationDTO.getSubType()); - application.setPaymentCurrency(applicationDTO.getPaymentCurrency()); - application.setTags(applicationDTO.getTags()); - application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles()); - application.setDeviceType(deviceType.getName()); - application.setRating(applicationDTO.getAppRating()); - List applicationReleases = applicationDTO.getApplicationReleaseDTOs() - .stream().map(this::releaseDtoToRelease).collect(Collectors.toList()); - application.setApplicationReleases(applicationReleases); - return application; - } - - private ApplicationRelease releaseDtoToRelease(ApplicationReleaseDTO applicationReleaseDTO){ - String artifactDownloadEndpoint = ConfigurationManager.getInstance().getConfiguration() - .getArtifactDownloadEndpoint(); - String basePath = artifactDownloadEndpoint + Constants.FORWARD_SLASH + applicationReleaseDTO.getUuid() - + Constants.FORWARD_SLASH; - List screenshotPaths = new ArrayList<>(); - ApplicationRelease applicationRelease = new ApplicationRelease(); - applicationRelease.setDescription(applicationReleaseDTO.getDescription()); - applicationRelease.setVersion(applicationReleaseDTO.getVersion()); - applicationRelease.setUuid(applicationReleaseDTO.getUuid()); - applicationRelease.setReleaseType(applicationReleaseDTO.getReleaseType()); - applicationRelease.setPrice(applicationReleaseDTO.getPrice()); - applicationRelease.setIsSharedWithAllTenants(applicationReleaseDTO.getIsSharedWithAllTenants()); - applicationRelease.setMetaData(applicationReleaseDTO.getMetaData()); - applicationRelease.setUrl(applicationReleaseDTO.getUrl()); - applicationRelease.setCurrentStatus(applicationReleaseDTO.getCurrentState()); - applicationRelease.setIsSharedWithAllTenants(applicationReleaseDTO.getIsSharedWithAllTenants()); - applicationRelease.setSupportedOsVersions(applicationReleaseDTO.getSupportedOsVersions()); - applicationRelease.setRating(applicationReleaseDTO.getRating()); - applicationRelease - .setInstallerPath(basePath + applicationReleaseDTO.getInstallerName()); - applicationRelease.setIconPath(basePath + applicationReleaseDTO.getIconName()); - applicationRelease.setBannerPath(basePath + applicationReleaseDTO.getBannerName()); - - if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName1())) { - screenshotPaths.add(basePath + applicationReleaseDTO.getScreenshotName1()); - } - if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName2())) { - screenshotPaths.add(basePath + applicationReleaseDTO.getScreenshotName2()); - } - if (!StringUtils.isEmpty(applicationReleaseDTO.getScreenshotName3())) { - screenshotPaths.add(basePath + applicationReleaseDTO.getScreenshotName3()); - } - applicationRelease.setScreenshots(screenshotPaths); - return applicationRelease; - } - private DeviceType getDeviceTypeData( T deviceTypeAttr) throws BadRequestException, UnexpectedServerErrorException { List deviceTypes; 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 a16dca83579..47f95cf0e63 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 @@ -28,6 +28,10 @@ import org.wso2.carbon.device.application.mgt.common.response.Application; import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease; import org.wso2.carbon.device.application.mgt.common.services.*; import org.wso2.carbon.device.application.mgt.common.ErrorResponse; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebClipReleaseWrapper; +import org.wso2.carbon.device.application.mgt.common.wrapper.WebClipWrapper; import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; @@ -212,6 +216,64 @@ public class APIUtil { } } + public static ApplicationDTO convertToAppDTO(T param) + throws BadRequestException, UnexpectedServerErrorException { + ApplicationDTO applicationDTO = new ApplicationDTO(); + + if (param instanceof ApplicationWrapper){ + ApplicationWrapper applicationWrapper = (ApplicationWrapper) param; + DeviceType deviceType = getDeviceTypeData(applicationWrapper.getDeviceType()); + applicationDTO.setName(applicationWrapper.getName()); + applicationDTO.setDescription(applicationWrapper.getDescription()); + applicationDTO.setAppCategories(applicationWrapper.getAppCategories()); + applicationDTO.setType(applicationWrapper.getType()); + applicationDTO.setSubType(applicationWrapper.getSubType()); + applicationDTO.setPaymentCurrency(applicationWrapper.getPaymentCurrency()); + applicationDTO.setTags(applicationWrapper.getTags()); + applicationDTO.setUnrestrictedRoles(applicationWrapper.getUnrestrictedRoles()); + applicationDTO.setDeviceTypeId(deviceType.getId()); + List applicationReleaseEntities = applicationWrapper.getApplicationReleaseWrappers() + .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); + applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); + } else if (param instanceof WebClipWrapper){ + WebClipWrapper webClipWrapper = (WebClipWrapper) param; + applicationDTO.setName(webClipWrapper.getName()); + applicationDTO.setDescription(webClipWrapper.getDescription()); + applicationDTO.setAppCategories(webClipWrapper.getCategories()); + applicationDTO.setSubType(webClipWrapper.getSubMethod()); + applicationDTO.setPaymentCurrency(webClipWrapper.getPaymentCurrency()); + applicationDTO.setTags(webClipWrapper.getTags()); + applicationDTO.setUnrestrictedRoles(webClipWrapper.getUnrestrictedRoles()); + List applicationReleaseEntities = webClipWrapper.getWebClipReleaseWrappers() + .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); + applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); + } + + return applicationDTO; + } + + public static ApplicationReleaseDTO releaseWrapperToReleaseDTO(T param){ + ApplicationReleaseDTO applicationReleaseDTO = new ApplicationReleaseDTO(); + if (param instanceof ApplicationReleaseWrapper){ + ApplicationReleaseWrapper applicationReleaseWrapper = (ApplicationReleaseWrapper) param; + applicationReleaseDTO.setDescription(applicationReleaseWrapper.getDescription()); + applicationReleaseDTO.setReleaseType(applicationReleaseWrapper.getReleaseType()); + applicationReleaseDTO.setPrice(applicationReleaseWrapper.getPrice()); + applicationReleaseDTO.setIsSharedWithAllTenants(applicationReleaseWrapper.getIsSharedWithAllTenants()); + applicationReleaseDTO.setMetaData(applicationReleaseWrapper.getMetaData()); + applicationReleaseDTO.setSupportedOsVersions(applicationReleaseWrapper.getSupportedOsVersions()); + } else if (param instanceof WebClipReleaseWrapper){ + WebClipReleaseWrapper webClipReleaseWrapper = (WebClipReleaseWrapper) param; + applicationReleaseDTO.setDescription(webClipReleaseWrapper.getDescription()); + applicationReleaseDTO.setReleaseType(webClipReleaseWrapper.getReleaseType()); + applicationReleaseDTO.setPrice(webClipReleaseWrapper.getPrice()); + applicationReleaseDTO.setInstallerName(webClipReleaseWrapper.getUrl()); + applicationReleaseDTO.setIsSharedWithAllTenants(webClipReleaseWrapper.getIsSharedWithAllTenants()); + applicationReleaseDTO.setMetaData(webClipReleaseWrapper.getMetaData()); + } + return applicationReleaseDTO; + } + public static Application appDtoToAppResponse(ApplicationDTO applicationDTO) throws BadRequestException, UnexpectedServerErrorException { 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 19323962e16..2aef9d23af5 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,6 +42,7 @@ import org.wso2.carbon.device.application.mgt.common.response.ApplicationRelease import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper; 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.WebClipWrapper; import java.util.List; import javax.validation.Valid; @@ -337,6 +338,71 @@ public interface ApplicationManagementPublisherAPI { @Multipart(value = "screenshot3") Attachment screenshot3 ); + @POST + @Path("/web-app") + @Produces(MediaType.APPLICATION_JSON) + @Consumes("multipart/mixed") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an web app", + notes = "This will create a new web app", + tags = "Application Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created a web application.", + response = ApplicationDTO.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "Web app creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the web app.", + response = ErrorResponse.class) + }) + Response createWebApp( + @ApiParam( + name = "webapp", + value = "The web app that need to be created.", + required = true) + @Multipart("webapp") WebClipWrapper webClipWrapper, + @ApiParam( + name = "icon", + value = "Icon of the uploading web app", + required = true) + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading web app", + required = true) + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading web app", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading web app", + required = false) + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading web app", + required = false) + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + @POST @Produces(MediaType.APPLICATION_JSON) @Consumes("multipart/mixed") 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 9d53177a031..d2e696944e3 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,6 +32,7 @@ import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; import org.wso2.carbon.device.application.mgt.common.wrapper.ApplicationReleaseWrapper; 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.WebClipWrapper; import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErrorException; @@ -179,8 +180,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); try { applicationManager.validateAppCreatingRequest(applicationWrapper); - applicationManager.validateReleaseCreatingRequest(applicationWrapper.getApplicationReleaseWrappers().get(0), - applicationWrapper.getType()); + applicationManager.validateReleaseCreatingRequest(applicationWrapper.getApplicationReleaseWrappers().get(0)); applicationManager.validateBinaryArtifact(binaryFile, applicationWrapper.getType()); applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); @@ -205,6 +205,44 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem } } + @POST + @Consumes("multipart/mixed") + @Path("/web-app") + public Response createWebApp( + @Multipart("webapp") WebClipWrapper webClipWrapper, + @Multipart("icon") Attachment iconFile, + @Multipart("banner") Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + try { + applicationManager.validateAppCreatingRequest(webClipWrapper); + applicationManager.validateReleaseCreatingRequest(webClipWrapper.getWebClipReleaseWrappers().get(0)); + applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); + + // Created new application entry + Application application = applicationManager.createWebClip(webClipWrapper, + constructApplicationArtifact(null, iconFile, bannerFile, attachmentList)); + if (application != null) { + return Response.status(Response.Status.CREATED).entity(application).build(); + } else { + String msg = "Web app creation is failed"; + log.error(msg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating the web application"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (RequestValidatingException e) { + String msg = "Error occurred while handling the web app creating request"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + } + @POST @Consumes("multipart/mixed") @Path("/{appType}/{appId}") @@ -221,7 +259,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem ApplicationManager applicationManager = APIUtil.getApplicationManager(); List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); try { - applicationManager.validateReleaseCreatingRequest(applicationReleaseWrapper, appType); + applicationManager.validateReleaseCreatingRequest(applicationReleaseWrapper); applicationManager.validateBinaryArtifact(binaryFile, appType); applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);