Add web clip support for APPM

feature/appm-store/pbac
lasanthaDLPDS 6 years ago
parent a87824616f
commit 0ae7479d49

@ -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;
<T> 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;
<T> void validateReleaseCreatingRequest(T param) throws ApplicationManagementException;
/***
*

@ -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; }

@ -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; }
}

@ -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<String> 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<String> tags;
@ApiModelProperty(name = "unrestrictedRoles",
value = "List of roles that users should have to view the web clip")
private List<String> unrestrictedRoles;
@ApiModelProperty(name = "applicationReleaseWrappers",
value = "List of web clip releases",
required = true)
private List<WebClipReleaseWrapper> webClipReleaseWrappers;
public String getName() {
return name;
}
public void setName(String name) { this.name = name; }
public List<String> getTags() { return tags; }
public void setTags(List<String> tags) { this.tags = tags; }
public String getPaymentCurrency() { return paymentCurrency; }
public void setPaymentCurrency(String paymentCurrency) { this.paymentCurrency = paymentCurrency; }
public List<String> getUnrestrictedRoles() { return unrestrictedRoles; }
public void setUnrestrictedRoles(List<String> unrestrictedRoles) { this.unrestrictedRoles = unrestrictedRoles; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public List<WebClipReleaseWrapper> getWebClipReleaseWrappers() { return webClipReleaseWrappers; }
public void setWebClipReleaseWrappers(List<WebClipReleaseWrapper> webClipReleaseWrappers) {
this.webClipReleaseWrappers = webClipReleaseWrappers; }
public List<String> getCategories() { return categories; }
public void setCategories(List<String> categories) { this.categories = categories; }
public String getSubMethod() { return subMethod; }
public void setSubMethod(String subMethod) { this.subMethod = subMethod; }
}

@ -83,6 +83,9 @@ public interface ApplicationDAO {
List<CategoryDTO> getAllCategories(int tenantId) throws ApplicationManagementDAOException;
List<Integer> getCategoryIdsForCategoryNames(List<String> CatgeoryNames, int tenantId)
throws ApplicationManagementDAOException;
List<Integer> getDistinctCategoryIdsInCategoryMapping() throws ApplicationManagementDAOException;
CategoryDTO getCategoryForCategoryName(String categoryName, int tenantId) throws ApplicationManagementDAOException;

@ -805,6 +805,40 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
}
}
@Override
public List<Integer> getCategoryIdsForCategoryNames(List<String> 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<Integer> 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<Integer> getDistinctCategoryIdsInCategoryMapping() throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {

@ -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<Integer> categoryIds;
ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(webClipWrapper);
List<String> unrestrictedRoles = applicationDTO.getUnrestrictedRoles();
List<String> tags = applicationDTO.getTags();
List<String> 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<ApplicationReleaseDTO> 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<TagDTO> registeredTags = applicationDAO.getAllTags(tenantId);
List<String> registeredTagNames = new ArrayList<>();
List<Integer> tagIds = new ArrayList<>();
for (TagDTO tagDTO : registeredTags) {
registeredTagNames.add(tagDTO.getTagName());
}
List<String> 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,77 +2447,187 @@ public class ApplicationManagerImpl implements ApplicationManager {
@Override
public void validateAppCreatingRequest(ApplicationWrapper applicationWrapper) throws RequestValidatingException {
String applicationType = applicationWrapper.getType();
public <T> void validateAppCreatingRequest(T param) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
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 RequestValidatingException(msg);
throw new BadRequestException(msg);
}
if (applicationWrapper.getAppCategories() == null) {
String msg = "Application category can't be null.";
log.error(msg);
throw new RequestValidatingException(msg);
throw new BadRequestException(msg);
}
if (applicationWrapper.getAppCategories().isEmpty()) {
String msg = "Application category can't be empty.";
log.error(msg);
throw new RequestValidatingException(msg);
throw new BadRequestException(msg);
}
if (StringUtils.isEmpty(applicationType)) {
if (StringUtils.isEmpty(applicationWrapper.getType())) {
String msg = "Application type can't be empty.";
log.error(msg);
throw new RequestValidatingException(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 RequestValidatingException(msg);
throw new BadRequestException(msg);
}
List<ApplicationReleaseWrapper> 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);
}
List<WebClipReleaseWrapper> 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<String> 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<ApplicationDTO> applicationList = applicationDAO.getApplications(filter, -1, tenantId);
if (!applicationList.isEmpty()) {
String msg =
"Invalid application creating request. ApplicationDTO creating request must have single application "
+ "release. ApplicationDTO name:" + applicationWrapper.getName() + " and type: " + applicationWrapper
.getType();
"Already an application registered with same name - " + applicationList.get(0).getName()
+ ".";
log.error(msg);
throw new RequestValidatingException(msg);
throw new BadRequestException(msg);
}
List<CategoryDTO> registeredCategories = this.applicationDAO.getAllCategories(tenantId);
List<String> 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 <T> 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<ApplicationReleaseDTO> 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<ApplicationRelease> 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<String> 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 <T> DeviceType getDeviceTypeData( T deviceTypeAttr)
throws BadRequestException, UnexpectedServerErrorException {
List<DeviceType> deviceTypes;

@ -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 <T> 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<ApplicationReleaseDTO> 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<ApplicationReleaseDTO> applicationReleaseEntities = webClipWrapper.getWebClipReleaseWrappers()
.stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList());
applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities);
}
return applicationDTO;
}
public static <T> 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 {

@ -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")

@ -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<Attachment> 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<Attachment> 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<Attachment> attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3);
try {
applicationManager.validateReleaseCreatingRequest(applicationReleaseWrapper, appType);
applicationManager.validateReleaseCreatingRequest(applicationReleaseWrapper);
applicationManager.validateBinaryArtifact(binaryFile, appType);
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);

Loading…
Cancel
Save