diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java
index 600da94b4f..bc2eaabc47 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.common/src/main/java/org/wso2/carbon/device/application/mgt/common/services/SubscriptionManager.java
@@ -24,8 +24,10 @@ import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManag
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
+import org.wso2.carbon.device.mgt.common.app.mgt.App;
import java.util.List;
+import java.util.Properties;
/**
* This interface manages all the operations related with ApplicationDTO Subscription.
@@ -33,22 +35,22 @@ import java.util.List;
public interface SubscriptionManager {
/**
* Performs bulk subscription operation for a given application and a subscriber list.
- *
- * @param applicationUUID UUID of the application to subscribe/unsubscribe
+ * @param applicationUUID UUID of the application to subscribe/unsubscribe
* @param params list of subscribers. This list can be of either
- * {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is equal
+ * {@link DeviceIdentifier} if {@param subType} is equal
* to DEVICE or
* {@link String} if {@param subType} is USER, ROLE or GROUP
* @param subType subscription type. E.g. DEVICE, USER, ROLE, GROUP
{@see {
- * @param action subscription action. E.g. INSTALL/UNINSTALL
{@see {
- * @param generic type of the method.
- * @return {@link ApplicationInstallResponse}
- * @throws ApplicationManagementException if error occurs when subscribing to the given application
- * @link org.wso2.carbon.device.application.mgt.common.SubscriptionType}}
- * @link org.wso2.carbon.device.application.mgt.common.SubAction}}
+ * @param action subscription action. E.g. INSTALL/UNINSTALL
{@see {
+ * @param generic type of the method.
+ * @return {@link ApplicationInstallResponse}
+ * @throws ApplicationManagementException if error occurs when subscribing to the given application
+ * @link org.wso2.carbon.device.application.mgt.common.SubscriptionType}}
+ * @link org.wso2.carbon.device.application.mgt.common.SubAction}}
+ * @param properties
*/
ApplicationInstallResponse performBulkAppOperation(String applicationUUID, List params, String subType,
- String action) throws ApplicationManagementException;
+ String action, Properties properties) throws ApplicationManagementException;
/**
* Create an entry related to the scheduled task in the database.
@@ -121,7 +123,7 @@ public interface SubscriptionManager {
* @throws ApplicationManagementException if error occurred while installing given applications into the given
* device
*/
- void installAppsForDevice(DeviceIdentifier deviceIdentifier, List releaseUUID)
+ void installAppsForDevice(DeviceIdentifier deviceIdentifier, List apps)
throws ApplicationManagementException;
/***
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java
index 8219dbb4e7..2de1094c1f 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/SubscriptionManagerImpl.java
@@ -121,7 +121,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
@Override
public ApplicationInstallResponse performBulkAppOperation(String applicationUUID, List params,
- String subType, String action) throws ApplicationManagementException {
+ String subType, String action, Properties properties) throws ApplicationManagementException {
if (log.isDebugEnabled()) {
log.debug("Install application release which has UUID " + applicationUUID + " to " + params.size()
+ " users.");
@@ -134,7 +134,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
params);
ApplicationInstallResponse applicationInstallResponse = performActionOnDevices(
applicationSubscriptionInfo.getAppSupportingDeviceTypeName(), applicationSubscriptionInfo.getDevices(),
- applicationDTO, subType, applicationSubscriptionInfo.getSubscribers(), action);
+ applicationDTO, subType, applicationSubscriptionInfo.getSubscribers(), action, properties);
applicationInstallResponse.setErrorDeviceIdentifiers(applicationSubscriptionInfo.getErrorDeviceIdentifiers());
return applicationInstallResponse;
@@ -347,7 +347,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
}
@Override
- public void installAppsForDevice(DeviceIdentifier deviceIdentifier, List releaseUUIDs)
+ public void installAppsForDevice(DeviceIdentifier deviceIdentifier, List apps)
throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
@@ -370,7 +370,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
List appInstallingDevices = new ArrayList<>();
- for (String releaseUUID : releaseUUIDs) {
+ for (App app : apps) {
+ String releaseUUID = app.getId();
try {
ConnectionManagerUtil.openDBConnection();
ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(releaseUUID, tenantId);
@@ -409,7 +410,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
if (!appInstallingDevices.isEmpty()) {
performBulkAppOperation(releaseUUID, appInstallingDevices, SubscriptionType.DEVICE.toString(),
- SubAction.INSTALL.toString());
+ SubAction.INSTALL.toString(), app.getProperties());
}
}
}
@@ -621,7 +622,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
* data.
*/
private ApplicationInstallResponse performActionOnDevices(String deviceType, List devices,
- ApplicationDTO applicationDTO, String subType, List subscribers, String action)
+ ApplicationDTO applicationDTO, String subType, List subscribers, String action, Properties properties)
throws ApplicationManagementException {
//Get app subscribing info of each device
@@ -667,11 +668,11 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
}
for (Map.Entry> entry : deviceIdentifierMap.entrySet()) {
Activity activity = addAppOperationOnDevices(applicationDTO, new ArrayList<>(entry.getValue()),
- entry.getKey(), action);
+ entry.getKey(), action, properties);
activityList.add(activity);
}
} else {
- Activity activity = addAppOperationOnDevices(applicationDTO, deviceIdentifiers, deviceType, action);
+ Activity activity = addAppOperationOnDevices(applicationDTO, deviceIdentifiers, deviceType, action, properties);
activityList.add(activity);
}
@@ -982,13 +983,13 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
* @throws ApplicationManagementException if found an invalid device.
*/
private Activity addAppOperationOnDevices(ApplicationDTO applicationDTO,
- List deviceIdentifierList, String deviceType, String action)
+ List deviceIdentifierList, String deviceType, String action, Properties properties)
throws ApplicationManagementException {
DeviceManagementProviderService deviceManagementProviderService = HelperUtil
.getDeviceManagementProviderService();
try {
Application application = APIUtil.appDtoToAppResponse(applicationDTO);
- Operation operation = generateOperationPayloadByDeviceType(deviceType, application, action);
+ Operation operation = generateOperationPayloadByDeviceType(deviceType, application, action, properties);
return deviceManagementProviderService.addOperation(deviceType, operation, deviceIdentifierList);
} catch (OperationManagementException e) {
String msg = "Error occurred while adding the application install operation to devices";
@@ -1010,7 +1011,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
* @throws ApplicationManagementException if unknown application type is found to generate operation payload or
* invalid action is found to generate operation payload.
*/
- private Operation generateOperationPayloadByDeviceType(String deviceType, Application application, String action)
+ private Operation generateOperationPayloadByDeviceType(String deviceType, Application application, String action, Properties properties)
throws ApplicationManagementException {
try {
if (ApplicationType.CUSTOM.toString().equalsIgnoreCase(application.getType())) {
@@ -1046,6 +1047,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
app.setLocation(application.getApplicationReleases().get(0).getInstallerPath());
app.setIdentifier(application.getPackageName());
app.setName(application.getName());
+ app.setProperties(properties);
if (SubAction.INSTALL.toString().equalsIgnoreCase(action)) {
return MDMAndroidOperationUtil.createInstallAppOperation(app);
} else {
@@ -1067,7 +1069,6 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
app.setType(mobileAppType);
app.setLocation(plistDownloadEndpoint);
app.setIconImage(application.getApplicationReleases().get(0).getIconPath());
- Properties properties = new Properties();
properties.put(MDMAppConstants.IOSConstants.IS_PREVENT_BACKUP, true);
properties.put(MDMAppConstants.IOSConstants.IS_REMOVE_APP, true);
properties.put(MDMAppConstants.IOSConstants.I_TUNES_ID, application.getPackageName());
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java
index 8a95efc0aa..d8f491e37d 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTask.java
@@ -37,6 +37,7 @@ import org.wso2.carbon.device.mgt.core.task.impl.RandomlyAssignedScheduleTask;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -45,6 +46,7 @@ public class ScheduledAppSubscriptionTask extends RandomlyAssignedScheduleTask {
private static final String TASK_NAME = "SCHEDULE_APP_SUBSCRIPTION";
private SubscriptionManager subscriptionManager;
+ private String payload;
private String subscribers;
private String subscriptionType;
private String application;
@@ -57,6 +59,7 @@ public class ScheduledAppSubscriptionTask extends RandomlyAssignedScheduleTask {
@Override
public void setProperties(Map map) {
this.subscribers = map.get(Constants.SUBSCRIBERS);
+ this.payload = map.get(Constants.PAYLOAD);
this.subscriptionType = map.get(Constants.SUB_TYPE);
this.application = map.get(Constants.APP_UUID);
this.action = map.get(Constants.ACTION);
@@ -89,8 +92,9 @@ public class ScheduledAppSubscriptionTask extends RandomlyAssignedScheduleTask {
new TypeToken>() {
}.getType());
try {
+ Properties properties = new Gson().fromJson(payload, Properties.class);
subscriptionManager.performBulkAppOperation(this.application, deviceIdentifiers,
- this.subscriptionType, this.action);
+ this.subscriptionType, this.action, properties);
subscriptionDTO.setStatus(ExecutionStatus.EXECUTED);
} catch (ApplicationManagementException e) {
log.error(
@@ -102,8 +106,9 @@ public class ScheduledAppSubscriptionTask extends RandomlyAssignedScheduleTask {
List subscriberList = Pattern.compile(",").splitAsStream(this.subscribers).collect(
Collectors.toList());
try {
+ Properties properties = new Gson().fromJson(payload, Properties.class);
subscriptionManager.performBulkAppOperation(this.application, subscriberList,
- this.subscriptionType, this.action);
+ this.subscriptionType, this.action, properties);
subscriptionDTO.setStatus(ExecutionStatus.EXECUTED);
} catch (ApplicationManagementException e) {
log.error(
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java
index 326a358e1b..b274b1850f 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/task/ScheduledAppSubscriptionTaskManager.java
@@ -46,6 +46,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Properties;
import java.util.stream.Collectors;
public class ScheduledAppSubscriptionTaskManager {
@@ -73,7 +74,7 @@ public class ScheduledAppSubscriptionTaskManager {
* @throws ApplicationOperationTaskException if error occurred while scheduling the subscription
*/
public void scheduleAppSubscriptionTask(String applicationUUID, List> subscribers,
- SubscriptionType subscriptionType, SubAction action, long timestamp)
+ SubscriptionType subscriptionType, SubAction action, long timestamp, Properties properties)
throws ApplicationOperationTaskException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(timestamp * 1000));
@@ -106,7 +107,6 @@ public class ScheduledAppSubscriptionTaskManager {
taskProperties.put(Constants.APP_UUID, applicationUUID);
taskProperties.put(Constants.TENANT_DOMAIN, carbonContext.getTenantDomain(true));
taskProperties.put(Constants.SUBSCRIBER, carbonContext.getUsername());
-
String subscribersString;
if (SubscriptionType.DEVICE.equals(subscriptionType)) {
subscribersString = new Gson().toJson(subscribers);
@@ -115,6 +115,10 @@ public class ScheduledAppSubscriptionTaskManager {
subscribersString = subscribers.stream().map(String.class::cast).collect(Collectors.joining(","));
taskProperties.put(Constants.SUBSCRIBERS, subscribersString);
}
+ if(properties != null) {
+ String payload = new Gson().toJson(properties);
+ taskProperties.put(Constants.PAYLOAD, payload);
+ }
if (log.isDebugEnabled()) {
log.debug("Scheduling a task to " + action.toString() + " application: " + applicationUUID +
" to/from the following " + subscriptionType.toString() + "S [" + subscribersString + "] at: "
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java
index 866fbdd524..27498f77bb 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/Constants.java
@@ -58,6 +58,7 @@ public class Constants {
public static final String SUB_TYPE = "SUBSCRIPTION_TYPE";
public static final String ACTION = "ACTION";
public static final String APP_UUID = "APP_UUID";
+ public static final String APP_PROPERTIES = "APP_PROPERTIES";
public static final String SUBSCRIBER = "SUBSCRIBER";
public static final String TENANT_DOMAIN = "TENANT_DOMAIN";
public static final String TENANT_ID = "__TENANT_ID_PROP__";
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java
index 84081e9f88..9c2bfcdf79 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/SubscriptionManagementAPI.java
@@ -133,7 +133,12 @@ public interface SubscriptionManagementAPI {
name = "timestamp",
value = "Timestamp of scheduled install/uninstall operation"
)
- @QueryParam("timestamp") long timestamp
+ @QueryParam("timestamp") long timestamp,
+ @ApiParam(
+ name = "block-uninstall",
+ value = "App removal status of the install operation"
+ )
+ @QueryParam("block-uninstall") Boolean isUninstallBlocked
);
@POST
@@ -186,7 +191,12 @@ public interface SubscriptionManagementAPI {
name = "timestamp",
value = "Timestamp of scheduled install/uninstall operation"
)
- @QueryParam("timestamp") long timestamp
+ @QueryParam("timestamp") long timestamp,
+ @ApiParam(
+ name = "block-uninstall",
+ value = "App removal status of the install operation"
+ )
+ @QueryParam("block-uninstall") Boolean isUninstallBlocked
);
@POST
diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java
index a6324c8fdb..4a51353997 100644
--- a/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java
+++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.store.api/src/main/java/org/wso2/carbon/device/application/mgt/store/api/services/impl/SubscriptionManagementAPIImpl.java
@@ -34,8 +34,6 @@ import org.wso2.carbon.device.application.mgt.common.BasicUserInfoList;
import org.wso2.carbon.device.application.mgt.common.RoleList;
import org.wso2.carbon.device.application.mgt.common.DeviceGroupList;
import org.wso2.carbon.device.application.mgt.store.api.services.impl.util.RequestValidationUtil;
-import org.wso2.carbon.device.mgt.common.PaginationRequest;
-import org.wso2.carbon.device.mgt.common.PaginationResult;
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;
@@ -44,6 +42,9 @@ import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
import org.wso2.carbon.device.application.mgt.store.api.services.SubscriptionManagementAPI;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
+import org.wso2.carbon.device.mgt.common.MDMAppConstants;
+import org.wso2.carbon.device.mgt.common.PaginationRequest;
+import org.wso2.carbon.device.mgt.common.PaginationResult;
import javax.validation.Valid;
import javax.ws.rs.Path;
@@ -55,9 +56,8 @@ import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.core.Response;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
import java.util.List;
+import java.util.Properties;
/**
* Implementation of Subscription Management related APIs.
@@ -75,16 +75,22 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("uuid") String uuid,
@PathParam("action") String action,
@Valid List deviceIdentifiers,
- @QueryParam("timestamp") long timestamp) {
+ @QueryParam("timestamp") long timestamp,
+ @QueryParam("block-uninstall") Boolean isUninstallBlocked
+ ) {
+ Properties properties = new Properties();
+ if(isUninstallBlocked != null) {
+ properties.put(MDMAppConstants.AndroidConstants.IS_BLOCK_UNINSTALL, isUninstallBlocked);
+ }
try {
if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
ApplicationInstallResponse response = subscriptionManager
- .performBulkAppOperation(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), action);
+ .performBulkAppOperation(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), action, properties);
return Response.status(Response.Status.OK).entity(response).build();
} else {
return scheduleApplicationOperationTask(uuid, deviceIdentifiers, SubscriptionType.DEVICE,
- SubAction.valueOf(action.toUpperCase()), timestamp);
+ SubAction.valueOf(action.toUpperCase()), timestamp, properties);
}
} catch (NotFoundException e) {
String msg = "Couldn't found an application release for UUI: " + uuid;
@@ -116,17 +122,23 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("subType") String subType,
@PathParam("action") String action,
@Valid List subscribers,
- @QueryParam("timestamp") long timestamp) {
+ @QueryParam("timestamp") long timestamp,
+ @QueryParam("block-uninstall") Boolean isUninstallBlocked
+ ) {
+ Properties properties = new Properties();
+ if(isUninstallBlocked != null) {
+ properties.put(MDMAppConstants.AndroidConstants.IS_BLOCK_UNINSTALL, isUninstallBlocked);
+ }
try {
if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
ApplicationInstallResponse response = subscriptionManager
- .performBulkAppOperation(uuid, subscribers, subType, action);
+ .performBulkAppOperation(uuid, subscribers, subType, action, properties);
return Response.status(Response.Status.OK).entity(response).build();
} else {
return scheduleApplicationOperationTask(uuid, subscribers,
SubscriptionType.valueOf(subType.toUpperCase()), SubAction.valueOf(action.toUpperCase()),
- timestamp);
+ timestamp, properties);
}
} catch (NotFoundException e) {
String msg = "Couldn't found an application release for UUID: " + uuid + ". Hence, verify the payload";
@@ -170,7 +182,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
return Response.status(Response.Status.OK).entity(msg).build();
} else {
return scheduleApplicationOperationTask(uuid, deviceIdentifiers, SubscriptionType.DEVICE,
- SubAction.valueOf(SubAction.INSTALL.toString().toUpperCase()), timestamp);
+ SubAction.valueOf(SubAction.INSTALL.toString().toUpperCase()), timestamp, null);
}
} catch (NotFoundException e) {
String msg = "Couldn't found an application release for UUI: " + uuid + " to perform ent app installation "
@@ -216,7 +228,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
} else {
return scheduleApplicationOperationTask(uuid, subscribers,
SubscriptionType.valueOf(subType.toUpperCase()),
- SubAction.valueOf(SubAction.INSTALL.toString().toUpperCase()), timestamp);
+ SubAction.valueOf(SubAction.INSTALL.toString().toUpperCase()), timestamp, null);
}
} catch (NotFoundException e) {
String msg = "Couldn't found an application release for UUID: " + uuid + ". Hence, verify the payload";
@@ -255,11 +267,11 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
* @return {@link Response} of the operation
*/
private Response scheduleApplicationOperationTask(String applicationUUID, List> subscribers,
- SubscriptionType subType, SubAction subAction, long timestamp) {
+ SubscriptionType subType, SubAction subAction, long timestamp, Properties payload) {
try {
ScheduledAppSubscriptionTaskManager subscriptionTaskManager = new ScheduledAppSubscriptionTaskManager();
subscriptionTaskManager.scheduleAppSubscriptionTask(applicationUUID, subscribers, subType, subAction,
- timestamp);
+ timestamp, payload);
} catch (ApplicationOperationTaskException e) {
String msg = "Error occurred while scheduling the application install operation";
log.error(msg, e);
@@ -330,7 +342,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while getting application with the application release uuid: "
- + uuid;
+ + uuid;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
@@ -385,17 +397,17 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (BadRequestException e) {
String msg = "Found invalid payload for getting application which has UUID: " + uuid
- + ". Hence verify the payload";
+ + ". Hence verify the payload";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ForbiddenException e) {
String msg = "Application release is not in the installable state."
- + "Hence you are not permitted to get the devices details.";
+ + "Hence you are not permitted to get the devices details.";
log.error(msg, e);
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while getting application with the application " +
- "release uuid: " + uuid;
+ "release uuid: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java
index fc2bfadc56..78b299346b 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java
@@ -15,6 +15,22 @@
* specific language governing permissions and limitations
* under the License.
*
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.jaxrs.service.api;
@@ -45,6 +61,7 @@ import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@@ -257,6 +274,87 @@ public interface GroupManagementService {
@QueryParam("requireGroupProps")
boolean requireGroupProps);
+
+ @GET
+ @Path("/hierarchy")
+ @ApiOperation(
+ produces = MediaType.APPLICATION_JSON,
+ httpMethod = HTTPConstants.HEADER_GET,
+ value = "Getting the List of Hierarchical Groups",
+ notes = "Returns all groups enrolled with the system hierarchically.",
+ tags = "Device Group Management",
+ extensions = {
+ @Extension(properties = {
+ @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:groups")
+ })
+ }
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of device hierarchical groups.",
+ response = DeviceGroupList.class,
+ responseHeaders = {
+ @ResponseHeader(
+ name = "Content-Type",
+ description = "The content type of the body"),
+ @ResponseHeader(
+ name = "ETag",
+ description = "Entity Tag of the response resource.\n" +
+ "Used by caches, or in conditional requests."),
+ @ResponseHeader(
+ name = "Last-Modified",
+ description = "Date and time the resource has been modified the last time.\n" +
+ "Used by caches, or in conditional requests."),
+ }),
+ @ApiResponse(
+ code = 304,
+ message = "Not Modified. \n Empty body because the client has already the latest version of " +
+ "the requested resource."),
+ @ApiResponse(
+ code = 406,
+ message = "Not Acceptable.\n The requested media type is not supported."),
+ @ApiResponse(
+ code = 500,
+ message = "Internal Server Error. \n Server error occurred while fetching the groups list.",
+ response = ErrorResponse.class)
+ })
+ Response getGroupsWithHierarchy(
+ @ApiParam(
+ name = "name",
+ value = "Name of the group.")
+ @QueryParam("name")
+ String name,
+ @ApiParam(
+ name = "owner",
+ value = "Owner of the group.")
+ @QueryParam("owner")
+ String owner,
+ @ApiParam(
+ name = "requireGroupProps",
+ value = "Request group properties to include in the response",
+ defaultValue = "false")
+ @QueryParam("requireGroupProps")
+ boolean requireGroupProps,
+ @ApiParam(
+ name = "depth",
+ value = "Depth of the group hierarchy.")
+ @DefaultValue("3")
+ @QueryParam("depth")
+ int depth,
+ @ApiParam(
+ name = "offset",
+ value = "The starting pagination index for the complete list of qualified items.",
+ defaultValue = "0")
+ @DefaultValue("0")
+ @QueryParam("offset")
+ int offset,
+ @ApiParam(
+ name = "limit",
+ value = "Provide how many records require from the starting pagination index/offset.",
+ defaultValue = "5")
+ @DefaultValue("5")
+ @QueryParam("limit")
+ int limit);
+
@Path("/count")
@GET
@ApiOperation(
@@ -426,7 +524,14 @@ public interface GroupManagementService {
value = "Request group properties to include in the response",
defaultValue = "false")
@QueryParam("requireGroupProps")
- boolean requireGroupProps);
+ boolean requireGroupProps,
+ @ApiParam(
+ name = "depth",
+ value = "Depth of the group hierarchy.",
+ defaultValue = "1")
+ @DefaultValue("1")
+ @QueryParam("depth")
+ int depth);
@Path("/name/{groupName}")
@GET
@@ -485,7 +590,14 @@ public interface GroupManagementService {
value = "Request group properties to include in the response",
defaultValue = "false")
@QueryParam("requireGroupProps")
- boolean requireGroupProps);
+ boolean requireGroupProps,
+ @ApiParam(
+ name = "depth",
+ value = "Depth of the group hierarchy.",
+ defaultValue = "1")
+ @DefaultValue("1")
+ @QueryParam("depth")
+ int depth);
@Path("/id/{groupId}")
@PUT
@@ -594,7 +706,12 @@ public interface GroupManagementService {
name = "groupId",
value = "ID of the group to be deleted.",
required = true)
- @PathParam("groupId") int groupId);
+ @PathParam("groupId") int groupId,
+ @ApiParam(
+ name = "isDeleteChildren",
+ value = "Is the children groups needs to be deleted.",
+ required = true)
+ @QueryParam("isDeleteChildren") boolean isDeleteChildren);
@Path("/id/{groupId}/share")
@POST
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java
index e430611e90..8fd956e9fc 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java
@@ -15,6 +15,22 @@
* specific language governing permissions and limitations
* under the License.
*
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.jaxrs.service.api.admin;
@@ -166,6 +182,90 @@ public interface GroupManagementAdminService {
@QueryParam("requireGroupProps")
boolean requireGroupProps);
+ @GET
+ @Path("hierarchy")
+ @ApiOperation(
+ produces = MediaType.APPLICATION_JSON,
+ httpMethod = HTTPConstants.HEADER_GET,
+ value = "Getting the List of Hierarchical Groups",
+ notes = "Returns all groups enrolled with the system hierarchically.",
+ tags = "Device Group Management",
+ extensions = {
+ @Extension(properties = {
+ @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin-groups:view")
+ })
+ }
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of device groups hierarchically.",
+ response = DeviceGroupList.class,
+ responseHeaders = {
+ @ResponseHeader(
+ name = "Content-Type",
+ description = "The content type of the body"),
+ @ResponseHeader(
+ name = "ETag",
+ description = "Entity Tag of the response resource.\n" +
+ "Used by caches, or in conditional requests."),
+ @ResponseHeader(
+ name = "Last-Modified",
+ description = "Date and time the resource has been modified the last time.\n" +
+ "Used by caches, or in conditional requests."),
+ }),
+ @ApiResponse(
+ code = 304,
+ message = "Not Modified. \n Empty body because the client has already the latest version of " +
+ "the requested resource."),
+ @ApiResponse(
+ code = 406,
+ message = "Not Acceptable.\n The requested media type is not supported."),
+ @ApiResponse(
+ code = 500,
+ message = "Internal Server Error. \n Server error occurred while fetching the groups list.",
+ response = ErrorResponse.class)
+ })
+ Response getGroupsWithHierarchy(@ApiParam(
+ name = "name",
+ value = "Name of the group.")
+ @QueryParam("name")
+ String name,
+ @ApiParam(
+ name = "owner",
+ value = "Owner of the group.")
+ @QueryParam("owner")
+ String owner,
+ @ApiParam(
+ name = "status",
+ value = "status of group to be retrieve.")
+ @QueryParam("status")
+ String status,
+ @ApiParam(
+ name = "requireGroupProps",
+ value = "Request group properties to include in the response",
+ defaultValue = "false")
+ @QueryParam("requireGroupProps")
+ boolean requireGroupProps,
+ @ApiParam(
+ name = "depth",
+ value = "Depth of the group hierarchy.")
+ @DefaultValue("3")
+ @QueryParam("depth")
+ int depth,
+ @ApiParam(
+ name = "offset",
+ value = "The starting pagination index for the complete list of qualified items.",
+ defaultValue = "0")
+ @DefaultValue("0")
+ @QueryParam("offset")
+ int offset,
+ @ApiParam(
+ name = "limit",
+ value = "Provide how many records require from the starting pagination index/offset.",
+ defaultValue = "5")
+ @DefaultValue("5")
+ @QueryParam("limit")
+ int limit);
+
@Path("/count")
@GET
@ApiOperation(
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java
index 7648a102b8..c0a5a4a6b4 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java
@@ -136,6 +136,7 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
+import java.util.Properties;
@Path("/devices")
public class DeviceManagementServiceImpl implements DeviceManagementService {
@@ -915,7 +916,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
if (UUID != null) {
ApplicationInstallResponse response = subscriptionManager
.performBulkAppOperation(UUID, deviceIdentifiers, SubscriptionType.DEVICE.toString(),
- "uninstall");
+ "uninstall", new Properties());
return Response.status(Response.Status.OK).entity(response).build();
//if the applications not installed via entgra store
} else {
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java
index 0502f37ab3..3fed8e7504 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java
@@ -15,6 +15,22 @@
* specific language governing permissions and limitations
* under the License.
*
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.jaxrs.service.impl;
@@ -36,7 +52,6 @@ import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException;
-import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList;
@@ -47,10 +62,12 @@ import org.wso2.carbon.device.mgt.jaxrs.service.api.GroupManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.policy.mgt.common.PolicyAdministratorPoint;
-import org.wso2.carbon.policy.mgt.common.PolicyEvaluationException;
-import org.wso2.carbon.policy.mgt.common.PolicyEvaluationPoint;
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
@@ -89,11 +106,41 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
}
+ @GET
+ @Path("/hierarchy")
+ @Override
+ public Response getGroupsWithHierarchy(
+ @QueryParam("name") String name,
+ @QueryParam("owner") String owner,
+ @QueryParam("requireGroupProps") boolean requireGroupProps,
+ @DefaultValue("3") @QueryParam("depth") int depth,
+ @DefaultValue("0") @QueryParam("offset") int offset,
+ @DefaultValue("5") @QueryParam("limit") int limit) {
+ try {
+ RequestValidationUtil.validatePaginationParameters(offset, limit);
+ String currentUser = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
+ GroupPaginationRequest request = new GroupPaginationRequest(offset, limit);
+ request.setGroupName(name);
+ request.setOwner(owner);
+ request.setDepth(depth);
+ PaginationResult deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
+ .getGroupsWithHierarchy(currentUser, request, requireGroupProps);
+ DeviceGroupList deviceGroupList = new DeviceGroupList();
+ deviceGroupList.setList(deviceGroupsResult.getData());
+ deviceGroupList.setCount(deviceGroupsResult.getRecordsTotal());
+ return Response.status(Response.Status.OK).entity(deviceGroupList).build();
+ } catch (GroupManagementException e) {
+ String error = "Error occurred while retrieving groups with hierarchy.";
+ log.error(error, e);
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
+ }
+ }
+
@Override
public Response getGroupCount() {
try {
String currentUser = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
- int count = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroupCount(currentUser);
+ int count = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroupCount(currentUser, null);
return Response.status(Response.Status.OK).entity(count).build();
} catch (GroupManagementException e) {
String msg = "Error occurred while retrieving group count.";
@@ -125,10 +172,10 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
@Override
- public Response getGroup(int groupId, boolean requireGroupProps) {
+ public Response getGroup(int groupId, boolean requireGroupProps, int depth) {
try {
GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService();
- DeviceGroup deviceGroup = service.getGroup(groupId, requireGroupProps);
+ DeviceGroup deviceGroup = service.getGroup(groupId, requireGroupProps, depth);
if (deviceGroup != null) {
return Response.status(Response.Status.OK).entity(deviceGroup).build();
} else {
@@ -142,7 +189,7 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
@Override
- public Response getGroup(String groupName, boolean requireGroupProps) {
+ public Response getGroup(String groupName, boolean requireGroupProps, int depth) {
try {
GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService();
DeviceGroup deviceGroup = service.getGroup(groupName, requireGroupProps);
@@ -178,9 +225,9 @@ public class GroupManagementServiceImpl implements GroupManagementService {
}
@Override
- public Response deleteGroup(int groupId) {
+ public Response deleteGroup(int groupId, boolean isDeleteChildren) {
try {
- if (DeviceMgtAPIUtils.getGroupManagementProviderService().deleteGroup(groupId)) {
+ if (DeviceMgtAPIUtils.getGroupManagementProviderService().deleteGroup(groupId, isDeleteChildren)) {
return Response.status(Response.Status.OK).build();
} else {
return Response.status(Response.Status.NOT_FOUND).entity("Group not found.").build();
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java
index b742a1d8e1..a461b71b50 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java
@@ -15,6 +15,22 @@
* specific language governing permissions and limitations
* under the License.
*
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.jaxrs.service.impl.admin;
@@ -31,6 +47,10 @@ import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.GroupManagementAdminSe
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
@@ -74,6 +94,37 @@ public class GroupManagementAdminServiceImpl implements GroupManagementAdminServ
}
}
+ @GET
+ @Path("/hierarchy")
+ @Override
+ public Response getGroupsWithHierarchy(
+ @QueryParam("name") String name,
+ @QueryParam("owner") String owner,
+ @QueryParam("status") String status,
+ @QueryParam("requireGroupProps") boolean requireGroupProps,
+ @DefaultValue("3") @QueryParam("depth") int depth,
+ @DefaultValue("0") @QueryParam("offset") int offset,
+ @DefaultValue("5") @QueryParam("limit") int limit) {
+ try {
+ RequestValidationUtil.validatePaginationParameters(offset, limit);
+ GroupPaginationRequest request = new GroupPaginationRequest(offset, limit);
+ request.setGroupName(name);
+ request.setOwner(owner);
+ request.setStatus(status);
+ request.setDepth(depth);
+ PaginationResult deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService()
+ .getGroupsWithHierarchy(null, request, requireGroupProps);
+ DeviceGroupList deviceGroupList = new DeviceGroupList();
+ deviceGroupList.setList(deviceGroupsResult.getData());
+ deviceGroupList.setCount(deviceGroupsResult.getRecordsTotal());
+ return Response.status(Response.Status.OK).entity(deviceGroupList).build();
+ } catch (GroupManagementException e) {
+ String error = "Error occurred while retrieving groups with hierarchy.";
+ log.error(error, e);
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
+ }
+ }
+
@Override
public Response getGroupCount(String status) {
try {
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java
index 20136b172d..2d430c09f6 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java
@@ -15,11 +15,26 @@
* specific language governing permissions and limitations
* under the License.
*
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.jaxrs.service.impl;
-import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
@@ -130,13 +145,14 @@ public class GroupManagementServiceImplTest {
.toReturn(groupManagementProviderService);
PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(context);
- Mockito.doReturn(2).when(groupManagementProviderService).getGroupCount(Mockito.anyString());
+ Mockito.doReturn(2).when(groupManagementProviderService)
+ .getGroupCount(Mockito.anyString(), Mockito.anyString());
Response response = groupManagementService.getGroupCount();
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"GetGroupCount request failed with valid parameters");
Mockito.reset(groupManagementProviderService);
Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService)
- .getGroupCount(Mockito.anyString());
+ .getGroupCount(Mockito.anyString(), Mockito.anyString());
response = groupManagementService.getGroupCount();
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"GetGroupCount request succeeded with in-valid parameters");
@@ -174,16 +190,16 @@ public class GroupManagementServiceImplTest {
public void testGetGroup() throws GroupManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService"))
.toReturn(groupManagementProviderService);
- Mockito.doReturn(new DeviceGroup()).when(groupManagementProviderService).getGroup(1, false);
- Mockito.doReturn(null).when(groupManagementProviderService).getGroup(2, false);
- Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getGroup(3, false);
- Response response = groupManagementService.getGroup(1, false);
+ Mockito.doReturn(new DeviceGroup()).when(groupManagementProviderService).getGroup(1, false, 1);
+ Mockito.doReturn(null).when(groupManagementProviderService).getGroup(2, false, 1);
+ Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getGroup(3, false, 1);
+ Response response = groupManagementService.getGroup(1, false, 1);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"getGroup request failed for a request with valid parameters");
- response = groupManagementService.getGroup(2, false);
+ response = groupManagementService.getGroup(2, false, 1);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
"getGroup request returned a group for a non-existing group");
- response = groupManagementService.getGroup(3, false);
+ response = groupManagementService.getGroup(3, false, 1);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"getGroup request returned a group for a in-valid request");
}
@@ -216,16 +232,16 @@ public class GroupManagementServiceImplTest {
public void testDeleteGroup() throws GroupManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService"))
.toReturn(groupManagementProviderService);
- Mockito.doReturn(true).when(groupManagementProviderService).deleteGroup(1);
- Mockito.doReturn(false).when(groupManagementProviderService).deleteGroup(2);
- Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).deleteGroup(3);
- Response response = groupManagementService.deleteGroup(1);
+ Mockito.doReturn(true).when(groupManagementProviderService).deleteGroup(1, false);
+ Mockito.doReturn(false).when(groupManagementProviderService).deleteGroup(2, false);
+ Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).deleteGroup(3, false);
+ Response response = groupManagementService.deleteGroup(1, false);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"delete group request failed for a request with valid parameters");
- response = groupManagementService.deleteGroup(2);
+ response = groupManagementService.deleteGroup(2, false);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
"Non-existing group was successfully deleted");
- response = groupManagementService.deleteGroup(3);
+ response = groupManagementService.deleteGroup(3, false);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Deletion succeeded with an erroneous condition.");
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/GroupPaginationRequest.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/GroupPaginationRequest.java
index d7a74f199b..9402d2ab37 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/GroupPaginationRequest.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/GroupPaginationRequest.java
@@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.common;
@@ -28,6 +45,8 @@ public class GroupPaginationRequest {
private String owner;
private String groupName;
private String status;
+ private String parentPath;
+ private int depth;
public GroupPaginationRequest(int start, int rowCount) {
this.startIndex = start;
@@ -74,6 +93,22 @@ public class GroupPaginationRequest {
this.groupName = groupName;
}
+ public String getParentPath() {
+ return parentPath;
+ }
+
+ public void setParentPath(String parentPath) {
+ this.parentPath = parentPath;
+ }
+
+ public int getDepth() {
+ return depth;
+ }
+
+ public void setDepth(int depth) {
+ this.depth = depth;
+ }
+
@Override
public String toString() {
return "Group Name '" + this.groupName + "' num of rows: " + this.rowCount + " start index: " + this.startIndex
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/MDMAppConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/MDMAppConstants.java
index e7f8f17df7..40b647d6ea 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/MDMAppConstants.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/MDMAppConstants.java
@@ -45,6 +45,7 @@ public class MDMAppConstants {
private AndroidConstants() {
throw new AssertionError();
}
+ public static final String IS_BLOCK_UNINSTALL = "isBlockUninstall";
public static final String OPCODE_INSTALL_APPLICATION = "INSTALL_APPLICATION";
public static final String OPCODE_UNINSTALL_APPLICATION = "UNINSTALL_APPLICATION";
public static final String UNMANAGED_APP_UNINSTALL= "UNMANAGED_APP_UNINSTALL";
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/AppStoreApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/AppStoreApplication.java
index 50126814ca..71464070b7 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/AppStoreApplication.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/AppStoreApplication.java
@@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.common.app.mgt.android;
import com.google.gson.Gson;
import java.io.Serializable;
+import java.util.Properties;
/**
* This class represents the Appstore AuthenticationImpl information.
@@ -29,6 +30,7 @@ public class AppStoreApplication implements Serializable {
private String type;
private String appIdentifier;
+ private Properties properties;
public String getType() {
return type;
@@ -51,4 +53,11 @@ public class AppStoreApplication implements Serializable {
return gson.toJson(this);
}
+ public Properties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Properties properties) {
+ this.properties = properties;
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/EnterpriseApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/EnterpriseApplication.java
index f087013a18..0e9bdb47da 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/EnterpriseApplication.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/EnterpriseApplication.java
@@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.common.app.mgt.android;
import com.google.gson.Gson;
import java.io.Serializable;
+import java.util.Properties;
/**
* This class represents the Enterprise AuthenticationImpl information.
@@ -30,6 +31,7 @@ public class EnterpriseApplication implements Serializable {
private String type;
private String url;
private String appIdentifier;
+ private Properties properties;
public String getAppIdentifier() {
return appIdentifier;
@@ -60,4 +62,11 @@ public class EnterpriseApplication implements Serializable {
return gson.toJson(this);
}
+ public Properties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Properties properties) {
+ this.properties = properties;
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/WebApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/WebApplication.java
index 3257429269..70797dc8d9 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/WebApplication.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/app/mgt/android/WebApplication.java
@@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.common.app.mgt.android;
import com.google.gson.Gson;
import java.io.Serializable;
+import java.util.Properties;
/**
* This class represents the Web AuthenticationImpl information.
@@ -30,6 +31,7 @@ public class WebApplication implements Serializable {
private String name;
private String url;
private String type;
+ private Properties properties;
public String getName() {
return name;
@@ -60,4 +62,11 @@ public class WebApplication implements Serializable {
return gson.toJson(this);
}
+ public Properties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Properties properties) {
+ this.properties = properties;
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceGroup.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceGroup.java
index 20ed01fb49..a3511033d5 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceGroup.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceGroup.java
@@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.common.group.mgt;
@@ -21,6 +38,7 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
+import java.util.List;
import java.util.Map;
/**
@@ -47,6 +65,15 @@ public class DeviceGroup implements Serializable {
@ApiModelProperty(name = "status", value = "The status of group that needs updating/retrieval.")
private String status;
+ @ApiModelProperty(name = "parentGroupId", value = "Group ID of parent group")
+ private int parentGroupId;
+
+ @ApiModelProperty(name = "parentPath", value = "Path of parent group")
+ private String parentPath;
+
+ @ApiModelProperty(name = "childrenGroups", value = "Children groups")
+ private List childrenGroups;
+
public String getStatus() {
return status;
}
@@ -103,4 +130,27 @@ public class DeviceGroup implements Serializable {
this.groupProperties = groupProperties;
}
+ public int getParentGroupId() {
+ return parentGroupId;
+ }
+
+ public void setParentGroupId(int parentGroupId) {
+ this.parentGroupId = parentGroupId;
+ }
+
+ public String getParentPath() {
+ return parentPath;
+ }
+
+ public void setParentPath(String parentPath) {
+ this.parentPath = parentPath;
+ }
+
+ public List getChildrenGroups() {
+ return childrenGroups;
+ }
+
+ public void setChildrenGroups(List childrenGroups) {
+ this.childrenGroups = childrenGroups;
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceGroupConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceGroupConstants.java
index 039219bfe8..b1a185d98f 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceGroupConstants.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/group/mgt/DeviceGroupConstants.java
@@ -84,4 +84,8 @@ public class DeviceGroupConstants {
public static final String[] DEFAULT_VIEW_EVENTS_PERMISSIONS =
{"/permission/device-mgt/user/groups/device_events"};
}
+
+ public static final class HierarchicalGroup {
+ public static final String SEPERATOR = "/";
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java
index 1c4a1e91cd..f494007330 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java
@@ -32,6 +32,7 @@ public class UIConfiguration {
private List scopes;
private boolean isSsoEnable;
private int sessionTimeOut;
+ private int loginCacheCapacity;
@XmlElement(name = "AppRegistration", required=true)
public AppRegistration getAppRegistration() {
@@ -69,4 +70,13 @@ public class UIConfiguration {
public void setSessionTimeOut(int sessionTimeOut) {
this.sessionTimeOut = sessionTimeOut;
}
+
+ @XmlElement(name = "LoginCacheCapacity")
+ public int getLoginCacheCapacity() {
+ return loginCacheCapacity;
+ }
+
+ public void setLoginCacheCapacity(int loginCacheCapacity) {
+ this.loginCacheCapacity = loginCacheCapacity;
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/GroupDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/GroupDAO.java
index 79b536feaa..9ba4e36283 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/GroupDAO.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/GroupDAO.java
@@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.dao;
@@ -74,6 +91,15 @@ public interface GroupDAO {
*/
void deleteAllGroupProperties(int groupId, int tenantId) throws GroupManagementDAOException;
+ /**
+ * Remove properties of device groups.
+ *
+ * @param groupIds to be deleted.
+ * @param tenantId of the group.
+ * @throws GroupManagementDAOException on error during deletion of group properties of groups
+ */
+ void deleteAllGroupsProperties(List groupIds, int tenantId) throws GroupManagementDAOException;
+
/**
* Retrives all properties stored against a group.
*
@@ -95,6 +121,15 @@ public interface GroupDAO {
void updateGroup(DeviceGroup deviceGroup, int groupId, int tenantId)
throws GroupManagementDAOException;
+ /**
+ * Update existing Device Groups.
+ *
+ * @param deviceGroups groups to update.
+ * @param tenantId of the group.
+ * @throws GroupManagementDAOException on error during updating of groups
+ */
+ void updateGroups(List deviceGroups, int tenantId) throws GroupManagementDAOException;
+
/**
* Delete an existing Device Group.
*
@@ -104,6 +139,24 @@ public interface GroupDAO {
*/
void deleteGroup(int groupId, int tenantId) throws GroupManagementDAOException;
+ /**
+ * Delete mappings of Device Groups.
+ *
+ * @param groupIds of Device Groups.
+ * @param tenantId of the group.
+ * @throws GroupManagementDAOException on error during deletion of mappings of groups
+ */
+ void deleteGroupsMapping(List groupIds, int tenantId) throws GroupManagementDAOException;
+
+ /**
+ * Delete existing Device Groups.
+ *
+ * @param groupIds of Device Groups.
+ * @param tenantId of the group.
+ * @throws GroupManagementDAOException on error during deletion of groups
+ */
+ void deleteGroups(List groupIds, int tenantId) throws GroupManagementDAOException;
+
/**
* Get device group by id.
*
@@ -114,6 +167,25 @@ public interface GroupDAO {
*/
DeviceGroup getGroup(int groupId, int tenantId) throws GroupManagementDAOException;
+ /**
+ * Get children groups by parent path.
+ *
+ * @param parentPath of parent group.
+ * @param tenantId of the group.
+ * @return {@link List} list of children device groups
+ * @throws GroupManagementDAOException on error during retrieval of children groups
+ */
+ List getChildrenGroups(String parentPath, int tenantId) throws GroupManagementDAOException;
+
+ /**
+ * Get root groups.
+ *
+ * @param tenantId of the group.
+ * @return {@link List} list of root device groups
+ * @throws GroupManagementDAOException on error during retrieval of root groups
+ */
+ List getRootGroups(int tenantId) throws GroupManagementDAOException;
+
/**
* Get the groups of device with device id provided
* @param deviceId
@@ -306,10 +378,11 @@ public interface GroupDAO {
*
* @param roles of the group.
* @param tenantId of user's tenant.
+ * @param parentPath of the group.
* @return count of device groups.
* @throws GroupManagementDAOException
*/
- int getGroupsCount(String[] roles, int tenantId) throws GroupManagementDAOException;
+ int getGroupsCount(String[] roles, int tenantId, String parentPath) throws GroupManagementDAOException;
/**
* Get all device groups which owned by user.
@@ -336,10 +409,11 @@ public interface GroupDAO {
*
* @param username of the owner.
* @param tenantId of user's tenant.
+ * @param parentPath of the group.
* @return count of device groups.
* @throws GroupManagementDAOException
*/
- int getOwnGroupsCount(String username, int tenantId) throws GroupManagementDAOException;
+ int getOwnGroupsCount(String username, int tenantId, String parentPath) throws GroupManagementDAOException;
/**
* Get device Ids of devices which are assigned to groups.
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java
index 04d4bce584..c3426e3521 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java
@@ -14,18 +14,34 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.dao.impl;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.solr.common.StringUtils;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
-import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupDAO;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
@@ -49,6 +65,127 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
private static final Log log = LogFactory.getLog(AbstractGroupDAOImpl.class);
+ @Override
+ public List getGroups(GroupPaginationRequest request, int tenantId)
+ throws GroupManagementDAOException {
+ try {
+ Connection conn = GroupManagementDAOFactory.getConnection();
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE TENANT_ID = ?";
+ if (StringUtils.isNotBlank(request.getGroupName())) {
+ sql += " AND UPPER(GROUP_NAME) LIKE ?";
+ }
+ if (StringUtils.isNotBlank(request.getOwner())) {
+ sql += " AND UPPER(OWNER) LIKE ?";
+ }
+ if (StringUtils.isNotBlank(request.getStatus())) {
+ sql += " AND STATUS = ?";
+ }
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ sql += " AND PARENT_PATH LIKE ?";
+ }
+ if (request.getRowCount() != 0) {
+ sql += " LIMIT ? OFFSET ?";
+ }
+
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ int paramIndex = 1;
+ stmt.setInt(paramIndex++, tenantId);
+ if (StringUtils.isNotBlank(request.getGroupName())) {
+ stmt.setString(paramIndex++, request.getGroupName() + "%");
+ }
+ if (StringUtils.isNotBlank(request.getOwner())) {
+ stmt.setString(paramIndex++, request.getOwner() + "%");
+ }
+ if (StringUtils.isNotBlank(request.getStatus())) {
+ stmt.setString(paramIndex++, request.getStatus().toUpperCase());
+ }
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ stmt.setString(paramIndex++, request.getParentPath());
+ }
+ if (request.getRowCount() != 0) {
+ stmt.setInt(paramIndex++, request.getRowCount());
+ stmt.setInt(paramIndex, request.getStartIndex());
+ }
+ List deviceGroupList = new ArrayList<>();
+ try (ResultSet resultSet = stmt.executeQuery()) {
+ while (resultSet.next()) {
+ deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
+ }
+ }
+ return deviceGroupList;
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while retrieving groups in tenant: " + tenantId;
+ log.error(msg);
+ throw new GroupManagementDAOException(msg, e);
+ }
+ }
+
+ @Override
+ public List getGroups(GroupPaginationRequest request, List deviceGroupIds,
+ int tenantId) throws GroupManagementDAOException {
+ int deviceGroupIdsCount = deviceGroupIds.size();
+ if (deviceGroupIdsCount == 0) {
+ return new ArrayList<>();
+ }
+
+ try {
+ Connection conn = GroupManagementDAOFactory.getConnection();
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP WHERE TENANT_ID = ?";
+ if (StringUtils.isNotBlank(request.getGroupName())) {
+ sql += " AND GROUP_NAME LIKE ?";
+ }
+ if (StringUtils.isNotBlank(request.getOwner())) {
+ sql += " AND OWNER LIKE ?";
+ }
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ sql += " AND PARENT_PATH LIKE ?";
+ }
+ sql += " AND ID IN (";
+ for (int i = 0; i < deviceGroupIdsCount; i++) {
+ sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
+ }
+ sql += ")";
+ if (request.getRowCount() != 0) {
+ sql += " LIMIT ? OFFSET ?";
+ }
+
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ int paramIndex = 1;
+ stmt.setInt(paramIndex++, tenantId);
+ if (StringUtils.isNotBlank(request.getGroupName())) {
+ stmt.setString(paramIndex++, request.getGroupName() + "%");
+ }
+ if (StringUtils.isNotBlank(request.getOwner())) {
+ stmt.setString(paramIndex++, request.getOwner() + "%");
+ }
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ stmt.setString(paramIndex++, request.getParentPath());
+ }
+ for (Integer deviceGroupId : deviceGroupIds) {
+ stmt.setInt(paramIndex++, deviceGroupId);
+ }
+ if (request.getRowCount() != 0) {
+ stmt.setInt(paramIndex++, request.getRowCount());
+ stmt.setInt(paramIndex, request.getStartIndex());
+ }
+ List deviceGroupList = new ArrayList<>();
+ try (ResultSet resultSet = stmt.executeQuery()) {
+ while (resultSet.next()) {
+ deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
+ }
+ }
+ return deviceGroupList;
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while retrieving groups of groups IDs " + deviceGroupIds.toString()
+ + " in tenant: " + tenantId;
+ log.error(msg);
+ throw new GroupManagementDAOException(msg, e);
+ }
+ }
+
@Override
public int addGroup(DeviceGroup deviceGroup, int tenantId) throws GroupManagementDAOException {
PreparedStatement stmt = null;
@@ -59,9 +196,11 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if (deviceGroup.getStatus() == null || deviceGroup.getStatus().isEmpty()) {
- sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID) VALUES (?, ?, ?, ?)";
+ sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH) "
+ + "VALUES (?, ?, ?, ?, ?)";
} else {
- sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, STATUS) VALUES (?, ?, ?, ?, ?)";
+ sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, STATUS) "
+ + "VALUES (?, ?, ?, ?, ?, ?)";
hasStatus = true;
}
stmt = conn.prepareStatement(sql, new String[]{"ID"});
@@ -69,8 +208,9 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
stmt.setString(2, deviceGroup.getName());
stmt.setString(3, deviceGroup.getOwner());
stmt.setInt(4, tenantId);
+ stmt.setString(5, deviceGroup.getParentPath());
if (hasStatus) {
- stmt.setString(5, deviceGroup.getStatus());
+ stmt.setString(6, deviceGroup.getStatus());
}
stmt.executeUpdate();
@@ -151,10 +291,12 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql =
- "UPDATE DM_GROUP SET DESCRIPTION = ?, GROUP_NAME = ?, OWNER = ? WHERE ID = ? AND TENANT_ID = ?";
+ "UPDATE DM_GROUP SET DESCRIPTION = ?, GROUP_NAME = ?, OWNER = ?, PARENT_PATH = ? WHERE ID = ? "
+ + "AND TENANT_ID = ?";
if (deviceGroup.getStatus() != null && !deviceGroup.getStatus().isEmpty()) {
- sql = "UPDATE DM_GROUP SET DESCRIPTION = ?, GROUP_NAME = ?, OWNER = ?, STATUS = ? WHERE ID = ? AND TENANT_ID = ?";
+ sql = "UPDATE DM_GROUP SET DESCRIPTION = ?, GROUP_NAME = ?, OWNER = ?, PARENT_PATH = ?, STATUS = ? "
+ + "WHERE ID = ? AND TENANT_ID = ?";
hasStatus = true;
}
stmt = conn.prepareStatement(sql);
@@ -162,11 +304,12 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
stmt.setString(paramIndex++, deviceGroup.getDescription());
stmt.setString(paramIndex++, deviceGroup.getName());
stmt.setString(paramIndex++, deviceGroup.getOwner());
+ stmt.setString(paramIndex++, deviceGroup.getParentPath());
if (hasStatus) {
stmt.setString(paramIndex++, deviceGroup.getStatus());
}
stmt.setInt(paramIndex++, groupId);
- stmt.setInt(paramIndex++, tenantId);
+ stmt.setInt(paramIndex, tenantId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while updating deviceGroup '" +
@@ -176,6 +319,32 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
+ @Override
+ public void updateGroups(List deviceGroups, int tenantId) throws GroupManagementDAOException {
+ try {
+ Connection conn = GroupManagementDAOFactory.getConnection();
+ String sql = "UPDATE DM_GROUP SET DESCRIPTION = ?, GROUP_NAME = ?, OWNER = ?, STATUS = ?, "
+ + "PARENT_PATH = ? WHERE ID = ? AND TENANT_ID = ?";
+ try (PreparedStatement stmt = conn.prepareStatement(sql)){
+ for (DeviceGroup deviceGroup : deviceGroups) {
+ stmt.setString(1, deviceGroup.getDescription());
+ stmt.setString(2, deviceGroup.getName());
+ stmt.setString(3, deviceGroup.getOwner());
+ stmt.setString(4, deviceGroup.getStatus());
+ stmt.setString(5, deviceGroup.getParentPath());
+ stmt.setInt(6, deviceGroup.getGroupId());
+ stmt.setInt(7, tenantId);
+ stmt.addBatch();
+ }
+ stmt.executeBatch();
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while updating groups as batch";
+ log.error(msg);
+ throw new GroupManagementDAOException(msg, e);
+ }
+ }
+
@Override
public void deleteGroup(int groupId, int tenantId) throws GroupManagementDAOException {
Connection conn;
@@ -217,6 +386,64 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
+ @Override
+ public void deleteGroupsMapping(List groupIds, int tenantId) throws GroupManagementDAOException {
+ try {
+ Connection conn = GroupManagementDAOFactory.getConnection();
+ String sql = "DELETE FROM DM_ROLE_GROUP_MAP WHERE GROUP_ID = ? AND TENANT_ID = ?";
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ for (int groupId : groupIds) {
+ stmt.setInt(1, groupId);
+ stmt.setInt(2, tenantId);
+ stmt.addBatch();
+ }
+ stmt.executeBatch();
+ }
+ sql = "DELETE FROM DM_DEVICE_GROUP_MAP WHERE GROUP_ID = ? AND TENANT_ID = ?";
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ for (int groupId : groupIds) {
+ stmt.setInt(1, groupId);
+ stmt.setInt(2, tenantId);
+ stmt.addBatch();
+ }
+ stmt.executeBatch();
+ }
+ sql = "DELETE FROM DM_DEVICE_GROUP_POLICY WHERE DEVICE_GROUP_ID = ? AND TENANT_ID = ?";
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ for (int groupId : groupIds) {
+ stmt.setInt(1, groupId);
+ stmt.setInt(2, tenantId);
+ stmt.addBatch();
+ }
+ stmt.executeBatch();
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while removing mappings of groups as batches";
+ log.error(msg);
+ throw new GroupManagementDAOException(msg, e);
+ }
+ }
+
+ @Override
+ public void deleteGroups(List groupIds, int tenantId) throws GroupManagementDAOException {
+ try {
+ Connection conn = GroupManagementDAOFactory.getConnection();
+ String sql = "DELETE FROM DM_GROUP WHERE ID = ? AND TENANT_ID = ?";
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ for (int groupId : groupIds) {
+ stmt.setInt(1, groupId);
+ stmt.setInt(2, tenantId);
+ stmt.addBatch();
+ }
+ stmt.executeBatch();
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while deleting groups as batches";
+ log.error(msg);
+ throw new GroupManagementDAOException(msg, e);
+ }
+ }
+
public void deleteAllGroupProperties(int groupId, int tenantId)
throws GroupManagementDAOException {
PreparedStatement stmt = null;
@@ -235,6 +462,25 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
+ public void deleteAllGroupsProperties(List groupIds, int tenantId) throws GroupManagementDAOException {
+ try {
+ Connection conn = GroupManagementDAOFactory.getConnection();
+ String sql = "DELETE FROM GROUP_PROPERTIES WHERE GROUP_ID = ? AND TENANT_ID = ?";
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ for (Integer groupId : groupIds) {
+ stmt.setInt(1, groupId);
+ stmt.setInt(2, tenantId);
+ stmt.addBatch();
+ }
+ stmt.executeUpdate();
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while deleting properties of groups as batches";
+ log.error(msg);
+ throw new GroupManagementDAOException(msg, e);
+ }
+ }
+
public Map getAllGroupProperties(int groupId, int tenantId)
throws GroupManagementDAOException {
PreparedStatement stmt = null;
@@ -266,7 +512,8 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
ResultSet resultSet = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE ID = ? AND TENANT_ID = ?";
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP WHERE ID = ? "
+ + "AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
stmt.setInt(2, tenantId);
@@ -284,6 +531,56 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
}
+ @Override
+ public List getChildrenGroups(String parentPath, int tenantId) throws GroupManagementDAOException {
+ try {
+ Connection conn = GroupManagementDAOFactory.getConnection();
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE PARENT_PATH LIKE ? AND TENANT_ID = ?";
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ stmt.setString(1, parentPath + "%");
+ stmt.setInt(2, tenantId);
+ List deviceGroupList = new ArrayList<>();
+ try (ResultSet resultSet = stmt.executeQuery()) {
+ while (resultSet.next()) {
+ deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
+ }
+ }
+ return deviceGroupList;
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while retrieving children group having parent path '" + parentPath
+ + "' in tenant: " + tenantId;
+ log.error(msg);
+ throw new GroupManagementDAOException(msg, e);
+ }
+ }
+
+ @Override
+ public List getRootGroups(int tenantId) throws GroupManagementDAOException {
+ try {
+ Connection conn = GroupManagementDAOFactory.getConnection();
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE PARENT_PATH LIKE ? AND TENANT_ID = ?";
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ stmt.setString(1, "/");
+ stmt.setInt(2, tenantId);
+ List deviceGroupList = new ArrayList<>();
+ try (ResultSet resultSet = stmt.executeQuery()) {
+ deviceGroupList = new ArrayList<>();
+ while (resultSet.next()) {
+ deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
+ }
+ }
+ return deviceGroupList;
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while retrieving root groups in tenant: " + tenantId;
+ log.error(msg);
+ throw new GroupManagementDAOException(msg, e);
+ }
+ }
+
@Override
public List getGroups(int deviceId, int tenantId) throws GroupManagementDAOException {
PreparedStatement stmt = null;
@@ -291,7 +588,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List deviceGroupBuilders = new ArrayList<>();
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT G.ID, G.GROUP_NAME, G.DESCRIPTION, G.OWNER, G.STATUS FROM DM_GROUP G " +
+ String sql = "SELECT G.ID, G.GROUP_NAME, G.DESCRIPTION, G.OWNER, G.STATUS, G.PARENT_PATH FROM DM_GROUP G " +
"INNER JOIN DM_DEVICE_GROUP_MAP GM ON G.ID = GM.GROUP_ID " +
"WHERE GM.DEVICE_ID = ? AND GM.TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
@@ -316,7 +613,8 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List deviceGroupList = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
resultSet = stmt.executeQuery();
@@ -389,6 +687,9 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
sql += " AND STATUS = ?";
hasStatus = true;
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ sql += " AND PARENT_PATH = ?";
+ }
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
@@ -397,10 +698,13 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
- stmt.setString(paramIndex, owner + "%");
+ stmt.setString(paramIndex++, owner + "%");
}
if (hasStatus) {
- stmt.setString(paramIndex, request.getStatus());
+ stmt.setString(paramIndex++, request.getStatus());
+ }
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ stmt.setString(paramIndex, request.getParentPath());
}
resultSet = stmt.executeQuery();
if (resultSet.next()) {
@@ -422,7 +726,8 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql =
- "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE GROUP_NAME = ? AND TENANT_ID = ?";
+ "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE GROUP_NAME = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, groupName);
stmt.setInt(2, tenantId);
@@ -592,7 +897,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List deviceGroupList = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP g, " +
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP g, " +
"(SELECT GROUP_ID FROM DM_ROLE_GROUP_MAP WHERE ROLE IN (";
int index = 0;
@@ -658,7 +963,7 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
@Override
- public int getGroupsCount(String[] roles, int tenantId) throws GroupManagementDAOException {
+ public int getGroupsCount(String[] roles, int tenantId, String parentPath) throws GroupManagementDAOException {
int rolesCount = roles.length;
if (rolesCount == 0) {
return 0;
@@ -672,14 +977,20 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
for (int i = 0; i < rolesCount; i++) {
sql += (rolesCount - 1 != i) ? "?," : "?";
}
- sql += ")) gr WHERE g.ID = gr.GROUP_ID AND TENANT_ID = ? GROUP BY g.ID";
-
+ sql += ")) gr WHERE g.ID = gr.GROUP_ID AND TENANT_ID = ? ";
+ if (StringUtils.isNotBlank(parentPath)) {
+ sql += " AND g.PARENT_PATH = ? ";
+ }
+ sql += "GROUP BY g.ID";
stmt = conn.prepareStatement(sql);
int index = 0;
while (index++ < rolesCount) {
stmt.setString(index, roles[index - 1]);
}
- stmt.setInt(index, tenantId);
+ stmt.setInt(index++, tenantId);
+ if (StringUtils.isNotBlank(parentPath)) {
+ stmt.setString(index, parentPath);
+ }
resultSet = stmt.executeQuery();
if (resultSet.next()) {
return resultSet.getInt("GROUP_COUNT");
@@ -700,7 +1011,8 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
List deviceGroupList = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE OWNER = ? AND TENANT_ID = ?";
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE OWNER = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, username);
stmt.setInt(2, tenantId);
@@ -744,15 +1056,21 @@ public abstract class AbstractGroupDAOImpl implements GroupDAO {
}
@Override
- public int getOwnGroupsCount(String username, int tenantId) throws GroupManagementDAOException {
+ public int getOwnGroupsCount(String username, int tenantId, String parentPath) throws GroupManagementDAOException {
PreparedStatement stmt = null;
ResultSet resultSet = null;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT COUNT(ID) AS GROUP_COUNT FROM DM_GROUP WHERE OWNER = ? AND TENANT_ID = ?";
+ if (StringUtils.isNotBlank(parentPath)) {
+ sql += " AND PARENT_PATH = ?";
+ }
stmt = conn.prepareStatement(sql);
stmt.setString(1, username);
stmt.setInt(2, tenantId);
+ if (StringUtils.isNotBlank(parentPath)) {
+ stmt.setString(3, parentPath);
+ }
resultSet = stmt.executeQuery();
if (resultSet.next()) {
return resultSet.getInt("GROUP_COUNT");
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/GenericGroupDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/GenericGroupDAOImpl.java
index d980e9e0ab..96ca67edd0 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/GenericGroupDAOImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/GenericGroupDAOImpl.java
@@ -14,18 +14,32 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.dao.impl.group;
import org.wso2.carbon.device.mgt.common.Device;
-import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
-import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.impl.AbstractGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
-import org.wso2.carbon.device.mgt.core.dao.util.GroupManagementDAOUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -38,134 +52,6 @@ import java.util.List;
* This class represents implementation of GroupDAO
*/
public class GenericGroupDAOImpl extends AbstractGroupDAOImpl {
- @Override
- public List getGroups(GroupPaginationRequest request, int tenantId)
- throws GroupManagementDAOException {
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
- List deviceGroupList = null;
-
- String groupName = request.getGroupName();
- boolean hasGroupName = false;
- String owner = request.getOwner();
- String status = request.getStatus();
- boolean hasOwner = false;
- boolean hasStatus = false;
- boolean hasLimit = request.getRowCount() != 0;
-
- try {
- Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
- if (groupName != null && !groupName.isEmpty()) {
- sql += " AND UPPER(GROUP_NAME) LIKE ?";
- hasGroupName = true;
- }
- if (owner != null && !owner.isEmpty()) {
- sql += " AND UPPER(OWNER) LIKE ?";
- hasOwner = true;
- }
- if (status != null && !status.isEmpty()) {
- sql += " AND STATUS = ?";
- hasStatus = true;
- }
- if (hasLimit) {
- sql += " LIMIT ?, ?";
- }
-
- int paramIndex = 1;
- stmt = conn.prepareStatement(sql);
- stmt.setInt(paramIndex++, tenantId);
- if (hasGroupName) {
- stmt.setString(paramIndex++, groupName + "%");
- }
- if (hasOwner) {
- stmt.setString(paramIndex++, owner + "%");
- }
- if (hasStatus) {
- stmt.setString(paramIndex++, status.toUpperCase());
- }
- if (hasLimit) {
- stmt.setInt(paramIndex++, request.getStartIndex());
- stmt.setInt(paramIndex, request.getRowCount());
- }
- resultSet = stmt.executeQuery();
- deviceGroupList = new ArrayList<>();
- while (resultSet.next()) {
- deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
- }
- } catch (SQLException e) {
- throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
- } finally {
- GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
- }
- return deviceGroupList;
- }
-
- @Override
- public List getGroups(GroupPaginationRequest request, List deviceGroupIds,
- int tenantId) throws GroupManagementDAOException {
- int deviceGroupIdsCount = deviceGroupIds.size();
- if (deviceGroupIdsCount == 0) {
- return new ArrayList<>();
- }
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
- List deviceGroupList = null;
-
- String groupName = request.getGroupName();
- boolean hasGroupName = false;
- String owner = request.getOwner();
- boolean hasOwner = false;
- boolean hasLimit = request.getRowCount() != 0;
-
- try {
- Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
- if (groupName != null && !groupName.isEmpty()) {
- sql += " AND GROUP_NAME LIKE ?";
- hasGroupName = true;
- }
- if (owner != null && !owner.isEmpty()) {
- sql += " AND OWNER LIKE ?";
- hasOwner = true;
- }
- sql += " AND ID IN (";
- for (int i = 0; i < deviceGroupIdsCount; i++) {
- sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
- }
- sql += ")";
- if (hasLimit) {
- sql += " LIMIT ?, ?";
- }
-
- int paramIndex = 1;
- stmt = conn.prepareStatement(sql);
- stmt.setInt(paramIndex++, tenantId);
- if (hasGroupName) {
- stmt.setString(paramIndex++, groupName + "%");
- }
- if (hasOwner) {
- stmt.setString(paramIndex++, owner + "%");
- }
- for (Integer deviceGroupId : deviceGroupIds) {
- stmt.setInt(paramIndex++, deviceGroupId);
- }
- if (hasLimit) {
- stmt.setInt(paramIndex++, request.getStartIndex());
- stmt.setInt(paramIndex, request.getRowCount());
- }
- resultSet = stmt.executeQuery();
- deviceGroupList = new ArrayList<>();
- while (resultSet.next()) {
- deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
- }
- } catch (SQLException e) {
- throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
- } finally {
- GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
- }
- return deviceGroupList;
- }
@Override
public List getDevices(int groupId, int startIndex, int rowCount, int tenantId)
@@ -209,4 +95,4 @@ public class GenericGroupDAOImpl extends AbstractGroupDAOImpl {
}
return devices;
}
-}
\ No newline at end of file
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/OracleGroupDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/OracleGroupDAOImpl.java
index 4074840e0f..e7473b6b53 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/OracleGroupDAOImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/OracleGroupDAOImpl.java
@@ -14,10 +14,28 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.dao.impl.group;
+import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
@@ -56,7 +74,8 @@ public class OracleGroupDAOImpl extends AbstractGroupDAOImpl {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
@@ -69,6 +88,9 @@ public class OracleGroupDAOImpl extends AbstractGroupDAOImpl {
sql += " AND STATUS = ?";
hasStatus = true;
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ sql += " AND PARENT_PATH LIKE ?";
+ }
if (hasLimit) {
sql += " OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
}
@@ -85,6 +107,9 @@ public class OracleGroupDAOImpl extends AbstractGroupDAOImpl {
if (hasStatus) {
stmt.setString(paramIndex++, status.toUpperCase());
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ stmt.setString(paramIndex++, request.getParentPath());
+ }
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
@@ -121,7 +146,8 @@ public class OracleGroupDAOImpl extends AbstractGroupDAOImpl {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
@@ -130,6 +156,9 @@ public class OracleGroupDAOImpl extends AbstractGroupDAOImpl {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ sql += " AND PARENT_PATH LIKE ?";
+ }
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
@@ -148,6 +177,9 @@ public class OracleGroupDAOImpl extends AbstractGroupDAOImpl {
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ stmt.setString(paramIndex++, request.getParentPath());
+ }
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
@@ -210,4 +242,4 @@ public class OracleGroupDAOImpl extends AbstractGroupDAOImpl {
}
return devices;
}
-}
\ No newline at end of file
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/PostgreSQLGroupDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/PostgreSQLGroupDAOImpl.java
index 4140a5c48a..a01ef5b6b8 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/PostgreSQLGroupDAOImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/PostgreSQLGroupDAOImpl.java
@@ -14,13 +14,29 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.dao.impl.group;
import org.apache.solr.common.StringUtils;
import org.wso2.carbon.device.mgt.common.Device;
-import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
@@ -50,10 +66,10 @@ public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql;
if(StringUtils.isEmpty(deviceGroup.getStatus())) {
- sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID) " +
+ sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH) " +
"VALUES (?, ?, ?, ?) RETURNING ID";
} else {
- sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, STATUS) " +
+ sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID, PARENT_PATH, STATUS) " +
"VALUES (?, ?, ?, ?, ?) RETURNING ID";
hasStatus = true;
}
@@ -62,8 +78,9 @@ public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
stmt.setString(2, deviceGroup.getName());
stmt.setString(3, deviceGroup.getOwner());
stmt.setInt(4, tenantId);
+ stmt.setString(5, deviceGroup.getParentPath());
if(hasStatus) {
- stmt.setString(5, deviceGroup.getStatus());
+ stmt.setString(6, deviceGroup.getStatus());
}
stmt.execute();
rs = stmt.getGeneratedKeys();
@@ -79,135 +96,6 @@ public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
}
}
- @Override
- public List getGroups(GroupPaginationRequest request, int tenantId)
- throws GroupManagementDAOException {
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
- List deviceGroupList = null;
-
- String groupName = request.getGroupName();
- boolean hasGroupName = false;
- String owner = request.getOwner();
- String status = request.getStatus();
- boolean hasOwner = false;
- boolean hasStatus = false;
- boolean hasLimit = request.getRowCount() != 0;
-
- try {
- Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
- if (groupName != null && !groupName.isEmpty()) {
- sql += " AND GROUP_NAME LIKE ?";
- hasGroupName = true;
- }
- if (owner != null && !owner.isEmpty()) {
- sql += " AND OWNER LIKE ?";
- hasOwner = true;
- }
- if (status != null && !status.isEmpty()) {
- sql += " AND STATUS = ?";
- hasStatus = true;
- }
- if (hasLimit) {
- sql += " LIMIT ? OFFSET ?";
- }
-
- int paramIndex = 1;
- stmt = conn.prepareStatement(sql);
- stmt.setInt(paramIndex++, tenantId);
- if (hasGroupName) {
- stmt.setString(paramIndex++, groupName + "%");
- }
- if (hasOwner) {
- stmt.setString(paramIndex++, owner + "%");
- }
- if (hasStatus) {
- stmt.setString(paramIndex++, status.toUpperCase());
- }
- if (hasLimit) {
- stmt.setInt(paramIndex++, request.getRowCount());
- stmt.setInt(paramIndex, request.getStartIndex());
- }
- resultSet = stmt.executeQuery();
- deviceGroupList = new ArrayList<>();
- while (resultSet.next()) {
- deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
- }
- } catch (SQLException e) {
- throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
- } finally {
- GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
- }
- return deviceGroupList;
- }
-
- @Override
- public List getGroups(GroupPaginationRequest request, List deviceGroupIds,
- int tenantId) throws GroupManagementDAOException {
- int deviceGroupIdsCount = deviceGroupIds.size();
- if (deviceGroupIdsCount == 0) {
- return new ArrayList<>();
- }
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
- List deviceGroupList = null;
-
- String groupName = request.getGroupName();
- boolean hasGroupName = false;
- String owner = request.getOwner();
- boolean hasOwner = false;
- boolean hasLimit = request.getRowCount() != 0;
-
- try {
- Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
- if (groupName != null && !groupName.isEmpty()) {
- sql += " AND GROUP_NAME LIKE ?";
- hasGroupName = true;
- }
- if (owner != null && !owner.isEmpty()) {
- sql += " AND OWNER LIKE ?";
- hasOwner = true;
- }
- sql += " AND ID IN (";
- for (int i = 0; i < deviceGroupIdsCount; i++) {
- sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
- }
- sql += ")";
- if (hasLimit) {
- sql += " LIMIT ? OFFSET ?";
- }
-
- int paramIndex = 1;
- stmt = conn.prepareStatement(sql);
- stmt.setInt(paramIndex++, tenantId);
- if (hasGroupName) {
- stmt.setString(paramIndex++, groupName + "%");
- }
- if (hasOwner) {
- stmt.setString(paramIndex++, owner + "%");
- }
- for (Integer deviceGroupId : deviceGroupIds) {
- stmt.setInt(paramIndex++, deviceGroupId);
- }
- if (hasLimit) {
- stmt.setInt(paramIndex++, request.getRowCount());
- stmt.setInt(paramIndex, request.getStartIndex());
- }
- resultSet = stmt.executeQuery();
- deviceGroupList = new ArrayList<>();
- while (resultSet.next()) {
- deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
- }
- } catch (SQLException e) {
- throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
- } finally {
- GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
- }
- return deviceGroupList;
- }
-
@Override
public List getDevices(int groupId, int startIndex, int rowCount, int tenantId)
throws GroupManagementDAOException {
@@ -250,4 +138,4 @@ public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
}
return devices;
}
-}
\ No newline at end of file
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/SQLServerGroupDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/SQLServerGroupDAOImpl.java
index 879d450349..5065628b08 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/SQLServerGroupDAOImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/group/SQLServerGroupDAOImpl.java
@@ -14,10 +14,28 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.dao.impl.group;
+import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
@@ -56,7 +74,8 @@ public class SQLServerGroupDAOImpl extends AbstractGroupDAOImpl {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
@@ -69,6 +88,9 @@ public class SQLServerGroupDAOImpl extends AbstractGroupDAOImpl {
sql += " AND STATUS = ?";
hasStatus = true;
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ sql += " AND PARENT_PATH LIKE ?";
+ }
if (hasLimit) {
sql += " ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
}
@@ -85,6 +107,9 @@ public class SQLServerGroupDAOImpl extends AbstractGroupDAOImpl {
if (hasStatus) {
stmt.setString(paramIndex++, status.toUpperCase());
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ stmt.setString(paramIndex++, request.getParentPath());
+ }
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
@@ -121,7 +146,8 @@ public class SQLServerGroupDAOImpl extends AbstractGroupDAOImpl {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
- String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS FROM DM_GROUP WHERE TENANT_ID = ?";
+ String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER, STATUS, PARENT_PATH FROM DM_GROUP "
+ + "WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
@@ -130,6 +156,9 @@ public class SQLServerGroupDAOImpl extends AbstractGroupDAOImpl {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ sql += " AND PARENT_PATH LIKE ?";
+ }
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
@@ -148,6 +177,9 @@ public class SQLServerGroupDAOImpl extends AbstractGroupDAOImpl {
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
+ if (StringUtils.isNotBlank(request.getParentPath())) {
+ stmt.setString(paramIndex++, request.getParentPath());
+ }
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
@@ -210,4 +242,4 @@ public class SQLServerGroupDAOImpl extends AbstractGroupDAOImpl {
}
return devices;
}
-}
\ No newline at end of file
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/GroupManagementDAOUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/GroupManagementDAOUtil.java
index b3acd1d313..3025fb6d0a 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/GroupManagementDAOUtil.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/GroupManagementDAOUtil.java
@@ -14,6 +14,22 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.dao.util;
@@ -86,6 +102,7 @@ public final class GroupManagementDAOUtil {
group.setName(resultSet.getString("GROUP_NAME"));
group.setOwner(resultSet.getString("OWNER"));
group.setStatus(resultSet.getString("STATUS"));
+ group.setParentPath(resultSet.getString("PARENT_PATH"));
return group;
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java
index 533b1cb1bc..7d2ff24875 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/report/mgt/ReportManagementServiceImpl.java
@@ -315,7 +315,7 @@ public class ReportManagementServiceImpl implements ReportManagementService {
}
//Map date blocks and counts
resultObject.addProperty(
- dateFormat.format(endDate) + " - " + dateFormat.format(previousDate), sum);
+ dateFormat.format(previousDate) + " - " + dateFormat.format(endDate), sum);
endDate = previousDate;
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java
index f729218314..c5e7417c86 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderService.java
@@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.service;
@@ -60,10 +77,11 @@ public interface GroupManagementProviderService {
* Delete existing device group.
*
* @param groupId to be deleted.
+ * @param isDeleteChildren to delete the children groups or not.
* @return status of the delete operation.
* @throws GroupManagementException
*/
- boolean deleteGroup(int groupId) throws GroupManagementException;
+ boolean deleteGroup(int groupId, boolean isDeleteChildren) throws GroupManagementException;
/**
* Get the device group provided the device group id.
@@ -75,6 +93,17 @@ public interface GroupManagementProviderService {
*/
DeviceGroup getGroup(int groupId, boolean requireGroupProps) throws GroupManagementException;
+ /**
+ * Get the device group provided the device group id and depth of children groups.
+ *
+ * @param groupId of the group.
+ * @param requireGroupProps to include group properties.
+ * @param depth of children groups to retrieve.
+ * @return {@link DeviceGroup} group with details.
+ * @throws GroupManagementException on error during retrieval of group
+ */
+ DeviceGroup getGroup(int groupId, boolean requireGroupProps, int depth) throws GroupManagementException;
+
/**
* Get the device group provided the device group name.
*
@@ -85,6 +114,17 @@ public interface GroupManagementProviderService {
*/
DeviceGroup getGroup(String groupName, boolean requireGroupProps) throws GroupManagementException;
+ /**
+ * Get the device group provided the device group id and depth of children groups.
+ *
+ * @param groupName of the group.
+ * @param requireGroupProps to include group properties.
+ * @param depth of children groups to retrieve.
+ * @return {@link DeviceGroup} group with details.
+ * @throws GroupManagementException on error during retrieval of group
+ */
+ DeviceGroup getGroup(String groupName, boolean requireGroupProps, int depth) throws GroupManagementException;
+
/**
* Get all device groups in tenant.
*
@@ -127,6 +167,18 @@ public interface GroupManagementProviderService {
PaginationResult getGroups(String username, GroupPaginationRequest paginationRequest, boolean requireGroupProps)
throws GroupManagementException;
+ /**
+ * Get device groups with children groups hierarchically which belongs to specified user with pagination.
+ *
+ * @param username of the user.
+ * @param request to filter results
+ * @param requireGroupProps to include group properties
+ * @return {@link PaginationResult} paginated groups.
+ * @throws GroupManagementException on error during retrieval of groups with hierarchy
+ */
+ PaginationResult getGroupsWithHierarchy(String username, GroupPaginationRequest request,
+ boolean requireGroupProps) throws GroupManagementException;
+
/**
* Get all device group count in tenant
*
@@ -147,10 +199,11 @@ public interface GroupManagementProviderService {
* Get device group count of user
*
* @param username of the user
+ * @param parentPath of the group
* @return group count
* @throws GroupManagementException
*/
- int getGroupCount(String username) throws GroupManagementException;
+ int getGroupCount(String username, String parentPath) throws GroupManagementException;
/**
* Manage device group sharing with user with list of roles.
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java
index b28cbefe25..6a678c1fca 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceImpl.java
@@ -14,10 +14,28 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.service;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
@@ -36,14 +54,12 @@ import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException;
-import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.dao.DeviceDAO;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.GroupDAO;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
-import org.wso2.carbon.device.mgt.core.event.config.EventOperationTaskConfiguration;
import org.wso2.carbon.device.mgt.core.event.config.GroupAssignmentEventOperationExecutor;
import org.wso2.carbon.device.mgt.core.geo.task.GeoFenceEventOperationManager;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
@@ -56,10 +72,11 @@ import org.wso2.carbon.user.api.UserStoreManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
public class GroupManagementProviderServiceImpl implements GroupManagementProviderService {
@@ -95,6 +112,20 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
GroupManagementDAOFactory.beginTransaction();
DeviceGroup existingGroup = this.groupDAO.getGroup(deviceGroup.getName(), tenantId);
if (existingGroup == null) {
+ if (deviceGroup.getParentGroupId() == 0) {
+ deviceGroup.setParentPath(DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
+ } else {
+ DeviceGroup immediateParentGroup = groupDAO.getGroup(deviceGroup.getParentGroupId(), tenantId);
+ if (immediateParentGroup == null) {
+ String msg = "Parent group with group ID '" + deviceGroup.getParentGroupId()
+ + "' does not exist. Hence creating of group '" + deviceGroup.getName()
+ + "' was not success";
+ log.error(msg);
+ throw new GroupManagementException(msg);
+ }
+ String parentPath = DeviceManagerUtil.createParentPath(immediateParentGroup);
+ deviceGroup.setParentPath(parentPath);
+ }
int updatedGroupID = this.groupDAO.addGroup(deviceGroup, tenantId);
if (deviceGroup.getGroupProperties() != null && deviceGroup.getGroupProperties().size() > 0) {
this.groupDAO.addGroupProperties(deviceGroup, updatedGroupID, tenantId);
@@ -146,7 +177,35 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
GroupManagementDAOFactory.beginTransaction();
DeviceGroup existingGroup = this.groupDAO.getGroup(groupId, tenantId);
if (existingGroup != null) {
- this.groupDAO.updateGroup(deviceGroup, groupId, tenantId);
+ List groupsToUpdate = new ArrayList<>();
+ String immediateParentID = StringUtils.substringAfterLast(existingGroup.getParentPath(), DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
+ String parentPath = "";
+ if (deviceGroup.getParentGroupId() == 0) {
+ deviceGroup.setParentPath(DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
+ } else {
+ DeviceGroup immediateParentGroup = groupDAO.getGroup(deviceGroup.getParentGroupId(), tenantId);
+ if (immediateParentGroup == null) {
+ String msg = "Parent group with group ID '" + deviceGroup.getParentGroupId()
+ + "' does not exist. Hence updating of group '" + groupId
+ + "' was not success";
+ log.error(msg);
+ throw new GroupManagementException(msg);
+ }
+ parentPath = DeviceManagerUtil.createParentPath(immediateParentGroup);
+ deviceGroup.setParentPath(parentPath);
+ }
+ deviceGroup.setGroupId(groupId);
+ groupsToUpdate.add(deviceGroup);
+ if (StringUtils.isNotBlank(immediateParentID)) {
+ List childrenGroups = groupDAO.getChildrenGroups(
+ DeviceManagerUtil.createParentPath(existingGroup), tenantId);
+ for (DeviceGroup childrenGroup : childrenGroups) {
+ childrenGroup.setParentPath(childrenGroup.getParentPath()
+ .replace(existingGroup.getParentPath(), parentPath));
+ groupsToUpdate.add(childrenGroup);
+ }
+ }
+ this.groupDAO.updateGroups(groupsToUpdate, tenantId);
if (deviceGroup.getGroupProperties() != null && deviceGroup.getGroupProperties().size() > 0) {
this.groupDAO.updateGroupProperties(deviceGroup, groupId, tenantId);
}
@@ -178,7 +237,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
* {@inheritDoc}
*/
@Override
- public boolean deleteGroup(int groupId) throws GroupManagementException {
+ public boolean deleteGroup(int groupId, boolean isDeleteChildren) throws GroupManagementException {
if (log.isDebugEnabled()) {
log.debug("Delete group: " + groupId);
}
@@ -189,8 +248,37 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
GroupManagementDAOFactory.beginTransaction();
- this.groupDAO.deleteGroup(groupId, tenantId);
- this.groupDAO.deleteAllGroupProperties(groupId, tenantId);
+ List childrenGroups = new ArrayList<>();
+ List groupIdsToDelete = new ArrayList<>();
+ if (deviceGroup.getChildrenGroups() != null && !deviceGroup.getChildrenGroups().isEmpty()) {
+ String parentPath = DeviceManagerUtil.createParentPath(deviceGroup);
+ childrenGroups = groupDAO.getChildrenGroups(parentPath, tenantId);
+ if (isDeleteChildren) {
+ groupIdsToDelete = childrenGroups.stream().map(DeviceGroup::getGroupId)
+ .collect(Collectors.toList());
+ } else {
+ for (DeviceGroup childrenGroup : childrenGroups) {
+ String newParentPath = childrenGroup.getParentPath()
+ .replace(DeviceGroupConstants.HierarchicalGroup.SEPERATOR + deviceGroup.getGroupId(), "");
+ if (StringUtils.isEmpty(newParentPath)) {
+ newParentPath = DeviceGroupConstants.HierarchicalGroup.SEPERATOR;
+ }
+ childrenGroup.setParentPath(newParentPath);
+ }
+ }
+ }
+ if (isDeleteChildren) {
+ groupIdsToDelete.add(groupId);
+ groupDAO.deleteGroupsMapping(groupIdsToDelete, tenantId);
+ groupDAO.deleteGroups(groupIdsToDelete, tenantId);
+ groupDAO.deleteAllGroupsProperties(groupIdsToDelete, tenantId);
+ } else {
+ groupDAO.deleteGroup(groupId, tenantId);
+ groupDAO.deleteAllGroupProperties(groupId, tenantId);
+ if (!childrenGroups.isEmpty()) {
+ groupDAO.updateGroups(childrenGroups, tenantId);
+ }
+ }
GroupManagementDAOFactory.commitTransaction();
if (log.isDebugEnabled()) {
log.debug("DeviceGroup " + deviceGroup.getName() + " removed.");
@@ -219,6 +307,11 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
*/
@Override
public DeviceGroup getGroup(int groupId, boolean requireGroupProps) throws GroupManagementException {
+ return getGroup(groupId, requireGroupProps, 1);
+ }
+
+ @Override
+ public DeviceGroup getGroup(int groupId, boolean requireGroupProps, int depth) throws GroupManagementException {
if (log.isDebugEnabled()) {
log.debug("Get group by id: " + groupId);
}
@@ -227,8 +320,13 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
try {
GroupManagementDAOFactory.openConnection();
deviceGroup = this.groupDAO.getGroup(groupId, tenantId);
- if (requireGroupProps) {
- populateGroupProperties(deviceGroup, tenantId);
+ if (deviceGroup != null) {
+ String parentPath = DeviceManagerUtil.createParentPath(deviceGroup);
+ List childrenGroups = groupDAO.getChildrenGroups(parentPath, tenantId);
+ createGroupWithChildren(deviceGroup, childrenGroups, requireGroupProps, tenantId, depth, 0);
+ if (requireGroupProps) {
+ populateGroupProperties(deviceGroup, tenantId);
+ }
}
return deviceGroup;
} catch (GroupManagementDAOException e) {
@@ -236,11 +334,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
log.error(msg, e);
throw new GroupManagementException(msg, e);
} catch (SQLException e) {
- String msg = "Error occurred while opening a connection to the data source.";
- log.error(msg, e);
- throw new GroupManagementException(msg, e);
- } catch (Exception e) {
- String msg = "Error occurred in getGroup for groupId: " + groupId;
+ String msg = "Error occurred while opening a connection to the data source to retrieve the group '"
+ + groupId + "'";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} finally {
@@ -253,6 +348,11 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
*/
@Override
public DeviceGroup getGroup(String groupName, boolean requireGroupProps) throws GroupManagementException {
+ return getGroup(groupName, requireGroupProps, 1);
+ }
+
+ @Override
+ public DeviceGroup getGroup(String groupName, boolean requireGroupProps, int depth) throws GroupManagementException {
if (groupName == null) {
String msg = "Received empty groupName for getGroup";
log.error(msg);
@@ -266,8 +366,13 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
try {
GroupManagementDAOFactory.openConnection();
deviceGroup = this.groupDAO.getGroup(groupName, tenantId);
- if (requireGroupProps) {
- populateGroupProperties(deviceGroup, tenantId);
+ if (deviceGroup != null) {
+ String parentPath = DeviceManagerUtil.createParentPath(deviceGroup);
+ List childrenGroups = groupDAO.getChildrenGroups(parentPath, tenantId);
+ createGroupWithChildren(deviceGroup, childrenGroups, requireGroupProps, tenantId, depth , 0);
+ if (requireGroupProps) {
+ populateGroupProperties(deviceGroup, tenantId);
+ }
}
return deviceGroup;
} catch (GroupManagementDAOException e) {
@@ -275,11 +380,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
log.error(msg, e);
throw new GroupManagementException(msg, e);
} catch (SQLException e) {
- String msg = "Error occurred while opening a connection to the data source.";
- log.error(msg, e);
- throw new GroupManagementException(msg, e);
- } catch (Exception e) {
- String msg = "Error occurred in getGroup with name " + groupName;
+ String msg = "Error occurred while opening a connection to the data source to retrieve group with name '"
+ + groupName + "'";
log.error(msg, e);
throw new GroupManagementException(msg, e);
} finally {
@@ -296,12 +398,10 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
GroupManagementDAOFactory.openConnection();
- deviceGroups = this.groupDAO.getGroups(tenantId);
- if (requireGroupProps) {
- if (deviceGroups != null && !deviceGroups.isEmpty()) {
- for (DeviceGroup group : deviceGroups) {
- populateGroupProperties(group, tenantId);
- }
+ deviceGroups = groupDAO.getRootGroups(tenantId);
+ for (DeviceGroup deviceGroup : deviceGroups) {
+ if (requireGroupProps) {
+ populateGroupProperties(deviceGroup, tenantId);
}
}
return deviceGroups;
@@ -334,16 +434,15 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
log.debug("Get groups with pagination " + request.toString());
}
request = DeviceManagerUtil.validateGroupListPageSize(request);
- List deviceGroups;
+ List rootGroups;
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
GroupManagementDAOFactory.openConnection();
- deviceGroups = this.groupDAO.getGroups(request, tenantId);
- if (requireGroupProps) {
- if (deviceGroups != null && !deviceGroups.isEmpty()) {
- for (DeviceGroup group : deviceGroups) {
- populateGroupProperties(group, tenantId);
- }
+ request.setParentPath(DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
+ rootGroups = this.groupDAO.getGroups(request, tenantId);
+ for (DeviceGroup rootGroup : rootGroups) {
+ if (requireGroupProps) {
+ populateGroupProperties(rootGroup, tenantId);
}
}
} catch (GroupManagementDAOException e) {
@@ -362,11 +461,68 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
GroupManagementDAOFactory.closeConnection();
}
PaginationResult groupResult = new PaginationResult();
- groupResult.setData(deviceGroups);
+ groupResult.setData(rootGroups);
groupResult.setRecordsTotal(getGroupCount(request));
return groupResult;
}
+ @Override
+ public PaginationResult getGroupsWithHierarchy(String username, GroupPaginationRequest request,
+ boolean requireGroupProps) throws GroupManagementException {
+ if (request == null) {
+ String msg = "Received incomplete data for retrieve groups with hierarchy";
+ log.error(msg);
+ throw new GroupManagementException(msg);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Get groups with hierarchy " + request.toString());
+ }
+ DeviceManagerUtil.validateGroupListPageSize(request);
+ List rootGroups;
+ try {
+ int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
+ request.setParentPath(DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
+ if (StringUtils.isBlank(username)) {
+ GroupManagementDAOFactory.openConnection();
+ rootGroups = groupDAO.getGroups(request, tenantId);
+ } else {
+ List allDeviceGroupIdsOfUser = getGroupIds(username);
+ GroupManagementDAOFactory.openConnection();
+ rootGroups = this.groupDAO.getGroups(request, allDeviceGroupIdsOfUser, tenantId);
+ }
+ String parentPath;
+ List childrenGroups;
+ for (DeviceGroup rootGroup : rootGroups) {
+ parentPath = DeviceManagerUtil.createParentPath(rootGroup);
+ childrenGroups = groupDAO.getChildrenGroups(parentPath, tenantId);
+ createGroupWithChildren(
+ rootGroup, childrenGroups, requireGroupProps, tenantId, request.getDepth(), 0);
+ if (requireGroupProps) {
+ populateGroupProperties(rootGroup, tenantId);
+ }
+ }
+ } catch (GroupManagementDAOException e) {
+ String msg = "Error occurred while retrieving all groups with hierarchy";
+ log.error(msg, e);
+ throw new GroupManagementException(msg, e);
+ } catch (SQLException e) {
+ String msg = "Error occurred while opening a connection to the data source to retrieve all groups "
+ + "with hierarchy";
+ log.error(msg, e);
+ throw new GroupManagementException(msg, e);
+ } finally {
+ GroupManagementDAOFactory.closeConnection();
+ }
+ PaginationResult groupResult = new PaginationResult();
+ groupResult.setData(rootGroups);
+ if (StringUtils.isBlank(username)) {
+ groupResult.setRecordsTotal(getGroupCount(request));
+ } else {
+ groupResult.setRecordsTotal(getGroupCount(username, request.getParentPath()));
+ }
+ return groupResult;
+ }
+
@Override
public List getGroups(String username, boolean requireGroupProps) throws GroupManagementException {
if (username == null || username.isEmpty()) {
@@ -457,16 +613,15 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
}
request = DeviceManagerUtil.validateGroupListPageSize(request);
List allDeviceGroupIdsOfUser = getGroupIds(currentUser);
- List allMatchingGroups;
+ List rootGroups;
try {
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
GroupManagementDAOFactory.openConnection();
- allMatchingGroups = this.groupDAO.getGroups(request, allDeviceGroupIdsOfUser, tenantId);
- if (requireGroupProps) {
- if (allMatchingGroups != null && !allMatchingGroups.isEmpty()) {
- for (DeviceGroup group : allMatchingGroups) {
- populateGroupProperties(group, tenantId);
- }
+ request.setParentPath(DeviceGroupConstants.HierarchicalGroup.SEPERATOR);
+ rootGroups = this.groupDAO.getGroups(request, allDeviceGroupIdsOfUser, tenantId);
+ for (DeviceGroup rootGroup : rootGroups) {
+ if (requireGroupProps) {
+ populateGroupProperties(rootGroup, tenantId);
}
}
} catch (GroupManagementDAOException | SQLException e) {
@@ -481,8 +636,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
GroupManagementDAOFactory.closeConnection();
}
PaginationResult groupResult = new PaginationResult();
- groupResult.setData(allMatchingGroups);
- groupResult.setRecordsTotal(getGroupCount(currentUser));
+ groupResult.setData(rootGroups);
+ groupResult.setRecordsTotal(getGroupCount(currentUser, request.getParentPath()));
return groupResult;
}
@@ -557,7 +712,7 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
* {@inheritDoc}
*/
@Override
- public int getGroupCount(String username) throws GroupManagementException {
+ public int getGroupCount(String username, String parentPath) throws GroupManagementException {
if (username == null || username.isEmpty()) {
String msg = "Received empty user name for getGroupCount";
log.error(msg);
@@ -574,8 +729,8 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
.getUserStoreManager();
String[] roleList = userStoreManager.getRoleListOfUser(username);
GroupManagementDAOFactory.openConnection();
- count = groupDAO.getOwnGroupsCount(username, tenantId);
- count += groupDAO.getGroupsCount(roleList, tenantId);
+ count = groupDAO.getOwnGroupsCount(username, tenantId, parentPath);
+ count += groupDAO.getGroupsCount(roleList, tenantId, parentPath);
return count;
} catch (UserStoreException e) {
String msg = "Error occurred while retrieving role list of user '" + username + "'";
@@ -1131,4 +1286,40 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
}
}
}
+
+ /**
+ * Recursive method to create group with children based on params to provide hierarchical grouping.
+ * @param parentGroup to which children group should be set.
+ * @param childrenGroups which are descendants of parent group.
+ * @param requireGroupProps to include device properties.
+ * @param tenantId of the group.
+ * @param depth of children groups set and when reaches recursive call returns to callee.
+ * @param counter to track the recursive calls and to stop when reaches the depth.
+ * @throws GroupManagementDAOException on error during population of group properties.
+ */
+ private void createGroupWithChildren(DeviceGroup parentGroup, List childrenGroups,
+ boolean requireGroupProps, int tenantId, int depth, int counter) throws GroupManagementDAOException {
+ if (childrenGroups.isEmpty() || depth == counter) {
+ return;
+ }
+ List immediateChildrenGroups = new ArrayList<>();
+ Iterator iterator = childrenGroups.iterator();
+ while (iterator.hasNext()) {
+ DeviceGroup childGroup = iterator.next();
+ int immediateParentID = Integer.parseInt(StringUtils.substringAfterLast(
+ childGroup.getParentPath(), DeviceGroupConstants.HierarchicalGroup.SEPERATOR));
+ if (immediateParentID == parentGroup.getGroupId()) {
+ if (requireGroupProps) {
+ populateGroupProperties(childGroup, tenantId);
+ }
+ immediateChildrenGroups.add(childGroup);
+ iterator.remove();
+ }
+ }
+ parentGroup.setChildrenGroups(immediateChildrenGroups);
+ counter++;
+ for (DeviceGroup nextParentGroup : immediateChildrenGroups) {
+ createGroupWithChildren(nextParentGroup, childrenGroups, requireGroupProps, tenantId, depth, counter);
+ }
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java
index 51ea934890..8a88d53ac0 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java
@@ -70,10 +70,10 @@ import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
+import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
-import org.wso2.carbon.device.mgt.common.permission.mgt.Permission;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.cache.DeviceCacheKey;
@@ -131,8 +131,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
-//import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
-
public final class DeviceManagerUtil {
private static final Log log = LogFactory.getLog(DeviceManagerUtil.class);
@@ -654,18 +652,6 @@ public final class DeviceManagerUtil {
}
}
- public static void initializeAPIResourcePermissionCache() {
- CacheManager manager = getCacheManager();
- if(!isAPIResourcePermissionCacheInitialized) {
- isAPIResourcePermissionCacheInitialized = true;
- if (manager != null) {
- manager.getCache(DeviceManagementConstants.API_RESOURCE_PERMISSION_CACHE);
- } else {
- Caching.getCacheManager().getCache(DeviceManagementConstants.API_RESOURCE_PERMISSION_CACHE);
- }
- }
- }
-
/**
* Enable Geofence caching according to the configurations proviced by cdm-config.xml
*/
@@ -1218,4 +1204,18 @@ public final class DeviceManagerUtil {
}
return text;
}
+
+ /**
+ * Create the parent path that the children groups can have
+ * @param deviceGroup parent group
+ * @return created parent path
+ */
+ public static String createParentPath(DeviceGroup deviceGroup) {
+ if (DeviceGroupConstants.HierarchicalGroup.SEPERATOR.equals(deviceGroup.getParentPath())) {
+ return deviceGroup.getParentPath() + deviceGroup.getGroupId();
+ } else {
+ return deviceGroup.getParentPath() + DeviceGroupConstants.HierarchicalGroup.SEPERATOR
+ + deviceGroup.getGroupId();
+ }
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/MDMAndroidOperationUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/MDMAndroidOperationUtil.java
index 14dbaea9ed..99cacfd950 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/MDMAndroidOperationUtil.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/MDMAndroidOperationUtil.java
@@ -52,6 +52,7 @@ public class MDMAndroidOperationUtil {
enterpriseApplication.setType(application.getType().toString());
enterpriseApplication.setUrl(application.getLocation());
enterpriseApplication.setAppIdentifier(application.getIdentifier());
+ enterpriseApplication.setProperties(application.getProperties());
operation.setPayLoad(enterpriseApplication.toJSON());
break;
case PUBLIC:
@@ -59,6 +60,7 @@ public class MDMAndroidOperationUtil {
new AppStoreApplication();
appStoreApplication.setType(application.getType().toString());
appStoreApplication.setAppIdentifier(application.getIdentifier());
+ appStoreApplication.setProperties(application.getProperties());
operation.setPayLoad(appStoreApplication.toJSON());
break;
case WEBAPP:
@@ -67,6 +69,7 @@ public class MDMAndroidOperationUtil {
webApplication.setUrl(application.getLocation());
webApplication.setName(application.getName());
webApplication.setType(application.getType().toString());
+ webApplication.setProperties(application.getProperties());
operation.setPayLoad(webApplication.toJSON());
break;
default:
@@ -93,6 +96,7 @@ public class MDMAndroidOperationUtil {
new EnterpriseApplication();
enterpriseApplication.setType(application.getType().toString());
enterpriseApplication.setAppIdentifier(application.getIdentifier());
+ enterpriseApplication.setProperties(application.getProperties());
operation.setPayLoad(enterpriseApplication.toJSON());
break;
case PUBLIC:
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceNegativeTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceNegativeTest.java
index fd34165031..ec8004e475 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceNegativeTest.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceNegativeTest.java
@@ -8,6 +8,23 @@
*
* 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.
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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
@@ -103,7 +120,7 @@ public class GroupManagementProviderServiceNegativeTest extends BaseDeviceManage
expectedExceptions = {GroupManagementException.class}, expectedExceptionsMessageRegExp = "Error occurred "
+ "while retrieving group count of user.*")
public void testGetGroupCountWithUserName() throws GroupManagementException {
- groupManagementProviderService.getGroupCount("test");
+ groupManagementProviderService.getGroupCount("test", null);
}
@@ -145,7 +162,7 @@ public class GroupManagementProviderServiceNegativeTest extends BaseDeviceManage
expectedExceptions = {GroupManagementException.class}, expectedExceptionsMessageRegExp = "Received empty "
+ "user name for getGroupCount.*")
public void testGetGroupCountWithUserName2() throws GroupManagementException {
- groupManagementProviderService.getGroupCount(null);
+ groupManagementProviderService.getGroupCount(null, null);
}
@Test(description = "This method tests getGroups method under negative circumstances",
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceTest.java
index 4ffb675fe7..b645eac9a0 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceTest.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/service/GroupManagementProviderServiceTest.java
@@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
+ *
+ *
+ * Copyright (c) 2021, Entgra (pvt) Ltd. (https://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.mgt.core.service;
@@ -119,13 +136,13 @@ public class GroupManagementProviderServiceTest extends BaseDeviceManagementTest
@Test(dependsOnMethods = ("createGroup"))
public void deleteGroup() throws GroupManagementException {
DeviceGroup deviceGroup = groupManagementProviderService.getGroup(TestUtils.createDeviceGroup4().getName(), false);
- Assert.assertTrue(groupManagementProviderService.deleteGroup(deviceGroup.getGroupId()));
+ Assert.assertTrue(groupManagementProviderService.deleteGroup(deviceGroup.getGroupId(), false));
}
@Test(dependsOnMethods = ("createGroup"))
public void deleteGroupNotExists() throws GroupManagementException {
- groupManagementProviderService.deleteGroup(8);
+ groupManagementProviderService.deleteGroup(8, false);
}
@@ -190,7 +207,7 @@ public class GroupManagementProviderServiceTest extends BaseDeviceManagementTest
@Test(dependsOnMethods = ("createGroup"))
public void getGroupCountByUsername(String username) throws GroupManagementException {
- int x = groupManagementProviderService.getGroupCount(username);
+ int x = groupManagementProviderService.getGroupCount(username, null);
Assert.assertNotNull(x);
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/sql/h2.sql b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/sql/h2.sql
index 63af00f07f..2c846cb1af 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/sql/h2.sql
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/resources/sql/h2.sql
@@ -14,6 +14,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
STATUS VARCHAR(50) DEFAULT NULL,
DESCRIPTION TEXT DEFAULT NULL,
OWNER VARCHAR(45) DEFAULT NULL,
+ PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/sql/CreateH2TestDB.sql b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/sql/CreateH2TestDB.sql
index d830a6387e..7238d37790 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/sql/CreateH2TestDB.sql
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/sql/CreateH2TestDB.sql
@@ -18,6 +18,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
DATE_OF_CREATE BIGINT DEFAULT NULL,
DATE_OF_LAST_UPDATE BIGINT DEFAULT NULL,
OWNER VARCHAR(45) DEFAULT NULL,
+ PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java
index 7bf0861f72..70004095f2 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java
@@ -85,7 +85,7 @@ public class InvokerHandler extends HttpServlet {
ProxyResponse proxyResponse = HandlerUtil.execute(postRequest);
if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) {
- proxyResponse = retryRequestWithRefreshedToken(req, resp, postRequest);
+ proxyResponse = HandlerUtil.retryRequestWithRefreshedToken(req, resp, postRequest, apiEndpoint);
if (proxyResponse == null) {
return;
}
@@ -113,15 +113,19 @@ public class InvokerHandler extends HttpServlet {
getRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken());
ProxyResponse proxyResponse = HandlerUtil.execute(getRequest);
if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) {
- proxyResponse = retryRequestWithRefreshedToken(req, resp, getRequest);
+ proxyResponse = HandlerUtil.retryRequestWithRefreshedToken(req, resp, getRequest, apiEndpoint);
if (proxyResponse == null) {
return;
}
}
if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
- log.error("Error occurred while invoking the GET API endpoint.");
- HandlerUtil.handleError(resp, proxyResponse);
- return;
+ if (proxyResponse.getCode() == HttpStatus.SC_UNAUTHORIZED) {
+ proxyResponse = HandlerUtil.retryRequestWithRefreshedToken(req, resp, getRequest, apiEndpoint);
+ } else {
+ log.error("Error occurred while invoking the GET API endpoint.");
+ HandlerUtil.handleError(resp, proxyResponse);
+ return;
+ }
}
HandlerUtil.handleSuccess(resp, proxyResponse);
}
@@ -139,7 +143,7 @@ public class InvokerHandler extends HttpServlet {
headRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken());
ProxyResponse proxyResponse = HandlerUtil.execute(headRequest);
if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) {
- proxyResponse = retryRequestWithRefreshedToken(req, resp, headRequest);
+ proxyResponse = HandlerUtil.retryRequestWithRefreshedToken(req, resp, headRequest, apiEndpoint);
if (proxyResponse == null) {
return;
}
@@ -166,7 +170,7 @@ public class InvokerHandler extends HttpServlet {
ProxyResponse proxyResponse = HandlerUtil.execute(putRequest);
if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) {
- proxyResponse = retryRequestWithRefreshedToken(req, resp, putRequest);
+ proxyResponse = HandlerUtil.retryRequestWithRefreshedToken(req, resp, putRequest, apiEndpoint);
if (proxyResponse == null) {
return;
}
@@ -194,7 +198,7 @@ public class InvokerHandler extends HttpServlet {
deleteRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken());
ProxyResponse proxyResponse = HandlerUtil.execute(deleteRequest);
if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) {
- proxyResponse = retryRequestWithRefreshedToken(req, resp, deleteRequest);
+ proxyResponse = HandlerUtil.retryRequestWithRefreshedToken(req, resp, deleteRequest, apiEndpoint);
if (proxyResponse == null) {
return;
}
@@ -305,7 +309,7 @@ public class InvokerHandler extends HttpServlet {
apiEndpoint = System.getProperty("iot.reporting.webapp.host");
if (StringUtils.isBlank(apiEndpoint)){
log.error("Reporting Endpoint is not defined in the iot-server.sh properly.");
- handleError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ HandlerUtil.handleError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR);
return false;
}
}
@@ -313,20 +317,20 @@ public class InvokerHandler extends HttpServlet {
HttpSession session = req.getSession(false);
if (session == null) {
log.error("Unauthorized, You are not logged in. Please log in to the portal");
- handleError(resp, HttpStatus.SC_UNAUTHORIZED);
+ HandlerUtil.handleError(resp, HttpStatus.SC_UNAUTHORIZED);
return false;
}
authData = (AuthData) session.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY);
if (authData == null) {
log.error("Unauthorized, Access token not found in the current session");
- handleError(resp, HttpStatus.SC_UNAUTHORIZED);
+ HandlerUtil.handleError(resp, HttpStatus.SC_UNAUTHORIZED);
return false;
}
if (req.getMethod() == null) {
log.error("Bad Request, Request method is empty");
- handleError(resp, HttpStatus.SC_BAD_REQUEST);
+ HandlerUtil.handleError(resp, HttpStatus.SC_BAD_REQUEST);
return false;
}
return true;
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java
index b1e34a99da..5acceaabfd 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java
@@ -24,7 +24,7 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import io.entgra.ui.request.interceptor.beans.AuthData;
-import io.entgra.ui.request.interceptor.cache.LoginCacheManager;
+import io.entgra.ui.request.interceptor.cache.LoginCache;
import io.entgra.ui.request.interceptor.cache.OAuthApp;
import io.entgra.ui.request.interceptor.cache.OAuthAppCacheKey;
import io.entgra.ui.request.interceptor.exceptions.LoginException;
@@ -39,7 +39,6 @@ import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HTTP;
import io.entgra.ui.request.interceptor.beans.ProxyResponse;
-import org.json.JSONString;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
@@ -81,10 +80,9 @@ public class LoginHandler extends HttpServlet {
httpSession.setMaxInactiveInterval(sessionTimeOut);
// Check if OAuth app cache exists. If not create a new application.
- LoginCacheManager loginCacheManager = new LoginCacheManager();
- loginCacheManager.initializeCacheManager();
+ LoginCache loginCache = HandlerUtil.getLoginCache(httpSession);
OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(HandlerConstants.PUBLISHER_APPLICATION_NAME, username);
- OAuthApp oAuthApp = loginCacheManager.getOAuthAppCache(oAuthAppCacheKey);
+ OAuthApp oAuthApp = loginCache.getOAuthAppCache(oAuthAppCacheKey);
if (oAuthApp == null) {
HttpPost apiRegEndpoint = new HttpPost(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT);
@@ -112,8 +110,6 @@ public class LoginHandler extends HttpServlet {
clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString();
encodedClientApp = Base64.getEncoder()
.encodeToString((clientId + HandlerConstants.COLON + clientSecret).getBytes());
-
- oAuthAppCacheKey = new OAuthAppCacheKey(HandlerConstants.PUBLISHER_APPLICATION_NAME, username);
oAuthApp = new OAuthApp(
HandlerConstants.PUBLISHER_APPLICATION_NAME,
username,
@@ -121,7 +117,7 @@ public class LoginHandler extends HttpServlet {
clientSecret,
encodedClientApp
);
- loginCacheManager.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp);
+ loginCache.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp);
}
if (getTokenAndPersistInSession(req, resp, clientId, clientSecret, encodedClientApp, scopes)) {
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java
index 6ae4c55ed7..7b93b9cad8 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java
@@ -23,7 +23,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
-import io.entgra.ui.request.interceptor.cache.LoginCacheManager;
+import io.entgra.ui.request.interceptor.cache.LoginCache;
import io.entgra.ui.request.interceptor.cache.OAuthApp;
import io.entgra.ui.request.interceptor.cache.OAuthAppCacheKey;
import io.entgra.ui.request.interceptor.util.HandlerConstants;
@@ -81,9 +81,9 @@ public class SsoLoginHandler extends HttpServlet {
private JsonObject uiConfigJsonObject;
private HttpSession httpSession;
-
- private LoginCacheManager loginCacheManager;
+ private LoginCache loginCache;
private OAuthApp oAuthApp;
+ private OAuthAppCacheKey oAuthAppCacheKey;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
@@ -99,13 +99,23 @@ public class SsoLoginHandler extends HttpServlet {
baseContextPath = req.getContextPath();
applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler"));
- // Check if oauth app cache is available
- loginCacheManager = new LoginCacheManager();
- loginCacheManager.initializeCacheManager();
- oAuthApp = loginCacheManager.getOAuthAppCache(
- new OAuthAppCacheKey(applicationName, adminUsername)
- );
+ String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR);
+ if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) {
+ iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR);
+ }
+ gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
+ + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
+ iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
+ + HandlerConstants.COLON + iotsCorePort;
+
+ // Fetch ui config and persists in session
+ String uiConfigUrl = iotsCoreUrl + HandlerConstants.UI_CONFIG_ENDPOINT;
+ uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp);
+ // Retrieving login cache and do a DCR if the cache is not available.
+ loginCache = HandlerUtil.getLoginCache(httpSession);
+ oAuthAppCacheKey = new OAuthAppCacheKey(applicationName, adminUsername);
+ oAuthApp = loginCache.getOAuthAppCache(oAuthAppCacheKey);
if (oAuthApp == null) {
dynamicClientRegistration(req, resp);
}
@@ -143,19 +153,6 @@ public class SsoLoginHandler extends HttpServlet {
*/
private void dynamicClientRegistration(HttpServletRequest req, HttpServletResponse resp) {
try {
- String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR);
-
- if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) {
- iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR);
- }
-
- gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
- + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
- iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
- + HandlerConstants.COLON + iotsCorePort;
- String uiConfigUrl = iotsCoreUrl + HandlerConstants.UI_CONFIG_ENDPOINT;
-
- uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp);
JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray();
JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray();
sessionTimeOut = Integer.parseInt(String.valueOf(uiConfigJsonObject.get("sessionTimeOut")));
@@ -191,9 +188,8 @@ public class SsoLoginHandler extends HttpServlet {
}
// cache the oauth app credentials
- OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(applicationName, adminUsername);
oAuthApp = new OAuthApp(applicationName, adminUsername, clientId, clientSecret, encodedClientApp);
- loginCacheManager.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp);
+ loginCache.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp);
}
// Get the details of the registered application
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java
index c545567ed8..ef334b8940 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/UserHandler.java
@@ -85,9 +85,13 @@ public class UserHandler extends HttpServlet {
ProxyResponse tokenStatus = HandlerUtil.execute(tokenEndpoint);
if (tokenStatus.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
- log.error("Error occurred while invoking the API to get token status.");
- HandlerUtil.handleError(resp, tokenStatus);
- return;
+ if (tokenStatus.getCode() == HttpStatus.SC_UNAUTHORIZED) {
+ tokenStatus = HandlerUtil.retryRequestWithRefreshedToken(req, resp, tokenEndpoint, serverUrl);
+ } else {
+ log.error("Error occurred while invoking the API to get token status.");
+ HandlerUtil.handleError(resp, tokenStatus);
+ return;
+ }
}
String tokenData = tokenStatus.getData();
if (tokenData == null) {
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCacheManager.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCache.java
similarity index 67%
rename from components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCacheManager.java
rename to components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCache.java
index 3ecd741350..06ca1cef6b 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCacheManager.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/cache/LoginCache.java
@@ -18,25 +18,19 @@
package io.entgra.ui.request.interceptor.cache;
-import io.entgra.ui.request.interceptor.util.HandlerConstants;
-
-import javax.cache.Cache;
-import javax.cache.CacheManager;
-import javax.cache.Caching;
+import java.util.LinkedHashMap;
/**
* Contains necessary functions to manage oAuth app cache during login handling
*/
-public class LoginCacheManager {
+public class LoginCache {
- private CacheManager cacheManager = null;
- private Cache cache = null;
+ private final LinkedHashMap cache;
+ private final int capacity;
- /**
- * Initialize the cache manager if it is not already initialized
- */
- public void initializeCacheManager() {
- cacheManager = Caching.getCacheManagerFactory().getCacheManager(HandlerConstants.LOGIN_CACHE);
+ public LoginCache(int capacity) {
+ this.capacity = capacity;
+ this.cache = new LinkedHashMap<>(capacity);
}
/**
@@ -46,7 +40,9 @@ public class LoginCacheManager {
* @param oAuthApp - The value of the cache which contains OAuth app data
*/
public void addOAuthAppToCache(OAuthAppCacheKey oAuthAppCacheKey, OAuthApp oAuthApp) {
- cache = cacheManager.getCache(HandlerConstants.LOGIN_CACHE);
+ if (cache.size() == capacity) {
+ cache.remove(cache.entrySet().iterator().next().getKey());
+ }
cache.put(oAuthAppCacheKey, oAuthApp);
}
@@ -57,7 +53,13 @@ public class LoginCacheManager {
* @return - Returns OAuthApp object
*/
public OAuthApp getOAuthAppCache(OAuthAppCacheKey oAuthAppCacheKey) {
- cache = cacheManager.getCache(HandlerConstants.LOGIN_CACHE);
- return cache.get(oAuthAppCacheKey);
+ OAuthApp oAuthApp = cache.get(oAuthAppCacheKey);
+ if (oAuthApp != null) {
+ if (cache.size() == capacity) {
+ cache.remove(oAuthAppCacheKey);
+ cache.put(oAuthAppCacheKey, oAuthApp);
+ }
+ }
+ return oAuthApp;
}
}
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java
index 4c864c81e5..f2303aba47 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java
@@ -55,7 +55,7 @@ public class HandlerConstants {
public static final String PASSWORD_GRANT_TYPE = "password";
public static final String JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
public static final String PRODUCTION_KEY = "PRODUCTION";
- public static final String LOGIN_CACHE = "LOGIN_CACHE";
+ public static final String LOGIN_CACHE_CAPACITY_KEY = "loginCacheCapacity";
public static final String SCHEME_SEPARATOR = "://";
public static final String COLON = ":";
diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java
index 5acec832ce..ab702eb9ad 100644
--- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java
+++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerUtil.java
@@ -23,13 +23,17 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import io.entgra.ui.request.interceptor.beans.AuthData;
+import io.entgra.ui.request.interceptor.cache.LoginCache;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Consts;
+import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.ContentType;
@@ -60,6 +64,9 @@ import java.io.StringWriter;
public class HandlerUtil {
private static final Log log = LogFactory.getLog(HandlerUtil.class);
+ private static LoginCache loginCache = null;
+ private static boolean isLoginCacheInitialized = false;
+ private static AuthData authData;
/***
*
@@ -166,9 +173,11 @@ public class HandlerUtil {
/***
+ * Handle error requests.
*
* @param resp {@link HttpServletResponse}
- * Return Error Response.
+ * @param proxyResponse {@link ProxyResponse}
+ * @throws IOException If error occurred when trying to send the error response.
*/
public static void handleError(HttpServletResponse resp, ProxyResponse proxyResponse) throws IOException {
Gson gson = new Gson();
@@ -188,6 +197,22 @@ public class HandlerUtil {
}
}
+ /**
+ * Handle error requests with custom error codes.
+ *
+ * @param resp {@link HttpServletResponse}
+ * @param errorCode HTTP error status code
+ * @throws IOException If error occurred when trying to send the error response.
+ */
+ public static void handleError(HttpServletResponse resp, int errorCode)
+ throws IOException {
+ ProxyResponse proxyResponse = new ProxyResponse();
+ proxyResponse.setCode(errorCode);
+ proxyResponse.setExecutorResponse(
+ HandlerConstants.EXECUTOR_EXCEPTION_PREFIX + HandlerUtil.getStatusKey(errorCode));
+ HandlerUtil.handleError(resp, proxyResponse);
+ }
+
/***
*
* @param resp {@link HttpServletResponse}
@@ -400,4 +425,136 @@ public class HandlerUtil {
return stringOutput;
}
+
+ /***
+ * Search a key from a given json string object.
+ *
+ * @param jsonObjectString - json object in string format.
+ * @param key - the key to be searched.
+ * @return string value of the key value.
+ */
+ private static String searchFromJsonObjectString(String jsonObjectString, String key) {
+ JsonParser jsonParser = new JsonParser();
+ JsonElement jsonElement = jsonParser.parse(jsonObjectString);
+ JsonObject jsonObject = jsonElement.getAsJsonObject();
+ return jsonObject.get(key).getAsString();
+ }
+
+ /***
+ * Initializes the login cache.
+ *
+ * @param httpSession - current active HttpSession.
+ */
+ private static void initializeLoginCache(HttpSession httpSession) {
+ String uiConfig = httpSession.getAttribute(HandlerConstants.UI_CONFIG_KEY).toString();
+ int capacity = Integer.parseInt(searchFromJsonObjectString(uiConfig, HandlerConstants.LOGIN_CACHE_CAPACITY_KEY));
+ loginCache = new LoginCache(capacity);
+ }
+
+ /***
+ * Retrieves login cache and initializes if its not done already.
+ *
+ * @param httpSession - current active HttpSession.
+ */
+ public static LoginCache getLoginCache(HttpSession httpSession) {
+ if (!isLoginCacheInitialized || loginCache == null) {
+ isLoginCacheInitialized = true;
+ initializeLoginCache(httpSession);
+ }
+ return loginCache;
+ }
+
+ /**
+ * Retry request again after refreshing the access token
+ *
+ * @param req incoming {@link HttpServletRequest}
+ * @param resp resp {@link HttpServletResponse}
+ * @param httpRequest subclass of {@link HttpRequestBase} related to the current request.
+ * @return {@link ProxyResponse} if successful and null
if failed.
+ * @throws IOException If an error occurs when try to retry the request.
+ */
+ public static ProxyResponse retryRequestWithRefreshedToken(HttpServletRequest req, HttpServletResponse resp,
+ HttpRequestBase httpRequest, String apiEndpoint) throws IOException {
+ if (refreshToken(req, resp, apiEndpoint)) {
+ HttpSession session = req.getSession(false);
+ if (session == null) {
+ log.error("Unauthorized, You are not logged in. Please log in to the portal");
+ handleError(resp, HttpStatus.SC_UNAUTHORIZED);
+ return null;
+ }
+ httpRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken());
+ ProxyResponse proxyResponse = HandlerUtil.execute(httpRequest);
+ if (proxyResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
+ log.error("Error occurred while invoking the API after refreshing the token.");
+ HandlerUtil.handleError(resp, proxyResponse);
+ return null;
+ }
+ return proxyResponse;
+ }
+ return null;
+ }
+
+ /***
+ * This method is responsible to get the refresh token
+ *
+ * @param req {@link HttpServletRequest}
+ * @param resp {@link HttpServletResponse}
+ * @return If successfully renew tokens, returns TRUE otherwise return FALSE
+ * @throws IOException If an error occurs while witting error response to client side or invoke token renewal API
+ */
+ private static boolean refreshToken(HttpServletRequest req, HttpServletResponse resp, String gatewayUrl)
+ throws IOException {
+ if (log.isDebugEnabled()) {
+ log.debug("refreshing the token");
+ }
+ HttpPost tokenEndpoint = new HttpPost(
+ gatewayUrl + HandlerConstants.TOKEN_ENDPOINT);
+ HttpSession session = req.getSession(false);
+ if (session == null) {
+ log.error("Couldn't find a session, hence it is required to login and proceed.");
+ handleError(resp, HttpStatus.SC_UNAUTHORIZED);
+ return false;
+ }
+
+ authData = (AuthData) session.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY);
+ StringEntity tokenEndpointPayload = new StringEntity(
+ "grant_type=refresh_token&refresh_token=" + authData.getRefreshToken() + "&scope=PRODUCTION",
+ ContentType.APPLICATION_FORM_URLENCODED);
+
+ tokenEndpoint.setEntity(tokenEndpointPayload);
+ String encodedClientApp = authData.getEncodedClientApp();
+ tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC +
+ encodedClientApp);
+ tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
+
+ ProxyResponse tokenResultResponse = HandlerUtil.execute(tokenEndpoint);
+ if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
+ log.error("Error occurred while refreshing access token.");
+ HandlerUtil.handleError(resp, tokenResultResponse);
+ return false;
+ }
+
+ JsonParser jsonParser = new JsonParser();
+ JsonElement jTokenResult = jsonParser.parse(tokenResultResponse.getData());
+
+ if (jTokenResult.isJsonObject()) {
+ JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject();
+ AuthData newAuthData = new AuthData();
+
+ newAuthData.setAccessToken(jTokenResultAsJsonObject.get("access_token").getAsString());
+ newAuthData.setRefreshToken(jTokenResultAsJsonObject.get("refresh_token").getAsString());
+ newAuthData.setScope(jTokenResultAsJsonObject.get("scope").getAsString());
+ newAuthData.setClientId(authData.getClientId());
+ newAuthData.setClientSecret(authData.getClientSecret());
+ newAuthData.setEncodedClientApp(authData.getEncodedClientApp());
+ newAuthData.setUsername(authData.getUsername());
+ authData = newAuthData;
+ session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, newAuthData);
+ return true;
+ }
+
+ log.error("Error Occurred in token renewal process.");
+ handleError(resp, HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ return false;
+ }
}
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml
index 36fe025034..aa3f169a33 100644
--- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml
@@ -22,6 +22,8 @@
true
3600
+
+ 10000
application_management
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql
index bda86bc93b..f6894eb4ac 100644
--- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql
@@ -23,6 +23,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
STATUS VARCHAR(50) DEFAULT NULL,
DESCRIPTION TEXT DEFAULT NULL,
OWNER VARCHAR(255) DEFAULT NULL,
+ PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql
index 247d796c52..c27f891445 100644
--- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql
@@ -32,6 +32,7 @@ IF NOT EXISTS(SELECT *
STATUS VARCHAR(50) DEFAULT NULL,
DESCRIPTION VARCHAR(MAX) DEFAULT NULL,
OWNER VARCHAR(255) DEFAULT NULL,
+ PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
);
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql
index cc9e8f1273..a69b79b783 100644
--- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql
@@ -27,6 +27,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
STATUS VARCHAR(50) DEFAULT NULL,
DESCRIPTION TEXT DEFAULT NULL,
OWNER VARCHAR(255) DEFAULT NULL,
+ PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
)
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql
index 007a7008f0..e2e4693bd2 100644
--- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql
@@ -50,6 +50,7 @@ CREATE TABLE DM_GROUP (
GROUP_NAME VARCHAR2(100) DEFAULT NULL,
STATUS VARCHAR2(50) DEFAULT NULL,
OWNER VARCHAR2(255) DEFAULT NULL,
+ PARENT_PATH VARCHAR2(255) DEFAULT NULL,
TENANT_ID NUMBER(10) DEFAULT 0,
CONSTRAINT PK_DM_GROUP PRIMARY KEY (ID)
)
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql
index db431497e8..bd8eb8771a 100644
--- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql
@@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP (
GROUP_NAME VARCHAR(100) DEFAULT NULL,
DESCRIPTION TEXT DEFAULT NULL,
OWNER VARCHAR(45) DEFAULT NULL,
+ PARENT_PATH VARCHAR(255) DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID)
)
@@ -732,4 +733,4 @@ CREATE TABLE IF NOT EXISTS DM_GEOFENCE (
PRIMARY KEY (ID)
);
--- END OF DM_GEOFENCE TABLE--
\ No newline at end of file
+-- END OF DM_GEOFENCE TABLE--