Merge branch 'master' into 'master'

Improve application searching logic

See merge request entgra/carbon-device-mgt!520
4.x.x
Dharmakeerthi Lasantha 4 years ago
commit c953c41872

@ -84,6 +84,12 @@ public class Application {
value = "Application Rating")
private double rating;
@ApiModelProperty(name = "isDeletableApp", value = "Is Deletable Application")
private boolean isDeletableApp;
@ApiModelProperty(name = "isHideableApp", value = "Is Hideable application")
private boolean isHideableApp;
@ApiModelProperty(name = "applicationReleases",
value = "List of application releases",
required = true)
@ -156,6 +162,14 @@ public class Application {
public void setRating(double rating) { this.rating = rating; }
public boolean isDeletableApp() { return isDeletableApp; }
public void setDeletableApp(boolean deletableApp) { isDeletableApp = deletableApp; }
public boolean isHideableApp() { return isHideableApp; }
public void setHideableApp(boolean hideableApp) { isHideableApp = hideableApp; }
public boolean isAndroidEnterpriseApp() { return isAndroidEnterpriseApp; }
public void setAndroidEnterpriseApp(boolean androidEnterpriseApp) { isAndroidEnterpriseApp = androidEnterpriseApp; }

@ -597,19 +597,13 @@ public class ApplicationManagerImpl implements ApplicationManager {
@Override
public ApplicationList getApplications(Filter filter) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
ApplicationList applicationList = new ApplicationList();
List<ApplicationDTO> appDTOs;
List<Application> applications = new ArrayList<>();
List<ApplicationDTO> filteredApplications = new ArrayList<>();
DeviceType deviceType = null;
DeviceType deviceType;
//set default values
if (!StringUtils.isEmpty(filter.getDeviceType())) {
if (StringUtils.isNotBlank(filter.getDeviceType())) {
deviceType = APIUtil.getDeviceTypeData(filter.getDeviceType());
}
if (deviceType == null) {
} else {
deviceType = new DeviceType();
deviceType.setId(-1);
}
@ -617,52 +611,50 @@ public class ApplicationManagerImpl implements ApplicationManager {
try {
ConnectionManagerUtil.openDBConnection();
validateFilter(filter);
appDTOs = applicationDAO.getApplications(filter, deviceType.getId(), tenantId);
List<ApplicationDTO> appDTOs = applicationDAO.getApplications(filter, deviceType.getId(), tenantId);
for (ApplicationDTO applicationDTO : appDTOs) {
boolean isSearchingApp = true;
List<String> filteringTags = filter.getTags();
List<String> filteringCategories = filter.getCategories();
List<String> filteringUnrestrictedRoles = filter.getUnrestrictedRoles();
if (!lifecycleStateManager.getEndState().equals(applicationDTO.getStatus())) {
//get application categories, tags and unrestricted roles.
List<String> appUnrestrictedRoles = visibilityDAO
.getUnrestrictedRoles(applicationDTO.getId(), tenantId);
List<String> appCategoryList = applicationDAO.getAppCategories(applicationDTO.getId(), tenantId);
List<String> appTagList = applicationDAO.getAppTags(applicationDTO.getId(), tenantId);
if (lifecycleStateManager.getEndState().equals(applicationDTO.getStatus())) {
continue;
}
//Set application categories, tags and unrestricted roles to the application DTO.
applicationDTO.setUnrestrictedRoles(appUnrestrictedRoles);
applicationDTO.setAppCategories(appCategoryList);
applicationDTO.setTags(appTagList);
if ((appUnrestrictedRoles.isEmpty() || hasUserRole(appUnrestrictedRoles, userName)) && (
filteringUnrestrictedRoles == null || filteringUnrestrictedRoles.isEmpty()
|| hasAppUnrestrictedRole(appUnrestrictedRoles, filteringUnrestrictedRoles,
userName))) {
if (filteringCategories != null && !filteringCategories.isEmpty()) {
isSearchingApp = filteringCategories.stream().anyMatch(appCategoryList::contains);
}
if (filteringTags != null && !filteringTags.isEmpty() && isSearchingApp) {
isSearchingApp = filteringTags.stream().anyMatch(appTagList::contains);
}
if (isSearchingApp) {
filteredApplications.add(applicationDTO);
//Set application categories, tags and unrestricted roles to the application DTO.
applicationDTO.setUnrestrictedRoles(visibilityDAO
.getUnrestrictedRoles(applicationDTO.getId(), tenantId));
applicationDTO.setAppCategories(applicationDAO.getAppCategories(applicationDTO.getId(), tenantId));
applicationDTO.setTags(applicationDAO.getAppTags(applicationDTO.getId(), tenantId));
if (isFilteringApp(applicationDTO, filter)) {
List<ApplicationReleaseDTO> filteredApplicationReleaseDTOs = new ArrayList<>();
AtomicBoolean isDeletableApp = new AtomicBoolean(true);
for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) {
String appReleaseCurrentState = applicationReleaseDTO.getCurrentState();
if (!lifecycleStateManager.getEndState().equals(appReleaseCurrentState)) {
if (isDeletableApp.get() && !lifecycleStateManager.isDeletableState(appReleaseCurrentState)) {
isDeletableApp.set(false);
}
filteredApplicationReleaseDTOs.add(applicationReleaseDTO);
}
}
}
List<ApplicationReleaseDTO> filteredApplicationReleaseDTOs = new ArrayList<>();
for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) {
if (!applicationReleaseDTO.getCurrentState().equals(lifecycleStateManager.getEndState())) {
filteredApplicationReleaseDTOs.add(applicationReleaseDTO);
applicationDTO.setApplicationReleaseDTOs(filteredApplicationReleaseDTOs);
Application application = APIUtil.appDtoToAppResponse(applicationDTO);
/*
* Load the entire application again if the searched application is either deletable or all the app
* releases are in the end state of the app lifecycle. App has to be reloaded because when searching
* applications it may not contains all the application releases of an application.
*/
if (isDeletableApp.get() || filteredApplicationReleaseDTOs.isEmpty()){
ApplicationDTO entireApp = applicationDAO.getApplication(applicationDTO.getId(), tenantId);
if (filteredApplicationReleaseDTOs.isEmpty()){
application.setHideableApp(isHideableApp(entireApp.getApplicationReleaseDTOs()));
}
if (isDeletableApp.get()) {
application.setDeletableApp(isDeletableApp(entireApp.getApplicationReleaseDTOs()));
}
}
applications.add(application);
}
applicationDTO.setApplicationReleaseDTOs(filteredApplicationReleaseDTOs);
}
for (ApplicationDTO appDTO : filteredApplications) {
applications.add(APIUtil.appDtoToAppResponse(appDTO));
}
Pagination pagination = new Pagination();
@ -679,13 +671,9 @@ public class ApplicationManagerImpl implements ApplicationManager {
+ "requested filter.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (UserStoreException e) {
String msg = "User-store exception while checking whether the user " + userName + " of tenant " + tenantId
+ " has the publisher permission";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "DAO exception while getting applications for the user " + userName + " of tenant " + tenantId;
String msg =
"DAO exception while getting applications of tenant " + tenantId + ". Filter: " + filter.toString();
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
} finally {
@ -693,6 +681,96 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
/**
* To check whether the application is filtering app or not
*
* @param applicationDTO Application DTO object
* @param filter Filter
* @return false if application doesn't satisfy filters, otherwise returns true.
* @throws ApplicationManagementException if error occurred while checking whether user has app unrestricted roles
* or filtering roles.
*/
private boolean isFilteringApp(ApplicationDTO applicationDTO, Filter filter) throws ApplicationManagementException {
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
List<String> filteringTags = filter.getTags();
List<String> filteringCategories = filter.getCategories();
List<String> filteringUnrestrictedRoles = filter.getUnrestrictedRoles();
List<String> appUnrestrictedRoles = applicationDTO.getUnrestrictedRoles();
List<String> appCategoryList = applicationDTO.getAppCategories();
List<String> appTagList = applicationDTO.getTags();
try {
if (!appUnrestrictedRoles.isEmpty() && !hasUserRole(appUnrestrictedRoles, userName)) {
return false;
}
if (filteringUnrestrictedRoles != null && !filteringUnrestrictedRoles.isEmpty() && !hasAppUnrestrictedRole(
appUnrestrictedRoles, filteringUnrestrictedRoles, userName)) {
return false;
}
if (filteringCategories != null && !filteringCategories.isEmpty() && filteringCategories.stream()
.noneMatch(appCategoryList::contains)) {
return false;
}
if (filteringTags != null && !filteringTags.isEmpty() && filteringTags.stream()
.noneMatch(appTagList::contains)) {
return false;
}
} catch (UserStoreException e) {
String msg = "User-store exception while checking whether the user " + userName
+ " has permission to view application";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
return true;
}
/**
* To check whether the application is whether hideable or not
*
* @param applicationReleaseDTOs Application releases
* @return true if application releases are in hideable state (i.e Retired), otherwise returns false
* @throws ApplicationManagementException if error occurred while getting application release end state.
*/
private boolean isHideableApp(List<ApplicationReleaseDTO> applicationReleaseDTOs)
throws ApplicationManagementException {
try {
for (ApplicationReleaseDTO applicationReleaseDTO : applicationReleaseDTOs) {
if (!lifecycleStateManager.getEndState().equals(applicationReleaseDTO.getCurrentState())) {
return false;
}
}
} catch (LifecycleManagementException e) {
String msg = "Error occurred while testing application is whether hideable app or not.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
return true;
}
/**
* To check whether the application is whether deletable or not
*
* @param applicationReleaseDTOs Application releases
* @return true if application releases are in deletable state (i.e Created or Rejected), otherwise returns false
* @throws ApplicationManagementException if error occurred while checking whether the application release is in
* deletable state or not.
*/
private boolean isDeletableApp(List<ApplicationReleaseDTO> applicationReleaseDTOs)
throws ApplicationManagementException {
try {
for (ApplicationReleaseDTO applicationReleaseDTO : applicationReleaseDTOs) {
if (!lifecycleStateManager.isDeletableState(applicationReleaseDTO.getCurrentState())) {
return false;
}
}
} catch (LifecycleManagementException e) {
String msg = "Error occurred while testing application is whether deletable app or not.";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
return true;
}
@Override
public List<Application> getApplications(List<String> packageNames) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();

@ -616,47 +616,6 @@ public interface ApplicationManagementPublisherAPI {
@Multipart(value = "screenshot3") Attachment screenshot3
);
@PUT
@Consumes("application/json")
@Path("/retire/{appId}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT",
value = "Retire the application with the given UUID",
notes = "This will retire the application with the given UUID",
tags = "ApplicationDTO Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully deleted the application identified by UUID.",
response = List.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while deleting the application.",
response = ErrorResponse.class),
@ApiResponse(
code = 403,
message = "Don't have permission to delete the application"),
@ApiResponse(
code = 404,
message = "Application not found"),
})
Response retireApplication(
@ApiParam(
name = "UUID",
value = "Unique identifier of the ApplicationDTO",
required = true)
@PathParam("appId") int applicationId
);
@PUT
@Path("/image-artifacts/{uuid}")
@Produces(MediaType.APPLICATION_JSON)

@ -305,4 +305,45 @@ public interface ApplicationManagementPublisherAdminAPI {
required = true)
@PathParam("categoryName") String categoryName
);
@PUT
@Consumes("application/json")
@Path("/retire/{appId}")
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT",
value = "Retire the application with the given UUID",
notes = "This will retire the application with the given UUID",
tags = "Application Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:admin:app:publisher:update")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully deleted the application identified by UUID.",
response = List.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while deleting the application.",
response = ErrorResponse.class),
@ApiResponse(
code = 403,
message = "Don't have permission to delete the application"),
@ApiResponse(
code = 404,
message = "Application not found"),
})
Response retireApplication(
@ApiParam(
name = "UUID",
value = "Unique identifier of the ApplicationDTO",
required = true)
@PathParam("appId") int applicationId
);
}

@ -686,31 +686,6 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
}
}
@PUT
@Path("/retire/{appId}")
public Response retireApplication(
@PathParam("appId") int applicationId) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
try {
applicationManager.retireApplication(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";
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 which has 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();
}
}
@GET
@Path("/life-cycle/state-changes/{uuid}")
public Response getLifecycleStates(

@ -187,4 +187,29 @@ public class ApplicationManagementPublisherAdminAPIImpl implements ApplicationMa
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@PUT
@Path("/retire/{appId}")
public Response retireApplication(
@PathParam("appId") int applicationId) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
try {
applicationManager.retireApplication(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";
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 which has 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();
}
}
}

Loading…
Cancel
Save