Merge branch 'application-mgt-new' of https://gitlab.com/tcdlpds/carbon-device-mgt into application-mgt-new

feature/appm-store/pbac
Jayasanka 5 years ago
commit ccc7021d1e

@ -68,7 +68,7 @@ public interface ApplicationManager {
* @param applicationId ID for tha application
* @throws ApplicationManagementException ApplicationDTO Management Exception
*/
List<String> deleteApplication(int applicationId) throws ApplicationManagementException;
void deleteApplication(int applicationId) throws ApplicationManagementException;
/**
* Delete an application identified by the unique ID.

@ -197,7 +197,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
if (!StringUtils.isEmpty(filter.getAppReleaseState())) {
sql += " AND AP_APP_RELEASE.CURRENT_STATE = ?";
}
if (deviceTypeId > 0) {
if (deviceTypeId != -1) {
sql += " AND AP_APP.DEVICE_TYPE_ID = ?";
}

@ -1,20 +1,18 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* WSO2 Inc. 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
* 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.
* 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.core.exception;

@ -0,0 +1,33 @@
/* 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.core.exception;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
/**
* Exception thrown during the ApplicationDTO Management DAO operations.
*/
public class SubscriptionManagementDAOException extends ApplicationManagementException {
public SubscriptionManagementDAOException(String message, Throwable throwable) {
super(message, throwable);
}
public SubscriptionManagementDAOException(String message) {
super(message, new Exception());
}
}

@ -87,6 +87,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@ -135,79 +136,126 @@ public class ApplicationManagerImpl implements ApplicationManager {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
ApplicationDTO applicationDTO;
Application application;
if (log.isDebugEnabled()) {
log.debug("Application create request is received for the tenant : " + tenantId + " From" + " the user : "
+ userName);
}
try {
applicationDTO = appWrapperToAppDTO(applicationWrapper);
ApplicationReleaseDTO initialApplicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0);
applicationDTO.getApplicationReleaseDTOs().clear();
ApplicationReleaseDTO applicationReleaseDTO = addApplicationReleaseArtifacts(applicationDTO.getType(),
applicationWrapper.getDeviceType(), initialApplicationReleaseDTO, applicationArtifact, false);
applicationDTO.getApplicationReleaseDTOs().add(addImageArtifacts(applicationReleaseDTO, applicationArtifact));
} catch (UnexpectedServerErrorException e) {
String msg = "Error occurred when getting Device Type data.";
log.error(msg);
throw new ApplicationManagementException(msg, e);
} catch (ResourceManagementException e) {
String msg = "Error Occured when uploading artifacts of the application: " + applicationWrapper.getName();
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
ApplicationDTO applicationDTO;
List<String> unrestrictedRoles;
Optional<CategoryDTO> category;
List<String> tags;
//validating and verifying application data
try {
List<ApplicationReleaseDTO> applicationReleaseEntities = new ArrayList<>();
ApplicationReleaseDTO applicationReleaseDTO;
ConnectionManagerUtil.openDBConnection();
applicationDTO = appWrapperToAppDTO(applicationWrapper);
unrestrictedRoles = applicationWrapper.getUnrestrictedRoles();
tags = applicationWrapper.getTags();
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(applicationDTO.getName().trim());
filter.setOffset(0);
filter.setLimit(1);
ConnectionManagerUtil.beginDBTransaction();
List<ApplicationDTO> applicationList = applicationDAO
.getApplications(filter, applicationDTO.getDeviceTypeId(), tenantId);
if (!applicationList.isEmpty()) {
String msg =
"Already an application registered with same name - " + applicationList.get(0)
.getName();
String msg = "Already an application registered with same name - " + applicationList.get(0).getName()
+ " for the device type " + applicationWrapper.getDeviceType();
log.error(msg);
throw new RequestValidatingException(msg);
}
List<CategoryDTO> registeredCategories = this.applicationDAO.getAllCategories(tenantId);
String categoryName = applicationWrapper.getAppCategory();
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);
}
category = registeredCategories.stream().filter(obj -> obj.getCategoryName().equals(categoryName))
.findAny();
if (!category.isPresent()) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Request contains invalid category: " + categoryName;
log.error(msg);
throw new ApplicationManagementException(msg);
}
} catch (DBConnectionException e) {
String msg = "Error occurred while getting database connection.";
log.error(msg);
throw new ApplicationManagementException(msg, e);
} catch (UnexpectedServerErrorException e) {
String msg = "Error occurred when getting Device Type data.";
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: "
+ applicationWrapper.getName() + " and application type: " + applicationWrapper.getType();
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 application";
log.error(msg);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
//uploading application artifacts
try {
ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0);
applicationReleaseDTO = addApplicationReleaseArtifacts(applicationDTO.getType(),
applicationWrapper.getDeviceType(), applicationReleaseDTO, applicationArtifact, false);
applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact);
applicationDTO.getApplicationReleaseDTOs().clear();
applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO);
} catch (ResourceManagementException e) {
String msg = "Error Occured when uploading artifacts of the application: " + applicationWrapper.getName();
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
//insert application data into databse
ApplicationStorageManager applicationStorageManager = Util.getApplicationStorageManager();
ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0);
try {
List<ApplicationReleaseDTO> applicationReleaseEntities = new ArrayList<>();
ConnectionManagerUtil.beginDBTransaction();
// Insert to application table
int appId = this.applicationDAO.createApplication(applicationDTO, tenantId);
if (appId == -1) {
log.error("ApplicationDTO creation is Failed");
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);
}
//adding application unrestricted roles
List<String> unrestrictedRoles = applicationWrapper.getUnrestrictedRoles();
if (!unrestrictedRoles.isEmpty()) {
if (!isValidRestrictedRole(unrestrictedRoles)) {
ConnectionManagerUtil.rollbackDBTransaction();
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)){
ConnectionManagerUtil.rollbackDBTransaction();
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);
}
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."
@ -215,25 +263,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
List<CategoryDTO> registeredCategories = this.applicationDAO.getAllCategories(tenantId);
String categoryName = applicationWrapper.getAppCategory();
Optional<CategoryDTO> category = registeredCategories.stream()
.filter(obj -> obj.getCategoryName().equals(categoryName)).findAny();
if (registeredCategories.isEmpty()) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Registered application category set is empty category: " + categoryName;
log.error(msg);
throw new ApplicationManagementException(msg);
}
if (!category.isPresent()){
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Request contains invalid category: " + categoryName;
log.error(msg);
throw new ApplicationManagementException(msg);
}
/*
In current flow, allow to add one category for an application. If it is required to add multiple
categories DAO layer is implemented to match with that requirement. Hence logic is also implemented
@ -241,11 +270,10 @@ public class ApplicationManagerImpl implements ApplicationManager {
*/
List<Integer> categoryIds = new ArrayList<>();
categoryIds.add(category.get().getId());
this.applicationDAO.addCategoryMapping(categoryIds,appId,tenantId);
this.applicationDAO.addCategoryMapping(categoryIds, appId, tenantId);
//adding application tags
List<String> tags = applicationWrapper.getTags();
if (!tags.isEmpty()) {
if (tags != null && !tags.isEmpty()) {
List<TagDTO> registeredTags = applicationDAO.getAllTags(tenantId);
List<String> registeredTagNames = new ArrayList<>();
List<Integer> tagIds = new ArrayList<>();
@ -277,61 +305,84 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.debug("Creating a new release. App Id:" + appId);
}
String initialLifecycleState = lifecycleStateManager.getInitialState();
applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0);
applicationReleaseDTO.setCurrentState(initialLifecycleState);
applicationReleaseDTO = this.applicationReleaseDAO.createRelease(applicationReleaseDTO, appId, tenantId);
applicationReleaseDTO = this.applicationReleaseDAO
.createRelease(applicationReleaseDTO, appId, tenantId);
LifecycleStateDTO lifecycleStateDTO = getLifecycleStateInstance(initialLifecycleState,
initialLifecycleState);
this.lifecycleStateDAO
.addLifecycleState(lifecycleStateDTO, appId, applicationReleaseDTO.getUuid(), tenantId);
applicationReleaseEntities.add(applicationReleaseDTO);
applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities);
application = appDtoToAppResponse(applicationDTO);
Application application = appDtoToAppResponse(applicationDTO);
ConnectionManagerUtil.commitDBTransaction();
return application;
}
return application;
} catch (LifeCycleManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while adding lifecycle state. application name: " + applicationWrapper.getName()
+ " application type: is " + applicationWrapper.getType();
String msg =
"Error occurred while adding lifecycle state. application name: " + applicationWrapper.getName()
+ " application type: is " + applicationWrapper.getType();
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: "
+ applicationWrapper.getName() + " application type: " + applicationWrapper.getType();
log.error(msg);
deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()));
throw new ApplicationManagementException(msg, e);
} catch(LifecycleManagementException e){
} catch (LifecycleManagementException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred when getting initial lifecycle state. application name: " + applicationWrapper
.getName() + " application type: is " + applicationWrapper.getType();
log.error(msg);
deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()));
throw new ApplicationManagementException(msg, e);
}catch (DBConnectionException 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: " + applicationWrapper.getName()
+ " application type: " + applicationWrapper.getType();
String msg =
"Error occurred while adding unrestricted roles. application name: " + applicationWrapper.getName()
+ " application type: " + applicationWrapper.getType();
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);
} catch (UserStoreException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred when validating the unrestricted roles given for the application";
log.error(msg);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
private void deleteApplicationArtifacts(List<String> directoryPaths) throws ApplicationManagementException {
ApplicationStorageManager applicationStorageManager = Util.getApplicationStorageManager();
try {
applicationStorageManager.deleteAllApplicationReleaseArtifacts(directoryPaths);
} catch (ApplicationStorageManagementException e) {
String errorLog = "Error occurred when deleting application artifacts. directory paths: ." + directoryPaths
.toString();
log.error(errorLog);
throw new ApplicationManagementException(errorLog, e);
}
}
private ApplicationReleaseDTO addApplicationReleaseArtifacts(String applicationType, String deviceType,
ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, boolean isNewRelease)
throws ResourceManagementException, ApplicationManagementException {
@ -476,8 +527,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
} catch (IOException e) {
String msg =
"Error occurred when getting byte array of binary file. Installer name: " + applicationArtifact
@ -578,9 +627,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
try {
//set default values
if (StringUtils.isEmpty(filter.getSortBy())) {
filter.setSortBy("ASC");
}
if (filter.getLimit() == 0) {
filter.setLimit(20);
}
@ -588,59 +634,54 @@ public class ApplicationManagerImpl implements ApplicationManager {
if (!StringUtils.isEmpty(deviceTypename)) {
deviceType = getDeviceTypeData(deviceTypename);
}
ConnectionManagerUtil.openDBConnection();
validateFilter(filter);
if (deviceType == null) {
appDTOs = applicationDAO.getApplications(filter, 0, tenantId);
} else {
appDTOs = applicationDAO.getApplications(filter, deviceType.getId(), tenantId);
deviceType = new DeviceType();
deviceType.setId(-1);
}
for (ApplicationDTO app : appDTOs) {
ConnectionManagerUtil.openDBConnection();
validateFilter(filter);
appDTOs = applicationDAO.getApplications(filter, deviceType.getId(), tenantId);
//todo as a performance improvement get these data from DB. Consider where in clause.
for (ApplicationDTO applicationDTO : appDTOs) {
boolean isSearchingApp = true;
List<String> filteringTags = filter.getTags();
List<String> filteringCategories = filter.getAppCategories();
List<String> filteringUnrestrictedRoles = filter.getUnrestrictedRoles();
if (!lifecycleStateManager.getEndState().equals(app.getStatus())) {
List<String> appUnrestrictedRoles = visibilityDAO.getUnrestrictedRoles(app.getId(), tenantId);
if (!lifecycleStateManager.getEndState().equals(applicationDTO.getStatus())) {
List<String> appUnrestrictedRoles = visibilityDAO.getUnrestrictedRoles(applicationDTO.getId(), tenantId);
if ((appUnrestrictedRoles.isEmpty() || hasUserRole(appUnrestrictedRoles, userName)) && (
filteringUnrestrictedRoles == null || filteringUnrestrictedRoles.isEmpty()
|| hasAppUnrestrictedRole(appUnrestrictedRoles, filteringUnrestrictedRoles,
userName))) {
if (filteringCategories != null && !filteringCategories.isEmpty()) {
List<String> appTagList = applicationDAO.getAppCategories(app.getId(), tenantId);
boolean isAppCategory = false;
for (String category : filteringCategories) {
if (appTagList.contains(category)) {
isAppCategory = true;
break;
}
}
List<String> appTagList = applicationDAO.getAppCategories(applicationDTO.getId(), tenantId);
boolean isAppCategory = filteringCategories.stream().anyMatch(appTagList::contains);
if (!isAppCategory) {
isSearchingApp = false;
}
}
if (filteringTags != null && !filteringTags.isEmpty()) {
List<String> appTagList = applicationDAO.getAppTags(app.getId(), tenantId);
boolean isAppTag = false;
for (String tag : filteringTags) {
if (appTagList.contains(tag)) {
isAppTag = true;
break;
}
}
List<String> appTagList = applicationDAO.getAppTags(applicationDTO.getId(), tenantId);
boolean isAppTag = filteringTags.stream().anyMatch(appTagList::contains);
if (!isAppTag) {
isSearchingApp = false;
}
}
if (isSearchingApp) {
filteredApplications.add(app);
filteredApplications.add(applicationDTO);
}
}
}
List<ApplicationReleaseDTO> filteredApplicationReleaseDTOs = new ArrayList<>();
for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) {
if (!applicationReleaseDTO.getCurrentState().equals(lifecycleStateManager.getEndState())) {
filteredApplicationReleaseDTOs.add(applicationReleaseDTO);
}
}
applicationDTO.setApplicationReleaseDTOs(filteredApplicationReleaseDTOs);
}
for(ApplicationDTO appDTO : filteredApplications){
@ -907,6 +948,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
private String[] getRoleNames() throws UserStoreException {
//todo check role by role
UserRealm userRealm = CarbonContext.getThreadLocalCarbonContext().getUserRealm();
if (userRealm != null) {
return userRealm.getUserStoreManager().getRoleNames();
@ -1045,80 +1087,52 @@ public class ApplicationManagerImpl implements ApplicationManager {
// return applicationReleases;
// }
@Override public List<String> deleteApplication(int applicationId) throws ApplicationManagementException {
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
@Override
public void deleteApplication(int applicationId) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
ApplicationStorageManager applicationStorageManager = Util.getApplicationStorageManager();
List<String> storedLocations = new ArrayList<>();
ApplicationDTO application;
ApplicationDTO applicationDTO;
if (log.isDebugEnabled()) {
log.debug("Request is received to delete applications which are related with the application id "
+ applicationId);
}
try {
ConnectionManagerUtil.beginDBTransaction();
application = this.applicationDAO.getApplicationById(applicationId, tenantId);
if (application == null) {
throw new NotFoundException("Couldn't found an application for ApplicationDTO ID: " + applicationId);
}
applicationDTO = this.applicationDAO.getApplicationById(applicationId, tenantId);
if (!isAdminUser(userName, tenantId, CarbonConstants.UI_ADMIN_PERMISSION_COLLECTION) && !application
.getUnrestrictedRoles().isEmpty() && hasUserRole(application.getUnrestrictedRoles(), userName)) {
throw new ForbiddenException(
"You don't have permission to delete this application. In order to delete an application you "
+ "need to have required permission. ApplicationDTO ID: " + applicationId);
}
List<ApplicationReleaseDTO> applicationReleases = getReleases(application, null);
if (log.isDebugEnabled()) {
log.debug("Request is received to delete applications which are related with the application id "
+ applicationId);
if (applicationDTO == null) {
throw new NotFoundException("Couldn't found an application for Application ID: " + applicationId);
}
for (ApplicationReleaseDTO applicationRelease : applicationReleases) {
LifecycleStateDTO appLifecycleState = this.lifecycleStateDAO
.getLatestLifeCycleState(applicationId, applicationRelease.getUuid());
LifecycleStateDTO newAppLifecycleState = getLifecycleStateInstance(AppLifecycleState.REMOVED.toString(),
appLifecycleState.getCurrentState());
if (lifecycleStateManager.isValidStateChange(newAppLifecycleState.getPreviousState(),
newAppLifecycleState.getCurrentState(), userName, tenantId)) {
this.lifecycleStateDAO
.addLifecycleState(newAppLifecycleState, applicationId, applicationRelease.getUuid(),
tenantId);
} else {
String currentState = appLifecycleState.getCurrentState();
List<String> lifecycleFlow = searchLifecycleStateFlow(currentState,
AppLifecycleState.REMOVED.toString());
for (String nextState : lifecycleFlow) {
LifecycleStateDTO lifecycleState = getLifecycleStateInstance(nextState, currentState);
if (lifecycleStateManager.isValidStateChange(currentState, nextState, userName, tenantId)) {
this.lifecycleStateDAO
.addLifecycleState(lifecycleState, applicationId, applicationRelease.getUuid(),
tenantId);
} else {
ConnectionManagerUtil.rollbackDBTransaction();
throw new ApplicationManagementException(
"Can't delete application release which has the UUID:" + applicationRelease
.getUuid()
+ " and its belongs to the application which has application ID:"
+ applicationId + " You have to move the lifecycle state from "
+ currentState + " to acceptable state");
}
currentState = nextState;
}
List<ApplicationReleaseDTO> applicationReleaseDTOs = applicationDTO.getApplicationReleaseDTOs();
List<ApplicationReleaseDTO> activeApplicationReleaseDTOs = new ArrayList<>();
for (ApplicationReleaseDTO applicationReleaseDTO : applicationReleaseDTOs) {
if (!applicationReleaseDTO.getCurrentState().equals(lifecycleStateManager.getEndState())){
activeApplicationReleaseDTOs.add(applicationReleaseDTO);
}
storedLocations.add(applicationRelease.getAppHashValue());
storedLocations.add(applicationReleaseDTO.getAppHashValue());
}
if (!activeApplicationReleaseDTOs.isEmpty()) {
String msg = "There are application releases which are not in the state " + lifecycleStateManager
.getEndState() + ". Hence you are not allowed to delete the application";
log.error(msg);
throw new ForbiddenException(msg);
}
this.applicationDAO.deleteApplication(applicationId);
ConnectionManagerUtil.commitDBTransaction();
} catch (UserStoreException e) {
String msg = "Error occured while check whether current user has the permission to delete an application";
applicationStorageManager.deleteAllApplicationReleaseArtifacts(storedLocations);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred when getting application data for application id: " + applicationId;
log.error(msg);
throw new ApplicationManagementException(msg, e);
} catch (LifeCycleManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occured while changing the application lifecycle state into REMOVED state.";
} catch (ApplicationStorageManagementException e) {
String msg = "Error occurred when deleting application artifacts in the file system. Application id: "
+ applicationId;
log.error(msg);
throw new ApplicationManagementException(msg, e);
throw new ApplicationManagementException(msg);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
return storedLocations;
}
private List<String> searchLifecycleStateFlow(String start, String finish) throws ApplicationManagementException {

@ -80,7 +80,7 @@ import javax.ws.rs.core.Response;
name = "Get ApplicationDTO Details",
description = "Get application details",
key = "perm:app:publisher:view",
permissions = {"/app-mgt/publisher/application/update"}
permissions = {"/app-mgt/publisher/application/view"}
),
@Scope(
name = "Update an ApplicationDTO",
@ -91,8 +91,7 @@ import javax.ws.rs.core.Response;
}
)
@Path("/applications")
@Api(value = "ApplicationDTO Management", description = "This API carries all application management related operations " +
"such as get all the applications, add application, etc.")
@Api(value = "ApplicationDTO Management")
@Produces(MediaType.APPLICATION_JSON)
public interface ApplicationManagementPublisherAPI {
@ -377,7 +376,7 @@ public interface ApplicationManagementPublisherAPI {
@DELETE
@Consumes("application/json")
@Path("/{appid}")
@Path("/{appId}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
@ -400,14 +399,21 @@ public interface ApplicationManagementPublisherAPI {
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while deleting the application.",
response = ErrorResponse.class)
response = ErrorResponse.class),
@ApiResponse(
code = 403,
message = "Don't have permission to delete the application"),
@ApiResponse(
code = 404,
message = "Application not found"),
})
//todo add new scope and permission
Response deleteApplication(
@ApiParam(
name = "UUID",
value = "Unique identifier of the ApplicationDTO",
required = true)
@PathParam("appid") int applicationId
@PathParam("appId") int applicationId
);
@PUT

@ -0,0 +1,136 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.publisher.api.services.admin;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
import org.wso2.carbon.device.application.mgt.common.ErrorResponse;
import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO;
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO;
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 javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
/**
* APIs to handle application management related tasks.
*/
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "ApplicationDTO Management Publisher Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "ApplicationManagementPublisherAdminService"),
@ExtensionProperty(name = "context", value = "/api/application-mgt-publisher/v1.0/admin/applications"),
})
}
),
tags = {
@Tag(name = "application_management, device_management", description = "App publisher related Admin APIs")
}
)
@Scopes(
scopes = {
@Scope(
name = "Delete Application Release",
description = "Delete Application Release",
key = "perm:admin:app:publisher:update",
permissions = {"/app-mgt/publisher/admin/application/update"}
)
}
)
@Path("/admin/applications")
@Api(value = "ApplicationDTO Management")
@Produces(MediaType.APPLICATION_JSON)
public interface ApplicationManagementPublisherAdminAPI {
String SCOPE = "scope";
@DELETE
@Path("/{appid}/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get all applications",
notes = "This will get all applications",
tags = "ApplicationDTO Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully delete application releaset.",
response = ApplicationList.class),
@ApiResponse(
code = 404,
message = "Not Found. There doesn't have an application release with UUID" +
"query."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while deleting application release.",
response = ErrorResponse.class)
}) Response deleteApplicationRelease(
@ApiParam(
name = "appId",
value = "application Id",
required = true)
@PathParam("appid") int applicationId,
@ApiParam(
name = "uuid",
value = "application release UUID",
required = true)
@PathParam("uuid") String releaseUuid);
}

@ -23,7 +23,6 @@ import org.apache.commons.logging.LogFactory;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import org.wso2.carbon.device.application.mgt.common.*;
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO;
import org.wso2.carbon.device.application.mgt.common.dto.LifecycleStateDTO;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException;
import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException;
@ -85,7 +84,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
return Response.status(Response.Status.OK).entity(applications).build();
} catch(BadRequestException e){
String msg = "Incompatible request payload is found. Please try with valid reuest payload.";
String msg = "Incompatible request payload is found. Please try with valid request payload.";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}catch (ApplicationManagementException e) {
@ -162,7 +161,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
if (application != null) {
return Response.status(Response.Status.CREATED).entity(application).build();
} else {
String msg = "ApplicationDTO creation is failed";
String msg = "Application creation is failed";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
@ -286,9 +285,6 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
@Multipart("binaryFile") Attachment binaryFile) {
try {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.validateBinaryArtifact(binaryFile, appType);
if (!ApplicationType.ENTERPRISE.toString().equals(appType)) {
String msg = "If ApplicationDTO type is " + appType
+ ", therefore you don't have application release artifact to update for application release UUID: "
@ -296,7 +292,8 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
ApplicationManager applicationManager = APIUtil.getApplicationManager();
applicationManager.validateBinaryArtifact(binaryFile, appType);
applicationManager.updateApplicationArtifact(deviceType, appType, applicationReleaseUuid,
constructApplicationArtifact(binaryFile, null, null, null));
return Response.status(Response.Status.OK)
@ -372,11 +369,11 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
applicationManager.validateImageArtifacts(iconFile, bannerFile, screenshots);
if (!applicationManager.updateRelease(deviceType, appType, applicationUUID, applicationReleaseWrapper,
constructApplicationArtifact(binaryFile, iconFile, bannerFile, screenshots))) {
log.error("Application release updating is failed. Please contact the administrator. "
+ "ApplicationDTO release UUID: " + applicationUUID + ", Supported device type: " + deviceType);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(applicationReleaseWrapper).build();
String msg ="Application release updating is failed. Please contact the administrator. "
+ "ApplicationDTO release UUID: " + applicationUUID + ", Supported device type: " + deviceType;
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return Response.status(Response.Status.OK).entity("Application release is successfully updated.").build();
} catch (BadRequestException e) {
String msg =
@ -404,20 +401,15 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
}
/*
//todo ----------------------
*/
@DELETE
@Path("/{appid}")
public Response deleteApplication(
@PathParam("appid") int applicationId) {
@Path("/{appId}")
public Response deleteApplication(@PathParam("appId") int applicationId) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager();
try {
List<String> storedLocations = applicationManager.deleteApplication(applicationId);
applicationStorageManager.deleteAllApplicationReleaseArtifacts(storedLocations);
String responseMsg = "Successfully deleted the application and application releases: " + applicationId;
return Response.status(Response.Status.OK).entity(responseMsg).build();
applicationManager.deleteApplication(applicationId);
return Response.status(Response.Status.OK)
.entity("Successfully deleted the application for application ID: " + applicationId).build();
} catch (NotFoundException e) {
String msg =
"Couldn't found application for application id: " + applicationId + " to delete the application";
@ -431,47 +423,13 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
String msg = "Error occurred while deleting the application: " + applicationId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ApplicationStorageManagementException e) {
String msg = "Error occurred while deleting the application storage: " + applicationId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@DELETE
@Path("/{appid}/{uuid}")
public Response deleteApplicationRelease(
@PathParam("appid") int applicationId,
@PathParam("uuid") String releaseUuid) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager();
try {
String storedLocation = applicationManager.deleteApplicationRelease(applicationId, releaseUuid);
applicationStorageManager.deleteApplicationReleaseArtifacts(storedLocation);
String responseMsg = "Successfully deleted the application release of: " + applicationId + "";
return Response.status(Response.Status.OK).entity(responseMsg).build();
} catch (NotFoundException e) {
String msg = "Couldn't found application release which is having application id: " + applicationId
+ " and application release UUID:" + releaseUuid;
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (ForbiddenException e) {
String msg =
"You don't have require permission to delete the application release which has UUID " + releaseUuid
+ " and application ID " + applicationId;
log.error(msg, e);
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
}catch (ApplicationManagementException e) {
String msg = "Error occurred while deleting the application: " + applicationId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ApplicationStorageManagementException e) {
String msg = "Error occurred while deleting the application storage: " + applicationId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
/*
//todo ----------------------
*/
@GET
@Path("/lifecycle/{appId}/{uuid}")
public Response getLifecycleState(

@ -0,0 +1,110 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.publisher.api.services.impl.admin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
import org.wso2.carbon.device.application.mgt.common.ApplicationArtifact;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
import org.wso2.carbon.device.application.mgt.common.ApplicationType;
import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.common.dto.LifecycleStateDTO;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationStorageManagementException;
import org.wso2.carbon.device.application.mgt.common.exception.RequestValidatingException;
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.ApplicationManager;
import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorageManager;
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.core.exception.BadRequestException;
import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException;
import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException;
import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
import org.wso2.carbon.device.application.mgt.publisher.api.services.ApplicationManagementPublisherAPI;
import org.wso2.carbon.device.application.mgt.publisher.api.services.admin.ApplicationManagementPublisherAdminAPI;
import javax.activation.DataHandler;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Implementation of Application Management related APIs.
*/
@Produces({"application/json"})
@Path("/applications")
public class ApplicationManagementPublisherAdminAPIImpl implements ApplicationManagementPublisherAdminAPI {
private static Log log = LogFactory.getLog(ApplicationManagementPublisherAdminAPIImpl.class);
@DELETE
@Path("/{appid}/{uuid}")
public Response deleteApplicationRelease(
@PathParam("appid") int applicationId,
@PathParam("uuid") String releaseUuid) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager();
try {
String storedLocation = applicationManager.deleteApplicationRelease(applicationId, releaseUuid);
applicationStorageManager.deleteApplicationReleaseArtifacts(storedLocation);
String responseMsg = "Successfully deleted the application release of: " + applicationId + "";
return Response.status(Response.Status.OK).entity(responseMsg).build();
} catch (NotFoundException e) {
String msg = "Couldn't found application release which is having application id: " + applicationId
+ " and application release UUID:" + releaseUuid;
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (ForbiddenException e) {
String msg =
"You don't have require permission to delete the application release which has UUID " + releaseUuid
+ " and application ID " + applicationId;
log.error(msg, e);
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
}catch (ApplicationManagementException e) {
String msg = "Error occurred while deleting the application: " + applicationId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ApplicationStorageManagementException e) {
String msg = "Error occurred while deleting the application storage: " + applicationId;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
}
Loading…
Cancel
Save