Merge pull request 'Add new get device activities API' (#246) from Sasini_Sandamali/device-mgt-core-forked:master into master

Reviewed-on: community/device-mgt-core#246
scope-fixes
Inosh Perara 1 year ago
commit 24d79b72cb

@ -0,0 +1,51 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.Gson;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;
import java.util.List;
@ApiModel(value = "ListOfDeviceActivities", description = "This contains a set of device activities that " +
"matches a given"
+ " criteria as a collection")
public class DeviceActivityList extends BasePaginatedResult {
private List<DeviceActivity> activities;
@ApiModelProperty(value = "List of device activity Ids")
@JsonProperty("activities")
public List<DeviceActivity> getList() {
return activities;
}
public void setList(List<DeviceActivity> activities) {
this.activities = activities;
}
@Override
public String toString() {
return new Gson().toJson(this);
}
}

@ -385,6 +385,131 @@ public interface ActivityInfoProviderService {
defaultValue = "5")
@QueryParam("limit") int limit);
@GET
@Path("/devices")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Device Activity Details",
notes = "Get the details of the operations/activities executed by the server on the devices registered" +
" with WSO2 EMM, during a defined time period.",
tags = "Device Activity Info Provider",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:get-activity")
})
},
nickname = "getDeviceActivitiesWithFilters"
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the device activity details.",
response = ActivityList.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 was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 304,
message = "Not Modified. \n Empty body because the client already has the latest version of the" +
" requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 404,
message = "Not Found. \n No activities found.",
response = ErrorResponse.class),
@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 activity data.",
response = ErrorResponse.class)
})
Response getDeviceActivities(
@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 activity details you require from the starting pagination index/offset.",
defaultValue = "5")
@DefaultValue("20") @QueryParam("limit") int limit,
@ApiParam(
name = "since",
value = "Checks if the requested variant was created since the specified date-time.\n" +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200"
)
@QueryParam("since") String since,
@ApiParam(
name = "initiatedBy",
value = "The user, who initiated the operation. If is done by the task, the SYSTEM will be returned." +
" And if a user adds the operation, username is returned"
)
@QueryParam("initiatedBy") String initiatedBy,
@ApiParam(
name = "operationCode",
value = "Operation Code to filter"
)
@QueryParam("operationCode") String operationCode,
@ApiParam(
name = "operationId",
value = "Operation Id to filter"
)
@QueryParam("operationId") int operationId,
@ApiParam(
name = "deviceType",
value = "Device Type to filter"
)
@QueryParam("deviceType") String deviceType,
@ApiParam(
name = "deviceId",
value = "Device Id to filter"
)
@QueryParam("deviceId") List<String> deviceIds,
@ApiParam(
name = "type",
value = "Operation type to filter"
)
@QueryParam("type") String type,
@ApiParam(
name = "status",
value = "Operation response status to filter"
)
@QueryParam("status") String status,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time\n." +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z\n." +
"Example: Mon, 05 Jan 2014 15:10:00 +0200"
)
@HeaderParam("If-Modified-Since") String ifModifiedSince,
@ApiParam(
name = "startTimestamp",
value = "Starting unix timestamp value for filtering activities"
)
@QueryParam("startTimestamp") long startTimestamp,
@ApiParam(
name = "endTimestamp",
value = "Ending unix timestamp value for filtering activities"
)
@QueryParam("endTimestamp") long endTimestamp);
@GET
@ApiOperation(
produces = MediaType.APPLICATION_JSON,

@ -29,6 +29,7 @@ import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Operation;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationManagementException;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ActivityList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.DeviceActivityList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorResponse;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.common.ActivityIdList;
import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.api.ActivityInfoProviderService;
@ -246,6 +247,130 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService
}
}
@GET
@Path("/devices")
@Override
public Response getDeviceActivities(@DefaultValue("0") @QueryParam("offset") int offset,
@DefaultValue("20") @QueryParam("limit") int limit,
@QueryParam("since") String since,
@QueryParam("initiatedBy") String initiatedBy,
@QueryParam("operationCode") String operationCode,
@QueryParam("operationId") int operationId,
@QueryParam("deviceType") String deviceType,
@QueryParam("deviceId") List<String> deviceIds,
@QueryParam("type") String type,
@QueryParam("status") String status,
@HeaderParam("If-Modified-Since") String ifModifiedSince,
@QueryParam("startTimestamp") long startTimestamp,
@QueryParam("endTimestamp") long endTimestamp) {
long ifModifiedSinceTimestamp;
long sinceTimestamp;
long timestamp = 0;
boolean isTimeDurationProvided = false;
if (log.isDebugEnabled()) {
log.debug("getDeviceActivities since: " + since + " , offset: " + offset + " ,limit: " + limit + " ," +
"ifModifiedSince: " + ifModifiedSince);
}
RequestValidationUtil.validatePaginationParameters(offset, limit);
if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
Date ifSinceDate;
SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
try {
ifSinceDate = format.parse(ifModifiedSince);
} catch (ParseException e) {
return Response.status(400).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(
"Invalid date string is provided in 'If-Modified-Since' header").build()).build();
}
ifModifiedSinceTimestamp = ifSinceDate.getTime();
timestamp = ifModifiedSinceTimestamp / 1000;
} else if (since != null && !since.isEmpty()) {
Date sinceDate;
SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
try {
sinceDate = format.parse(since);
} catch (ParseException e) {
return Response.status(400).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(
"Invalid date string is provided in 'since' filter").build()).build();
}
sinceTimestamp = sinceDate.getTime();
timestamp = sinceTimestamp / 1000;
} else if (startTimestamp > 0 && endTimestamp > 0) {
RequestValidationUtil.validateTimeDuration(startTimestamp, endTimestamp);
isTimeDurationProvided = true;
}
if (timestamp == 0 && !isTimeDurationProvided) {
//If timestamp is not sent by the user, a default value is set, that is equal to current time-12 hours.
long time = System.currentTimeMillis() / 1000;
timestamp = time - 42300;
}
if (log.isDebugEnabled()) {
log.debug("getDeviceActivities final timestamp " + timestamp);
}
DeviceActivityList deviceActivityList = new DeviceActivityList();
DeviceManagementProviderService dmService;
ActivityPaginationRequest activityPaginationRequest = new ActivityPaginationRequest(offset, limit);
try {
if (log.isDebugEnabled()) {
log.debug("Calling database to get device activities.");
}
dmService = DeviceMgtAPIUtils.getDeviceManagementService();
if (initiatedBy != null && !initiatedBy.isEmpty()) {
activityPaginationRequest.setInitiatedBy(initiatedBy);
}
if (operationCode != null && !operationCode.isEmpty()) {
activityPaginationRequest.setOperationCode(operationCode);
}
if (operationId > 0) {
activityPaginationRequest.setOperationId(operationId);
}
if (deviceType != null && !deviceType.isEmpty()) {
activityPaginationRequest.setDeviceType(deviceType);
}
if (deviceIds != null && !deviceIds.isEmpty()) {
activityPaginationRequest.setDeviceIds(deviceIds);
}
if (type != null && !type.isEmpty()) {
activityPaginationRequest.setType(Operation.Type.valueOf(type.toUpperCase()));
}
if (status != null && !status.isEmpty()) {
activityPaginationRequest.setStatus(Operation.Status.valueOf(status.toUpperCase()));
}
if (timestamp > 0) {
activityPaginationRequest.setSince(timestamp);
} else {
activityPaginationRequest.setStartTimestamp(startTimestamp);
activityPaginationRequest.setEndTimestamp(endTimestamp);
}
if (log.isDebugEnabled()) {
log.debug("Device Activity request: " + new Gson().toJson(activityPaginationRequest));
}
int count = dmService.getDeviceActivitiesCount(activityPaginationRequest);
if (log.isDebugEnabled()) {
log.debug("Filtered Device Activity count: " + count);
}
if (count > 0) {
deviceActivityList.setList(dmService.getDeviceActivities(activityPaginationRequest));
if (log.isDebugEnabled()) {
log.debug("Fetched Device Activity count: " + deviceActivityList.getList().size());
}
} else if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
return Response.notModified().build();
}
deviceActivityList.setCount(count);
return Response.ok().entity(deviceActivityList).build();
} catch (OperationManagementException e) {
String msg
= "ErrorResponse occurred while fetching the device activities updated after given time stamp.";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}
@GET
@Override
public Response getActivities(@DefaultValue("0") @QueryParam("offset") int offset,
@ -306,8 +431,6 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService
if (log.isDebugEnabled()) {
log.debug("getActivities final timestamp " + timestamp);
}
Response response = validateAdminPermission();
if (response == null) {
ActivityList activityList = new ActivityList();
DeviceManagementProviderService dmService;
ActivityPaginationRequest activityPaginationRequest = new ActivityPaginationRequest(offset, limit);
@ -367,9 +490,6 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
} else {
return response;
}
}
private Response validateAdminPermission() {

@ -34,6 +34,9 @@ import org.wso2.carbon.context.PrivilegedCarbonContext;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import io.entgra.device.mgt.core.device.mgt.common.ActivityPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Operation;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationManagementException;
import io.entgra.device.mgt.core.device.mgt.core.authorization.DeviceAccessAuthorizationServiceImpl;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
@ -47,6 +50,7 @@ import io.entgra.device.mgt.core.policy.mgt.core.util.PolicyManagerUtil;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.mockito.MockitoAnnotations.initMocks;
@ -63,6 +67,12 @@ public class ActivityProviderServiceImplTest {
private static final Log log = LogFactory.getLog(ActivityProviderServiceImplTest.class);
private static final String TEST_ACTIVITY_ID = "ACTIVITY_1";
private static final String IF_MODIFIED_SINCE = "01Aug2018";
private static final String SINCE = "Fri, 06 Oct 2023 15:30:00 GMT";
private static final String DEVICE_TYPE_2 = "power-meter";
private static final Operation.Status STATUS = Operation.Status.NOTNOW;
private static final Operation.Type TYPE = Operation.Type.PROFILE;
private static final String INITIATED_BY = "admin";
private static final int OPERATION_ID = 158572;
private static final String DEVICE_TYPE = "android";
private static final String DEVICE_ID = "1234567";
private static final String OPERATION_CODE = "111222";
@ -71,7 +81,10 @@ public class ActivityProviderServiceImplTest {
private static final String TEST_ACTIVITY_ID_LIST = "ACTIVITY_1,ACTIVITY_2";
private static final List<String> idList = new ArrayList();
private static final List<Activity> activities = new ArrayList<>();
private static final List<DeviceActivity> deviceActivities = new ArrayList<>();
private static final ActivityIdList activityList = new ActivityIdList(TEST_ACTIVITY_ID_LIST);
private static final ActivityPaginationRequest activityPaginationRequest = new ActivityPaginationRequest(LIMIT,OFFSET);
private static final ActivityIdList activityListEmpty = new ActivityIdList("");
private List<String> idList1;
@ -108,6 +121,23 @@ public class ActivityProviderServiceImplTest {
activity2.setActivityId("ACTIVITY_2");
activities.add(activity1);
activities.add(activity2);
DeviceActivity deviceActivity1 = new DeviceActivity();
DeviceActivity deviceActivity2 = new DeviceActivity();
deviceActivity1.setActivityId("ACTIVITY_3");
deviceActivity2.setActivityId("ACTIVITY_4");
deviceActivities.add(deviceActivity1);
deviceActivities.add(deviceActivity2);
activityPaginationRequest.setDeviceIds(Collections.singletonList(DEVICE_ID));
activityPaginationRequest.setOperationCode(OPERATION_CODE);
activityPaginationRequest.setDeviceType(DEVICE_TYPE_2);
activityPaginationRequest.setOperationId(OPERATION_ID);
activityPaginationRequest.setInitiatedBy(INITIATED_BY);
activityPaginationRequest.setStatus(STATUS);
activityPaginationRequest.setType(TYPE);
activityPaginationRequest.setStartTimestamp(0);
activityPaginationRequest.setEndTimestamp(0);
activityPaginationRequest.setLimit(LIMIT);
activityPaginationRequest.setOffset(OFFSET);
}
@Test(description =
@ -186,6 +216,70 @@ public class ActivityProviderServiceImplTest {
Mockito.reset(this.deviceManagementProviderService);
}
@Test(description = "This method tests trying to get details activity IDs when call with data")
public void testGetActivitiesWithActivityPaginationRequest() throws OperationManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isAdmin")).toReturn(true);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getActivitiesCount(Mockito.any())).thenReturn(2);
Mockito.when(this.deviceManagementProviderService.getActivities(Mockito.any())).thenReturn(activities);
Response response = this.activityInfoProviderService.getActivities(
OFFSET, LIMIT, SINCE, INITIATED_BY, OPERATION_CODE, OPERATION_ID,
DEVICE_TYPE_2, Collections.singletonList(DEVICE_ID), TYPE.toString(), STATUS.toString(), null, 0, 0);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
Assert.assertNotNull(response);
Mockito.reset(this.deviceManagementProviderService);
}
@Test(description = "This method tests trying to get details device activity IDs when call with empty data")
public void testGetActivitiesWithEmptyActivityPaginationRequest() throws OperationManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isAdmin")).toReturn(true);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.activityInfoProviderService.getActivities(
OFFSET, 0, null, null, null, 0,
null, null, null, null, null, 0, 0);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
Assert.assertEquals(response.getEntity().toString(), "{\"count\":0}");
Mockito.reset(this.deviceManagementProviderService);
}
@Test(description = "This method tests trying to get details device activity IDs when call with data")
public void testGetDeviceActivitiesWithActivityPaginationRequest() throws OperationManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isAdmin")).toReturn(true);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDeviceActivitiesCount(Mockito.any())).thenReturn(2);
Mockito.when(this.deviceManagementProviderService.getDeviceActivities(Mockito.any())).thenReturn(deviceActivities);
Response response = this.activityInfoProviderService.getDeviceActivities(
OFFSET, LIMIT, SINCE, INITIATED_BY, OPERATION_CODE, OPERATION_ID,
DEVICE_TYPE_2, Collections.singletonList(DEVICE_ID), TYPE.toString(), STATUS.toString(), null, 0, 0);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
Assert.assertNotNull(response);
Mockito.reset(this.deviceManagementProviderService);
}
@Test(description = "This method tests trying to get details activity IDs when call with empty data")
public void testGetDeviceActivitiesWithEmptyActivityPaginationRequest() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isAdmin")).toReturn(true);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.activityInfoProviderService.getDeviceActivities(
OFFSET, 0, null, null, null, 0,
null, null, null, null, null, 0, 0);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
Assert.assertEquals(response.getEntity().toString(), "{\"count\":0}");
Mockito.reset(this.deviceManagementProviderService);
}
@Test(description = "This method tests trying to get details of a list activity IDs which does not exists")
public void testGetActivitiesWithNonExistingActivityIdList() throws OperationManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isAdmin")).toReturn(true);

@ -0,0 +1,205 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.common.operation.mgt;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import java.util.List;
@ApiModel(value = "DeviceActivity", description = "An activity instance carries a unique identifier that can be " +
"used to identify a particular operation instance uniquely")
public class DeviceActivity {
public enum Type {
CONFIG, MESSAGE, INFO, COMMAND, PROFILE, POLICY
}
public enum Status {
IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED, INVALID, UNAUTHORIZED, NOTNOW, REQUIRED_CONFIRMATION, CONFIRMED
}
@ApiModelProperty(
name = "activityId",
value = "Device Activity identifier",
required = true,
example = "ACTIVITY_1")
@JsonProperty("activityId")
private String activityId;
@ApiModelProperty(
name = "code",
value = "Device Activity code",
required = true,
example = "DEVICE_RING")
@JsonProperty("code")
private String code;
@ApiModelProperty(
name = "operationId",
value = "Operation Id",
required = false,
example = "10")
@JsonProperty("operationId")
private int operationId;
@ApiModelProperty(
name = "type",
value = "Activity type",
required = true,
allowableValues = "CONFIG, MESSAGE, INFO, COMMAND, PROFILE, POLICY",
example = "COMMAND")
@JsonProperty("type")
private Type type;
@ApiModelProperty(
name = "status",
value = "Status of the device activity performed.",
required = true,
example = "PENDING")
@JsonProperty("status")
private Status status;
@ApiModelProperty(
name = "createdTimeStamp",
value = "Timestamp recorded when the activity took place",
required = true,
example = "Thu Oct 06 11:18:47 IST 2016")
@JsonProperty("createdTimestamp")
private String createdTimeStamp;
@ApiModelProperty(
name = "deviceActivities",
value = "Collection of devices activities corresponding to the activity",
required = true)
@JsonProperty("deviceActivities")
private List<DeviceActivity> deviceActivities;
@ApiModelProperty(
name = "initiatedBy",
value = "Initiated user",
required = true)
@JsonProperty("initiatedBy")
private String initiatedBy;
@ApiModelProperty(
name = "deviceIdentifier",
value = "Device identifier of the device.",
required = true)
@JsonProperty("deviceIdentifier")
private DeviceIdentifier deviceIdentifier;
@ApiModelProperty(
name = "responses",
value = "Responses received from devices.",
required = true)
@JsonProperty("responses")
private List<OperationResponse> responses;
@ApiModelProperty(
name = "updatedTimestamp ",
value = "Last updated time of the activity.",
required = true,
example = "Thu Oct 06 11:18:47 IST 2016")
@JsonProperty("updatedTimestamp")
private String updatedTimestamp;
public DeviceIdentifier getDeviceIdentifier() {
return deviceIdentifier;
}
public void setDeviceIdentifier(DeviceIdentifier deviceIdentifier) {
this.deviceIdentifier = deviceIdentifier;
}
public List<OperationResponse> getResponses() {
return responses;
}
public void setResponses(List<OperationResponse> responses) {
this.responses = responses;
}
public String getUpdatedTimestamp() {
return updatedTimestamp;
}
public void setUpdatedTimestamp(String updatedTimestamp) {
this.updatedTimestamp = updatedTimestamp;
}
public String getActivityId() {
return activityId;
}
public void setActivityId(String activityId) {
this.activityId = activityId;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public int getOperationId() {
return operationId;
}
public void setOperationId(int operationId) {
this.operationId = operationId;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public String getCreatedTimeStamp() {
return createdTimeStamp;
}
public void setCreatedTimeStamp(String createdTimeStamp) {
this.createdTimeStamp = createdTimeStamp;
}
public List<DeviceActivity> getDeviceActivities() {
return deviceActivities;
}
public void setDeviceActivities(List<DeviceActivity> deviceActivities) {
this.deviceActivities = deviceActivities;
}
public String getInitiatedBy() {
return initiatedBy;
}
public void setInitiatedBy(String initiatedBy) {
this.initiatedBy = initiatedBy;
}
}

@ -128,6 +128,11 @@ public interface OperationManager {
int getActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementException;
List<DeviceActivity> getDeviceActivities(ActivityPaginationRequest activityPaginationRequest) throws OperationManagementException;
int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementException;
List<Activity> getFilteredActivities(String operationCode, int limit, int offset) throws OperationManagementException;
int getTotalCountOfFilteredActivities(String operationCode) throws OperationManagementException;

@ -41,6 +41,7 @@ import io.entgra.device.mgt.core.device.mgt.common.exceptions.InvalidDeviceExcep
import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException;
import io.entgra.device.mgt.core.device.mgt.common.group.mgt.DeviceGroupConstants;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityStatus;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Operation;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationManagementException;
@ -1303,6 +1304,36 @@ public class OperationManagerImpl implements OperationManager {
}
}
@Override
public List<DeviceActivity> getDeviceActivities(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementException {
try {
OperationManagementDAOFactory.openConnection();
return operationDAO.getDeviceActivities(activityPaginationRequest);
} catch (SQLException e) {
throw new OperationManagementException("Error occurred while opening a connection to the data source.", e);
} catch (OperationManagementDAOException e) {
throw new OperationManagementException("Error occurred while getting the device activity list.", e);
} finally {
OperationManagementDAOFactory.closeConnection();
}
}
@Override
public int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementException {
try {
OperationManagementDAOFactory.openConnection();
return operationDAO.getDeviceActivitiesCount(activityPaginationRequest);
} catch (SQLException e) {
throw new OperationManagementException("Error occurred while opening a connection to the data source.", e);
} catch (OperationManagementDAOException e) {
throw new OperationManagementException("Error occurred while getting the device activity count.", e);
} finally {
OperationManagementDAOFactory.closeConnection();
}
}
@Override
public List<Activity> getFilteredActivities(String operationCode, int limit, int offset) throws OperationManagementException {
try {

@ -22,6 +22,7 @@ import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationResponse;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;
import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.Operation;
import io.entgra.device.mgt.core.device.mgt.core.dto.operation.mgt.OperationResponseMeta;
import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.OperationMapping;
@ -118,4 +119,9 @@ public interface OperationDAO {
int getActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementDAOException;
List<DeviceActivity> getDeviceActivities(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementDAOException;
int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementDAOException;
}

@ -26,6 +26,7 @@ import io.entgra.device.mgt.core.device.mgt.common.ActivityPaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityHolder;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityStatus;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationResponse;
@ -399,6 +400,51 @@ public class GenericOperationDAOImpl implements OperationDAO {
}
}
public OperationResponse populateResponse(ResultSet rs) throws SQLException {
OperationResponse response = new OperationResponse();
DeviceActivity deviceActivity = new DeviceActivity();
int responseId = 0;
List<OperationResponse> operationResponses = new ArrayList<>();
List<Integer> largeResponseIDs = new ArrayList<>();
if (rs.getTimestamp("RECEIVED_TIMESTAMP") != null) {
Timestamp receivedTimestamp = rs.getTimestamp("RECEIVED_TIMESTAMP");
response.setReceivedTimeStamp(new Date(receivedTimestamp.getTime()).toString());
}
response.setResponse(rs.getString("OPERATION_RESPONSE"));
int deviceOpId = rs.getInt("OPERATION_ID");
String deviceActivityId = DeviceManagementConstants.OperationAttributes.ACTIVITY + deviceOpId;
String deviceIdentifierId = rs.getString("DEVICE_IDENTIFICATION");
if (rs.getInt("UPDATED_TIMESTAMP") != 0) {
responseId = rs.getInt("OP_RES_ID");
if (rs.getBoolean("IS_LARGE_RESPONSE")) {
largeResponseIDs.add(responseId);
} else {
deviceActivity.setResponses(operationResponses);
}
}
if (!largeResponseIDs.isEmpty()) {
Map<String, Map<String, List<OperationResponse>>> largeOperationResponses = null;
try {
largeOperationResponses = getLargeOperationResponsesInBulk(largeResponseIDs);
if (!largeOperationResponses.isEmpty()) {
Map<String, List<OperationResponse>> largeResponse = largeOperationResponses.get(deviceActivityId);
if (largeResponse != null) {
response = largeResponse.get(deviceIdentifierId).get(0);
}
}
} catch (OperationManagementDAOException e) {
log.warn("Unable to get operation response for Operation ID: " + deviceOpId +
", Error: " + e.getErrorMessage());
}
}
return response;
}
@Override
public Activity getActivity(int operationId) throws OperationManagementDAOException {
@ -2566,4 +2612,222 @@ public class GenericOperationDAOImpl implements OperationDAO {
return 0;
}
@Override
public List<DeviceActivity> getDeviceActivities(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementDAOException {
List<DeviceActivity> finalizedActivitiesList = new ArrayList<>();
try {
boolean isTimeDurationFilteringProvided = false;
Connection conn = OperationManagementDAOFactory.getConnection();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
StringBuilder sql = new StringBuilder("SELECT " +
" eom.*," +
" opr.ID AS OP_RES_ID," +
" opr.RECEIVED_TIMESTAMP," +
" opr.OPERATION_RESPONSE, " +
" opr.IS_LARGE_RESPONSE " +
"FROM(" +
" SELECT * " +
" FROM " +
" DM_ENROLMENT_OP_MAPPING " +
" WHERE " +
" TENANT_ID = ? ");
if (activityPaginationRequest.getStartTimestamp() > 0 && activityPaginationRequest.getEndTimestamp() > 0) {
isTimeDurationFilteringProvided = true;
sql.append("AND CREATED_TIMESTAMP BETWEEN ? AND ? ");
}
if (activityPaginationRequest.getDeviceType() != null) {
sql.append("AND DEVICE_TYPE = ? ");
}
if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) {
sql.append("AND DEVICE_IDENTIFICATION IN (");
for (int i = 0; i < activityPaginationRequest.getDeviceIds().size() - 1; i++) {
sql.append("?, ");
}
sql.append("?) ");
}
if (activityPaginationRequest.getOperationId() > 0) {
sql.append("AND OPERATION_ID = ? ");
}
if (activityPaginationRequest.getOperationCode() != null) {
sql.append("AND OPERATION_CODE = ? ");
}
if (activityPaginationRequest.getInitiatedBy() != null) {
sql.append("AND INITIATED_BY = ? ");
}
if (activityPaginationRequest.getSince() != 0) {
sql.append("AND UPDATED_TIMESTAMP > ? ");
}
if (activityPaginationRequest.getType() != null) {
sql.append("AND TYPE = ? ");
}
if (activityPaginationRequest.getStatus() != null) {
sql.append("AND STATUS = ? ");
}
sql.append("ORDER BY ID ASC limit ? , ? ) eom " +
"LEFT JOIN DM_DEVICE_OPERATION_RESPONSE opr ON eom.ID = opr.EN_OP_MAP_ID");
int index = 1;
try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) {
stmt.setInt(index++, tenantId);
if (isTimeDurationFilteringProvided) {
stmt.setLong(index++, activityPaginationRequest.getStartTimestamp());
stmt.setLong(index++, activityPaginationRequest.getEndTimestamp());
}
if (activityPaginationRequest.getDeviceType() != null) {
stmt.setString(index++, activityPaginationRequest.getDeviceType());
}
if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) {
for (String deviceId : activityPaginationRequest.getDeviceIds()) {
stmt.setString(index++, deviceId);
}
}
if (activityPaginationRequest.getOperationId() > 0) {
stmt.setInt(index++, activityPaginationRequest.getOperationId());
}
if (activityPaginationRequest.getOperationCode() != null) {
stmt.setString(index++, activityPaginationRequest.getOperationCode());
}
if (activityPaginationRequest.getInitiatedBy() != null) {
stmt.setString(index++, activityPaginationRequest.getInitiatedBy());
}
if (activityPaginationRequest.getSince() != 0) {
stmt.setLong(index++, activityPaginationRequest.getSince());
}
if (activityPaginationRequest.getType() != null) {
stmt.setString(index++, activityPaginationRequest.getType().name());
}
if (activityPaginationRequest.getStatus() != null) {
stmt.setString(index++, activityPaginationRequest.getStatus().name());
}
stmt.setInt(index++, activityPaginationRequest.getOffset());
stmt.setInt(index, activityPaginationRequest.getLimit());
try (ResultSet rs = stmt.executeQuery()) {
Map<Integer, DeviceActivity> activities = new HashMap<>();
while (rs.next()) {
int activityId = rs.getInt("ID");
DeviceActivity deviceActivity = activities.get(activityId);
if (deviceActivity == null) {
deviceActivity = OperationDAOUtil.populateActivity(rs);
activities.put(activityId, deviceActivity);
}
deviceActivity.getResponses().add(populateResponse(rs));
}
for (int activityId : activities.keySet()) {
DeviceActivity deviceActivity = activities.get(activityId);
finalizedActivitiesList.add(deviceActivity);
}
}
}
} catch (SQLException e) {
String msg = "Error occurred while getting the operation details from the database.";
log.error(msg, e);
throw new OperationManagementDAOException(msg, e);
}
return finalizedActivitiesList;
}
@Override
public int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementDAOException {
try {
boolean isTimeDurationFilteringProvided = false;
Connection conn = OperationManagementDAOFactory.getConnection();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
StringBuilder sql = new StringBuilder();
sql.append("SELECT count(DISTINCT ID) AS ACTIVITY_COUNT " +
"FROM DM_ENROLMENT_OP_MAPPING WHERE TENANT_ID = ? ");
if (activityPaginationRequest.getDeviceType() != null) {
sql.append("AND DEVICE_TYPE = ? ");
}
if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) {
sql.append("AND DEVICE_IDENTIFICATION IN (");
for (int i = 0; i < activityPaginationRequest.getDeviceIds().size() - 1; i++) {
sql.append("?, ");
}
sql.append("?) ");
}
if (activityPaginationRequest.getOperationCode() != null) {
sql.append("AND OPERATION_CODE = ? ");
}
if (activityPaginationRequest.getOperationId() > 0) {
sql.append("AND OPERATION_ID = ? ");
}
if (activityPaginationRequest.getInitiatedBy() != null) {
sql.append("AND INITIATED_BY = ? ");
}
if (activityPaginationRequest.getSince() != 0) {
sql.append("AND UPDATED_TIMESTAMP > ? ");
}
if (activityPaginationRequest.getType() != null) {
sql.append("AND TYPE = ? ");
}
if (activityPaginationRequest.getStatus() != null) {
sql.append("AND STATUS = ? ");
}
if (activityPaginationRequest.getStartTimestamp() > 0 && activityPaginationRequest.getEndTimestamp() > 0) {
isTimeDurationFilteringProvided = true;
sql.append("AND CREATED_TIMESTAMP BETWEEN ? AND ? ");
}
int index = 1;
try (PreparedStatement stmt = conn.prepareStatement(sql.toString())) {
stmt.setInt(index++, tenantId);
if (activityPaginationRequest.getDeviceType() != null) {
stmt.setString(index++, activityPaginationRequest.getDeviceType());
}
if (activityPaginationRequest.getDeviceIds() != null && !activityPaginationRequest.getDeviceIds().isEmpty()) {
for (String deviceId : activityPaginationRequest.getDeviceIds()) {
stmt.setString(index++, deviceId);
}
}
if (activityPaginationRequest.getOperationCode() != null) {
stmt.setString(index++, activityPaginationRequest.getOperationCode());
}
if (activityPaginationRequest.getOperationId() > 0) {
stmt.setInt(index++, activityPaginationRequest.getOperationId());
}
if (activityPaginationRequest.getInitiatedBy() != null) {
stmt.setString(index++, activityPaginationRequest.getInitiatedBy());
}
if (activityPaginationRequest.getSince() != 0) {
stmt.setLong(index++, activityPaginationRequest.getSince());
}
if (activityPaginationRequest.getType() != null) {
stmt.setString(index++, activityPaginationRequest.getType().name());
}
if (activityPaginationRequest.getStatus() != null) {
stmt.setString(index++, activityPaginationRequest.getStatus().name());
}
if (isTimeDurationFilteringProvided) {
stmt.setLong(index++, activityPaginationRequest.getStartTimestamp());
stmt.setLong(index, activityPaginationRequest.getEndTimestamp());
}
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
return rs.getInt("ACTIVITY_COUNT");
}
}
}
} catch (SQLException e) {
String msg = "Error occurred while getting the operation details from the database.";
log.error(msg, e);
throw new OperationManagementDAOException(msg, e);
}
return 0;
}
}

@ -21,6 +21,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.DeviceIdentifier;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityHolder;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityMapper;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.ActivityStatus;
@ -38,6 +39,8 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -136,8 +139,9 @@ public class OperationDAOUtil {
public static OperationResponse getLargeOperationResponse(ResultSet rs) throws
ClassNotFoundException, IOException, SQLException {
OperationResponse response = new OperationResponse();
if (rs.getTimestamp("RECEIVED_TIMESTAMP") != (null)) {
response.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
if (rs.getTimestamp("RECEIVED_TIMESTAMP") != null) {
Timestamp receivedTimestamp = rs.getTimestamp("RECEIVED_TIMESTAMP");
response.setReceivedTimeStamp(new Date(receivedTimestamp.getTime()).toString());
}
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
@ -171,8 +175,9 @@ public class OperationDAOUtil {
public static OperationResponse getOperationResponse(ResultSet rs) throws SQLException {
OperationResponse response = new OperationResponse();
if (rs.getTimestamp("RECEIVED_TIMESTAMP") != (null)) {
response.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
if (rs.getTimestamp("RECEIVED_TIMESTAMP") != null) {
Timestamp receivedTimestamp = rs.getTimestamp("RECEIVED_TIMESTAMP");
response.setReceivedTimeStamp(new Date(receivedTimestamp.getTime()).toString());
}
if (rs.getString("OPERATION_RESPONSE") != null) {
response.setResponse(rs.getString("OPERATION_RESPONSE"));
@ -302,4 +307,27 @@ public class OperationDAOUtil {
throw new OperationManagementDAOException(msg, e);
}
}
public static DeviceActivity populateActivity(ResultSet rs) throws SQLException {
DeviceActivity deviceActivity = new DeviceActivity();
List<OperationResponse> operationResponses = new ArrayList<>();
deviceActivity.setType(DeviceActivity.Type.valueOf(rs.getString("TYPE")));
deviceActivity.setCreatedTimeStamp(new Date(rs.getLong(("CREATED_TIMESTAMP")) * 1000).toString());
deviceActivity.setActivityId(OperationDAOUtil.getActivityId(rs.getInt("OPERATION_ID")));
deviceActivity.setCode(rs.getString("OPERATION_CODE"));
deviceActivity.setOperationId(rs.getInt("OPERATION_ID"));
deviceActivity.setInitiatedBy(rs.getString("INITIATED_BY"));
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(rs.getString("DEVICE_IDENTIFICATION"));
deviceIdentifier.setType(rs.getString("DEVICE_TYPE"));
deviceActivity.setDeviceIdentifier(deviceIdentifier);
deviceActivity.setStatus(DeviceActivity.Status.valueOf(rs.getString("STATUS")));
if (rs.getInt("UPDATED_TIMESTAMP") != 0) {
deviceActivity.setResponses(operationResponses);
}
deviceActivity.setUpdatedTimestamp(new Date(rs.getLong(("UPDATED_TIMESTAMP")) * 1000).toString());
return deviceActivity;
}
}

@ -39,6 +39,7 @@ import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoQuery;
import io.entgra.device.mgt.core.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails;
import io.entgra.device.mgt.core.device.mgt.common.license.mgt.License;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Operation;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.PolicyMonitoringManager;
@ -1004,6 +1005,11 @@ public interface DeviceManagementProviderService {
int getActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementException;
List<DeviceActivity> getDeviceActivities(ActivityPaginationRequest activityPaginationRequest) throws OperationManagementException;
int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementException;
License getLicenseConfig (String deviceTypeName) throws DeviceManagementException;
/**

@ -93,6 +93,7 @@ import io.entgra.device.mgt.core.device.mgt.common.license.mgt.LicenseManagement
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Activity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.DeviceActivity;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.Operation;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.operation.mgt.OperationManager;
@ -2564,6 +2565,19 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
.getActivitiesCount(activityPaginationRequest);
}
@Override
public List<DeviceActivity> getDeviceActivities(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager().getDeviceActivities(activityPaginationRequest);
}
@Override
public int getDeviceActivitiesCount(ActivityPaginationRequest activityPaginationRequest)
throws OperationManagementException {
return DeviceManagementDataHolder.getInstance().getOperationManager()
.getDeviceActivitiesCount(activityPaginationRequest);
}
@Override
public List<MonitoringOperation> getMonitoringOperationList(String deviceType) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();

Loading…
Cancel
Save