Fix merge conflicts

4.x.x
tcdlpds@gmail.com 4 years ago
commit b9c2190762

@ -127,7 +127,10 @@ class AddNewReleaseFormComponent extends React.Component {
description: 'New release was added successfully', description: 'New release was added successfully',
}); });
const uuid = res.data.data.uuid; const uuid = res.data.data.uuid;
this.props.history.push('/publisher/apps/releases/' + uuid); this.props.history.push({
pathname: '/publisher/apps/releases/' + uuid,
state: { fullAppDetails: this.props.location.state.fullAppDetails },
});
} else { } else {
this.setState({ this.setState({
loading: false, loading: false,

@ -702,7 +702,14 @@ class AppDetailsDrawer extends React.Component {
title="Click to view full details" title="Click to view full details"
placement="topRight" placement="topRight"
> >
<Link to={'apps/releases/' + release.uuid}> <Link
to={{
pathname: `apps/releases/${release.uuid}`,
state: {
fullAppDetails: app.applicationReleases,
},
}}
>
<Card className="release-card"> <Card className="release-card">
<Meta <Meta
avatar={ avatar={
@ -773,7 +780,12 @@ class AppDetailsDrawer extends React.Component {
<Text>Add new release for the application</Text> <Text>Add new release for the application</Text>
</div> </div>
<Link <Link
to={`/publisher/apps/${app.deviceType}/${app.id}/add-release`} to={{
pathname: `/publisher/apps/${app.deviceType}/${app.id}/add-release`,
state: {
fullAppDetails: app.applicationReleases,
},
}}
> >
<Button htmlType="button" type="primary" size="small"> <Button htmlType="button" type="primary" size="small">
Add Add

@ -27,6 +27,7 @@ import {
Steps, Steps,
Alert, Alert,
Tabs, Tabs,
Tooltip,
} from 'antd'; } from 'antd';
import axios from 'axios'; import axios from 'axios';
import ReactQuill from 'react-quill'; import ReactQuill from 'react-quill';
@ -76,6 +77,7 @@ class LifeCycle extends React.Component {
current: 0, current: 0,
lifecycleSteps: [], lifecycleSteps: [],
lifeCycleStates: [], lifeCycleStates: [],
isPublished: false,
}; };
} }
@ -85,9 +87,11 @@ class LifeCycle extends React.Component {
const lifecycleSteps = Object.keys(lifeCycleConfig).map(config => { const lifecycleSteps = Object.keys(lifeCycleConfig).map(config => {
return lifeCycleConfig[config]; return lifeCycleConfig[config];
}); });
let isPublished = this.checkReleaseLifeCycleStatus();
this.setState({ this.setState({
current: lifeCycleConfig[this.props.currentStatus].step, current: lifeCycleConfig[this.props.currentStatus].step,
lifecycleSteps, lifecycleSteps,
isPublished,
}); });
this.getLifeCycleHistory(); this.getLifeCycleHistory();
} }
@ -198,6 +202,27 @@ class LifeCycle extends React.Component {
this.setState({ current }); this.setState({ current });
}; };
/*
Function to check if the same app releases are in published
state or not and assigned a boolean value to disable
the publish button if an app release is already published
*/
checkReleaseLifeCycleStatus = () => {
if (typeof this.props.appReleases !== 'undefined') {
let appReleases = this.props.appReleases.fullAppDetails;
for (let i = 0; i < appReleases.length; i++) {
if (
this.props.uuid !== appReleases[i].uuid &&
appReleases[i].currentStatus === 'PUBLISHED'
) {
return true;
}
}
return false;
}
return false;
};
render() { render() {
const { const {
currentStatus, currentStatus,
@ -207,6 +232,7 @@ class LifeCycle extends React.Component {
lifeCycleStates, lifeCycleStates,
} = this.state; } = this.state;
const { lifecycle } = this.props; const { lifecycle } = this.props;
const text = <span>Already an app is in publish state</span>;
let proceedingStates = []; let proceedingStates = [];
if ( if (
lifecycle !== null && lifecycle !== null &&
@ -247,17 +273,31 @@ class LifeCycle extends React.Component {
<p>{step.text}</p> <p>{step.text}</p>
{proceedingStates.map(lifecycleState => { {proceedingStates.map(lifecycleState => {
return ( return (
<Button <Tooltip
size={'small'}
style={{ marginRight: 3 }}
onClick={() =>
this.showReasonModal(lifecycleState)
}
key={lifecycleState} key={lifecycleState}
type={'primary'} title={
lifecycleState === 'PUBLISHED' &&
this.state.isPublished
? text
: ''
}
> >
{lifecycleState} <Button
</Button> size={'small'}
style={{ marginRight: 3 }}
disabled={
lifecycleState === 'PUBLISHED' &&
this.state.isPublished
}
onClick={() =>
this.showReasonModal(lifecycleState)
}
key={lifecycleState}
type={'primary'}
>
{lifecycleState}
</Button>
</Tooltip>
); );
})} })}
</div> </div>

@ -232,6 +232,7 @@ class Release extends React.Component {
this.changeCurrentLifecycleStatus this.changeCurrentLifecycleStatus
} }
lifecycle={lifecycle} lifecycle={lifecycle}
appReleases={this.props.location.state}
/> />
)} )}
</Skeleton> </Skeleton>

@ -153,7 +153,7 @@ class ReleaseView extends React.Component {
metaData = JSON.parse(release.metaData); metaData = JSON.parse(release.metaData);
// eslint-disable-next-line no-empty // eslint-disable-next-line no-empty
} catch (e) {} } catch (e) {}
if (app.hasOwnProperty('packageName')) { if (app.type !== 'WEB_CLIP' && app.hasOwnProperty('packageName')) {
metaData.push({ metaData.push({
key: 'Package Name', key: 'Package Name',
value: app.packageName, value: app.packageName,

@ -1588,8 +1588,38 @@ public interface DeviceManagementService {
@ApiParam( @ApiParam(
name = "ownership", name = "ownership",
value = "Provides the ownership of the required device.") value = "Provides the ownership of the required device.")
@QueryParam("owner") @QueryParam("ownership")
String ownership); String ownership,
@ApiParam(
name = "createdFrom",
value = "Since when user wants to filter operation logs using the created data and time")
@QueryParam("createdFrom")
Long createdFrom,
@ApiParam(
name = "createdTo",
value = "Till when user wants to filter operation logs using the created data and time")
@QueryParam("createdTo")
Long createdTo,
@ApiParam(
name = "updatedFrom",
value = "Since when user wants to filter operation logs using the received date and time")
@QueryParam("updatedFrom")
Long updatedFrom,
@ApiParam(
name = "updatedTo",
value = "Till when user wants to filter operation logs using the received date and time")
@QueryParam("updatedTo")
Long updatedTo,
@ApiParam(
name = "operationCode",
value = "Provides the operation codes to filter the operation logs via operation codes")
@QueryParam("operationCode")
List<String> operationCode,
@ApiParam(
name = "operationStatus",
value = "Provides the status codes to filter operation logs via status")
@QueryParam("operationStatus")
List<String> status);
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)

@ -42,14 +42,15 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.OperationLogFilters;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.DeviceFilters; import org.wso2.carbon.device.mgt.common.DeviceFilters;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
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.Application; import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
@ -92,9 +93,9 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList; import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest; import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest;
import org.wso2.carbon.device.mgt.jaxrs.beans.ComplianceDeviceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationList; import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationList;
import org.wso2.carbon.device.mgt.jaxrs.beans.OperationStatusBean; import org.wso2.carbon.device.mgt.jaxrs.beans.OperationStatusBean;
import org.wso2.carbon.device.mgt.jaxrs.beans.ComplianceDeviceList;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService; import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
@ -122,9 +123,9 @@ import javax.ws.rs.DefaultValue;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.ArrayList;
@Path("/devices") @Path("/devices")
public class DeviceManagementServiceImpl implements DeviceManagementService { public class DeviceManagementServiceImpl implements DeviceManagementService {
@ -886,21 +887,30 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@QueryParam("offset") int offset, @QueryParam("offset") int offset,
@QueryParam("limit") int limit, @QueryParam("limit") int limit,
@QueryParam("owner") String owner, @QueryParam("owner") String owner,
@QueryParam("ownership") String ownership) { @QueryParam("ownership") String ownership,
@QueryParam("createdFrom") Long createdFrom,
@QueryParam("createdTo") Long createdTo,
@QueryParam("updatedFrom") Long updatedFrom,
@QueryParam("updatedTo") Long updatedTo,
@QueryParam("operationCode") List<String> operationCode,
@QueryParam("operationStatus") List<String> status) {
OperationList operationsList = new OperationList(); OperationList operationsList = new OperationList();
RequestValidationUtil requestValidationUtil = new RequestValidationUtil();
RequestValidationUtil.validateOwnerParameter(owner); RequestValidationUtil.validateOwnerParameter(owner);
RequestValidationUtil.validatePaginationParameters(offset, limit); RequestValidationUtil.validatePaginationParameters(offset, limit);
PaginationRequest request = new PaginationRequest(offset, limit); PaginationRequest request = new PaginationRequest(offset, limit);
request.setOwner(owner); request.setOwner(owner);
PaginationResult result;
DeviceManagementProviderService dms;
try { try {
//validating the operation log filters
OperationLogFilters olf = requestValidationUtil.validateOperationLogFilters(operationCode, createdFrom,
createdTo, updatedFrom, updatedTo, status, type);
request.setOperationLogFilters(olf);
RequestValidationUtil.validateDeviceIdentifier(type, id); RequestValidationUtil.validateDeviceIdentifier(type, id);
dms = DeviceMgtAPIUtils.getDeviceManagementService(); DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
if (!StringUtils.isBlank(ownership)) { if (!StringUtils.isBlank(ownership)) {
request.setOwnership(ownership); request.setOwnership(ownership);
} }
result = dms.getOperations(new DeviceIdentifier(id, type), request); PaginationResult result = dms.getOperations(new DeviceIdentifier(id, type), request);
operationsList.setList((List<? extends Operation>) result.getData()); operationsList.setList((List<? extends Operation>) result.getData());
operationsList.setCount(result.getRecordsTotal()); operationsList.setCount(result.getRecordsTotal());
return Response.status(Response.Status.OK).entity(operationsList).build(); return Response.status(Response.Status.OK).entity(operationsList).build();
@ -910,6 +920,20 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
log.error(msg, e); log.error(msg, e);
return Response.serverError().entity( return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (InputValidationException e) {
String msg = "Error occurred while fetching the operations for the '" + type + "' device, which " +
"carries the id '" + id + "'";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the list of [" + type + "] features with params " +
"{featureType: operation, hidden: true}";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (DeviceTypeNotFoundException e) {
String msg = "No device type found with name '" + type + "'";
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} }
} }

@ -23,11 +23,16 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.OperationLogFilters;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException;
import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata;
import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; import org.wso2.carbon.device.mgt.common.notification.mgt.Notification;
import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.beans.GeofenceWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.GeofenceWrapper;
@ -36,20 +41,24 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.PolicyWrapper;
import org.wso2.carbon.device.mgt.jaxrs.beans.ProfileFeature; import org.wso2.carbon.device.mgt.jaxrs.beans.ProfileFeature;
import org.wso2.carbon.device.mgt.jaxrs.beans.RoleInfo; import org.wso2.carbon.device.mgt.jaxrs.beans.RoleInfo;
import org.wso2.carbon.device.mgt.jaxrs.beans.Scope; import org.wso2.carbon.device.mgt.jaxrs.beans.Scope;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceTypeManagementService;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants; import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.policy.mgt.common.PolicyPayloadValidator; import org.wso2.carbon.policy.mgt.common.PolicyPayloadValidator;
import javax.ws.rs.core.Response;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class RequestValidationUtil { public class RequestValidationUtil {
private static final Log log = LogFactory.getLog(RequestValidationUtil.class); private static final Log log = LogFactory.getLog(RequestValidationUtil.class);
/** /**
* Checks if multiple criteria are specified in a conditional request. * Checks if multiple criteria are specified in a conditional request.
* *
@ -477,6 +486,155 @@ public class RequestValidationUtil {
} }
} }
/**
* Checks if operation log filters are valid
*
* @param type Device type upon which the selection is done
* @param createdFrom Since when created date and time upon to filter operation logs
* @param createdTo Till when created date and time upon to filter operation logs
* @param updatedFrom Since when received date and time upon to filter operation logs
* @param updatedTo Till when received date and time upon to filter operation logs
* @param status List of operation status codes upon to filter operation logs
*/
public OperationLogFilters validateOperationLogFilters(List<String> operationCode,
Long createdFrom, Long createdTo, Long updatedFrom,
Long updatedTo, List<String> status, String type)
throws DeviceTypeNotFoundException, DeviceManagementException {
OperationLogFilters operationLogFilters = new OperationLogFilters();
Calendar date = Calendar.getInstance();
long timeMilli = date.getTimeInMillis();
if (updatedFrom != null || updatedTo != null) {
validateDates(updatedFrom, updatedTo);
//if user only sends the fromDate toDate sets as current date
if (updatedFrom != null && updatedTo == null) {
timeMilli = timeMilli / 1000;
operationLogFilters.setUpdatedDayTo(timeMilli);
operationLogFilters.setUpdatedDayFrom(updatedFrom);
} else {
operationLogFilters.setUpdatedDayFrom(updatedFrom);
operationLogFilters.setUpdatedDayTo(updatedTo);
}
}
if (createdTo != null || createdFrom != null) {
validateDates(createdFrom, createdTo);
createdFrom = createdFrom * 1000;
//if user only sends the fromDate toDate sets as current date
if (createdFrom != null && createdTo == null) {
operationLogFilters.setCreatedDayFrom(createdFrom);
operationLogFilters.setCreatedDayTo(timeMilli);
} else {
createdTo = createdTo * 1000;
operationLogFilters.setCreatedDayFrom(createdFrom);
operationLogFilters.setCreatedDayTo(createdTo);
}
}
if (status != null && !status.isEmpty()) {
validateStatusFiltering(status);
operationLogFilters.setStatus(status);
}
if (operationCode != null && !operationCode.isEmpty()) {
validateOperationCodeFiltering(operationCode, type);
operationLogFilters.setOperationCode(operationCode);
}
return operationLogFilters;
}
/**
* Checks if date ranges requested by user are valid
*
* @param toDate Till when created/updated dates upon to validate dates
* @param fromDate Since when created/updated dates upon to validate dates
*/
public static void validateDates(Long fromDate, Long toDate) {
Calendar date = Calendar.getInstance();
long timeMilli = date.getTimeInMillis();
timeMilli = timeMilli / 1000;
//if user only sends toDate
if (fromDate == null && toDate != null) {
String msg = "Request parameter must sent with the from date parameter";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
//if user sends future dates
if (fromDate != null && toDate != null) {
if (timeMilli < fromDate || timeMilli < toDate) {
String msg = "Bad Request cannot apply future dates";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
}
//if user send future dates - only when from date sends
if (fromDate != null && toDate == null) {
if (fromDate > timeMilli) {
String msg = "Bad Request cannot apply future dates";
log.error(msg);
throw new InputValidationException(
new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build());
}
}
}
/**
* Checks if user requested operation status codes are valid.
*
* @param status status codes upon to filter operation logs using status
*/
public static void validateStatusFiltering(List<String> status) {
for (int i = 0; i < status.size(); i++) {
if (Constants.OperationStatus.COMPLETED.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.ERROR.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.NOTNOW.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.REPEATED.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.PENDING.toUpperCase().equals(status.get(i))
|| Constants.OperationStatus.IN_PROGRESS.toUpperCase().equals(status.get(i))) {
} else {
String msg = "Invalid status type: " + status + ". \nValid status types are COMPLETED | ERROR | " +
"IN_PROGRESS | NOTNOW | PENDING | REPEATED";
log.error(msg);
throw new InputValidationException(new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST)
.setMessage(msg).build());
}
}
}
/**
* Checks if user requested operation codes are valid.
*
* @param operationCode operation codes upon to filter operation logs using operation codes
* @param type status codes upon to filter operation logs using status
*/
public static void validateOperationCodeFiltering(List<String> operationCode, String type)
throws DeviceTypeNotFoundException, DeviceManagementException {
int count = 0;
List<Feature> features;
DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm = dms.getFeatureManager(type);
features = fm.getFeatures("operation");
for (String oc : operationCode) {
for (Feature f : features) {
if (f.getCode().equals(oc)) {
count++;
break;
}
}
}
if (!(count == operationCode.size())) {
String msg = "Requested Operation code invalid";
log.error(msg);
throw new InputValidationException(new ErrorResponse.ErrorResponseBuilder()
.setCode(HttpStatus.SC_BAD_REQUEST)
.setMessage(msg).build());
}
}
/** /**
* Validate if the metaData and metaKey values are non empty & in proper format. * Validate if the metaData and metaKey values are non empty & in proper format.
* *

@ -648,24 +648,28 @@ public class DeviceManagementServiceImplTest {
@Test(description = "Testing getting operation list of a device") @Test(description = "Testing getting operation list of a device")
public void testGetDeviceOperations() { public void testGetDeviceOperations() {
List<String> operationCodes = new ArrayList<>();
List<String> statusCodes = new ArrayList<>();
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService); .toReturn(this.deviceManagementProviderService);
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME, .getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME,
DEFAULT_OWNERSHIP); DEFAULT_OWNERSHIP, null, null, null, null, operationCodes, statusCodes);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"Expects to return HTTP 200 when the operation is retrieved successfully."); "Expects to return HTTP 200 when the operation is retrieved successfully.");
} }
@Test(description = "Testing getting operation list of a device when unable to retrieve operations") @Test(description = "Testing getting operation list of a device when unable to retrieve operations")
public void testGetDeviceOperationsException() throws OperationManagementException { public void testGetDeviceOperationsException() throws OperationManagementException {
List<String> operationCodes = new ArrayList<>();
List<String> statusCodes = new ArrayList<>();
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService); .toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getOperations(Mockito.any(DeviceIdentifier.class), Mockito.when(this.deviceManagementProviderService.getOperations(Mockito.any(DeviceIdentifier.class),
Mockito.any(PaginationRequest.class))).thenThrow(new OperationManagementException()); Mockito.any(PaginationRequest.class))).thenThrow(new OperationManagementException());
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME, .getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5, DEFAULT_USERNAME,
DEFAULT_OWNERSHIP); DEFAULT_OWNERSHIP, null, null, null, null, operationCodes, statusCodes);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Expects to return HTTP 500 when an exception occurred while retrieving operation list of the device"); "Expects to return HTTP 500 when an exception occurred while retrieving operation list of the device");
} }

@ -30,7 +30,9 @@ public class EnrolmentInfo implements Serializable {
private static final long serialVersionUID = 1998101712L; private static final long serialVersionUID = 1998101712L;
public enum Status { public enum Status {
CREATED, ACTIVE, INACTIVE, UNREACHABLE, UNCLAIMED, SUSPENDED, BLOCKED, REMOVED, DISENROLLMENT_REQUESTED CREATED, ACTIVE, INACTIVE, UNREACHABLE, UNCLAIMED, SUSPENDED, BLOCKED, REMOVED, DISENROLLMENT_REQUESTED,
CONFIGURED, READY_TO_CONNECT, RETURN_PENDING, RETURNED, DEFECTIVE, WARRANTY_PENDING, WARRANTY_SENT,
WARRANTY_REPLACED
} }
public enum OwnerShip { public enum OwnerShip {

@ -0,0 +1,72 @@
/*
* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.common;
import java.util.List;
/**
* This class carries information related to operation log filtering values which will be used in the UI to filter operations.
*/
public class OperationLogFilters {
private List<String> operationCode;
private Long createdDayFrom;
private Long createdDayTo ;
private Long updatedDayFrom;
private Long updatedDayTo ;
private List<String> status;
public OperationLogFilters() {
}
public OperationLogFilters(List<String> operationCode , Long createdDayFrom, Long createdDayTo,
Long updatedDayFrom, Long updatedDayTo, List<String> status) {
this.operationCode = operationCode;
this.createdDayFrom = createdDayFrom;
this.createdDayTo = createdDayTo;
this.updatedDayFrom = updatedDayFrom;
this.updatedDayTo = updatedDayTo;
this.status = status;
}
public List<String> getOperationCode() {
return operationCode;
}
public void setOperationCode(List<String> operationCode) {
this.operationCode = operationCode;
}
public List<String> getStatus() {
return status;
}
public void setStatus(List<String> status) {
this.status = status;
}
public Long getUpdatedDayFrom() {
return updatedDayFrom;
}
public void setUpdatedDayFrom(Long updatedDayFrom) {
this.updatedDayFrom = updatedDayFrom;
}
public Long getUpdatedDayTo() {
return updatedDayTo;
}
public void setUpdatedDayTo(Long updatedDayTo) {
this.updatedDayTo = updatedDayTo;
}
public Long getCreatedDayFrom() { return createdDayFrom; }
public void setCreatedDayFrom(Long createdDayFrom) { this.createdDayFrom = createdDayFrom; }
public Long getCreatedDayTo() { return createdDayTo; }
public void setCreatedDayTo(Long createdDayTo) { this.createdDayTo = createdDayTo; }
}

@ -42,12 +42,17 @@ public class PaginationRequest {
private String filter; private String filter;
private Map<String, Object> property = new HashMap<>(); private Map<String, Object> property = new HashMap<>();
private List<String> statusList = new ArrayList<>(); private List<String> statusList = new ArrayList<>();
private OperationLogFilters operationLogFilters = new OperationLogFilters();
public OperationLogFilters getOperationLogFilters() {
return operationLogFilters;
}
public void setOperationLogFilters(OperationLogFilters operationLogFilters) {
this.operationLogFilters = operationLogFilters;
}
public PaginationRequest(int start, int rowCount) { public PaginationRequest(int start, int rowCount) {
this.startIndex = start; this.startIndex = start;
this.rowCount = rowCount; this.rowCount = rowCount;
} }
public int getStartIndex() { public int getStartIndex() {
return startIndex; return startIndex;
} }

@ -44,12 +44,14 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList; import java.text.DateFormat;
import java.util.Date; import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.HashMap;
import java.util.Date;
/** /**
* This class holds the generic implementation of OperationDAO which can be used to support ANSI db syntax. * This class holds the generic implementation of OperationDAO which can be used to support ANSI db syntax.
@ -1327,44 +1329,139 @@ public class GenericOperationDAOImpl implements OperationDAO {
@Override @Override
public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request) public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException { throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Operation operation; Operation operation;
List<Operation> operations = new ArrayList<Operation>(); List<Operation> operations = new ArrayList<Operation>();
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false; //updated day = received day
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCode = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
String sql = "SELECT " +
"o.ID, " +
"TYPE, " +
"o.CREATED_TIMESTAMP, " +
"o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, " +
"om.STATUS, " +
"om.ID AS OM_MAPPING_ID, " +
"om.UPDATED_TIMESTAMP " +
"FROM " +
"DM_OPERATION o " +
"INNER JOIN " +
"(SELECT dm.OPERATION_ID, " +
"dm.ID, " +
"dm.STATUS, " +
"dm.UPDATED_TIMESTAMP " +
"FROM " +
"DM_ENROLMENT_OP_MAPPING dm " +
"WHERE " +
"dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql = sql + " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql = sql + ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql = sql + " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if ((isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " AND (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
} else if ((!isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " WHERE (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
}
if ((isCreatedDayProvided || isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " AND (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
} else if ((!isCreatedDayProvided && !isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " WHERE (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
}
sql = sql + " ORDER BY o.CREATED_TIMESTAMP DESC LIMIT ?,?";
try { try {
Connection conn = OperationManagementDAOFactory.getConnection(); Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, o.TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, " + try (PreparedStatement stmt = conn.prepareStatement(sql)) {
"o.OPERATION_CODE, om.STATUS, om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " + int paramIndex = 1;
"INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING dm " + stmt.setInt(paramIndex++, enrolmentId);
"WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID " + if (isUpdatedDayProvided) {
"ORDER BY o.CREATED_TIMESTAMP DESC, o.ID DESC LIMIT ?,?"; stmt.setLong(paramIndex++, updatedFrom);
stmt = conn.prepareStatement(sql); stmt.setLong(paramIndex++, updatedTo);
stmt.setInt(1, enrolmentId); }
stmt.setInt(2, request.getStartIndex()); if (isCreatedDayProvided) {
stmt.setInt(3, request.getRowCount()); stmt.setString(paramIndex++, createdFrom);
rs = stmt.executeQuery(); stmt.setString(paramIndex++, createdTo);
}
while (rs.next()) { if (isStatusProvided) {
operation = new Operation(); int size = status.size();
operation.setId(rs.getInt("ID")); for (int i = 0; i < size; i++) {
operation.setType(Operation.Type.valueOf(rs.getString("TYPE"))); stmt.setString(paramIndex++, status.get(i));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString()); }
if (rs.getLong("UPDATED_TIMESTAMP") == 0) { }
operation.setReceivedTimeStamp(""); if (isOperationCodeProvided) {
} else { int size = operationCode.size();
operation.setReceivedTimeStamp( for (int i = 0; i < size; i++) {
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); stmt.setString(paramIndex++, operationCode.get(i));
}
}
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getLong("UPDATED_TIMESTAMP") == 0) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
} }
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new OperationManagementDAOException("SQL error occurred while retrieving the operation " + throw new OperationManagementDAOException("SQL error occurred while retrieving the operation " +
"available for the device'" + enrolmentId + "' with status '", e); "available for the device'" + enrolmentId + "' with status '", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
} }
return operations; return operations;
} }

@ -37,11 +37,13 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ArrayList;
import java.util.LinkedList;
/** /**
* This class holds the implementation of OperationDAO which can be used to support Oracle db syntax. * This class holds the implementation of OperationDAO which can be used to support Oracle db syntax.
@ -53,44 +55,140 @@ public class OracleOperationDAOImpl extends GenericOperationDAOImpl {
@Override @Override
public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request) public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException { throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Operation operation; Operation operation;
List<Operation> operations = new ArrayList<Operation>(); List<Operation> operations = new ArrayList<Operation>();
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false; //updated day = received day
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCode = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
String sql = "SELECT " +
"o.ID, " +
"TYPE, " +
"o.CREATED_TIMESTAMP, " +
"o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, " +
"om.STATUS, " +
"om.ID AS OM_MAPPING_ID, " +
"om.UPDATED_TIMESTAMP " +
"FROM " +
"DM_OPERATION o " +
"INNER JOIN " +
"(SELECT " +
"dm.OPERATION_ID, " +
"dm.ID, " +
"dm.STATUS, " +
"dm.UPDATED_TIMESTAMP " +
"FROM " +
"DM_ENROLMENT_OP_MAPPING dm " +
"WHERE " +
"dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql = sql + " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql = sql + ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql = sql + " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if ((isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " AND (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
} else if ((!isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " WHERE (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
}
if ((isCreatedDayProvided || isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " AND (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
} else if ((!isCreatedDayProvided && !isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " WHERE (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
}
sql = sql + " ORDER BY o.CREATED_TIMESTAMP DESC FFSET ? ROWS FETCH NEXT ? ROWS ONLY";
int paramIndex = 1;
try { try {
Connection conn = OperationManagementDAOFactory.getConnection(); Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, " try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ "o.OPERATION_CODE, om.STATUS, om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " stmt.setInt(paramIndex++, enrolmentId);
+ "INNER JOIN (SELECT dm.OPERATION_ID, dm.ID, dm.STATUS, dm.UPDATED_TIMESTAMP FROM DM_ENROLMENT_OP_MAPPING dm " if (isUpdatedDayProvided) {
+ "WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID ORDER BY o.CREATED_TIMESTAMP DESC " stmt.setLong(paramIndex++, updatedFrom);
+ "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; stmt.setLong(paramIndex++, updatedTo);
stmt = conn.prepareStatement(sql); }
stmt.setInt(1, enrolmentId); if (isCreatedDayProvided) {
stmt.setInt(2, request.getStartIndex()); stmt.setString(paramIndex++, createdFrom);
stmt.setInt(3, request.getRowCount()); stmt.setString(paramIndex++, createdTo);
rs = stmt.executeQuery(); }
if (isStatusProvided) {
while (rs.next()) { int size = status.size();
operation = new Operation(); for (int i = 0; i < size; i++) {
operation.setId(rs.getInt("ID")); stmt.setString(paramIndex++, status.get(i));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE"))); }
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString()); }
if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) { if (isOperationCodeProvided) {
operation.setReceivedTimeStamp(""); int size = operationCode.size();
} else { for (int i = 0; i < size; i++) {
operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString()); stmt.setString(paramIndex++, operationCode.get(i));
}
}
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
} }
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new OperationManagementDAOException( throw new OperationManagementDAOException(
"SQL error occurred while retrieving the operation " + "available for the device'" + enrolmentId "SQL error occurred while retrieving the operation " + "available for the device'" + enrolmentId
+ "' with status '", e); + "' with status '", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
} }
return operations; return operations;
} }

@ -32,9 +32,11 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.ArrayList;
/** /**
* This class holds the implementation of OperationDAO which can be used to support PostgreSQL db syntax. * This class holds the implementation of OperationDAO which can be used to support PostgreSQL db syntax.
@ -44,42 +46,139 @@ public class PostgreSQLOperationDAOImpl extends GenericOperationDAOImpl {
@Override @Override
public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request) public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException { throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Operation operation; Operation operation;
List<Operation> operations = new ArrayList<Operation>(); List<Operation> operations = new ArrayList<Operation>();
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false; //updated day = received day
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCode = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
String sql = "SELECT " +
"o.ID, " +
"TYPE, " +
"o.CREATED_TIMESTAMP, " +
"o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, " +
"om.STATUS, " +
"om.ID AS OM_MAPPING_ID, " +
"om.UPDATED_TIMESTAMP " +
"FROM " +
"DM_OPERATION o " +
"INNER JOIN " +
"(SELECT " +
"dm.OPERATION_ID, " +
"dm.ID, " +
"dm.STATUS, " +
"dm.UPDATED_TIMESTAMP " +
"FROM " +
"DM_ENROLMENT_OP_MAPPING dm " +
"WHERE " +
"dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql = sql + " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql = sql + ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql = sql + " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if ((isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " AND (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
} else if ((!isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " WHERE (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
}
if ((isCreatedDayProvided || isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " AND (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
} else if ((!isCreatedDayProvided && !isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
int size = operationCode.size();
sql = sql + " WHERE (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
}
sql = sql + " ORDER BY o.CREATED_TIMESTAMP DESC LIMIT ? OFFSET ?";
int paramIndex = 1;
try { try {
Connection conn = OperationManagementDAOFactory.getConnection(); Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, o.TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, " + try (PreparedStatement stmt = conn.prepareStatement(sql)) {
"o.OPERATION_CODE, om.STATUS FROM DM_OPERATION o " + stmt.setInt(paramIndex++, enrolmentId);
"INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING dm " + if (isUpdatedDayProvided) {
"WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID ORDER BY o.CREATED_TIMESTAMP DESC LIMIT ? OFFSET ?"; stmt.setLong(paramIndex++, updatedFrom);
stmt = conn.prepareStatement(sql); stmt.setLong(paramIndex++, updatedTo);
stmt.setInt(1, enrolmentId); }
stmt.setInt(2, request.getRowCount()); if (isCreatedDayProvided) {
stmt.setInt(3, request.getStartIndex()); stmt.setString(paramIndex++, createdFrom);
rs = stmt.executeQuery(); stmt.setString(paramIndex++, createdTo);
}
while (rs.next()) { if (isStatusProvided) {
operation = new Operation(); int size = status.size();
operation.setId(rs.getInt("ID")); for (int i = 0; i < size; i++) {
operation.setType(Operation.Type.valueOf(rs.getString("TYPE"))); stmt.setString(paramIndex++, status.get(i));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString()); }
if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) { }
operation.setReceivedTimeStamp(""); if (isOperationCodeProvided) {
} else { int size = operationCode.size();
operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString()); for (int i = 0; i < size; i++) {
stmt.setString(paramIndex++, operationCode.get(i));
}
}
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getTimestamp("RECEIVED_TIMESTAMP") == null) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
} }
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new OperationManagementDAOException("SQL error occurred while retrieving the operation " + throw new OperationManagementDAOException("SQL error occurred while retrieving the operation " +
"available for the device'" + enrolmentId, e); "available for the device'" + enrolmentId, e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
} }
return operations; return operations;
} }

@ -56,12 +56,13 @@ import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ArrayList;
import java.util.LinkedList;
/** /**
* This class holds the implementation of OperationDAO which can be used to support SQLServer db syntax. * This class holds the implementation of OperationDAO which can be used to support SQLServer db syntax.
*/ */
@ -72,44 +73,142 @@ public class SQLServerOperationDAOImpl extends GenericOperationDAOImpl {
@Override @Override
public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request) public List<? extends Operation> getOperationsForDevice(int enrolmentId, PaginationRequest request)
throws OperationManagementDAOException { throws OperationManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
Operation operation; Operation operation;
List<Operation> operations = new ArrayList<Operation>(); List<Operation> operations = new ArrayList<Operation>();
String createdTo = null;
String createdFrom = null;
DateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
boolean isCreatedDayProvided = false;
boolean isUpdatedDayProvided = false; //updated day = received day
boolean isOperationCodeProvided = false;
boolean isStatusProvided = false;
if (request.getOperationLogFilters().getCreatedDayFrom() != null) {
createdFrom = simple.format(request.getOperationLogFilters().getCreatedDayFrom());
}
if (request.getOperationLogFilters().getCreatedDayTo() != null) {
createdTo = simple.format(request.getOperationLogFilters().getCreatedDayTo());
}
Long updatedFrom = request.getOperationLogFilters().getUpdatedDayFrom();
Long updatedTo = request.getOperationLogFilters().getUpdatedDayTo();
List<String> operationCode = request.getOperationLogFilters().getOperationCode();
List<String> status = request.getOperationLogFilters().getStatus();
String sql = "SELECT " +
"o.ID, " +
"TYPE, " +
"o.CREATED_TIMESTAMP, " +
"o.RECEIVED_TIMESTAMP, " +
"o.OPERATION_CODE, " +
"om.STATUS, " +
"om.ID AS OM_MAPPING_ID, " +
"om.UPDATED_TIMESTAMP " +
"FROM " +
"DM_OPERATION o " +
"INNER JOIN " +
"(SELECT " +
"dm.OPERATION_ID, " +
"dm.ID, " +
"dm.STATUS, " +
"dm.UPDATED_TIMESTAMP " +
"FROM " +
"DM_ENROLMENT_OP_MAPPING dm " +
"WHERE " +
"dm.ENROLMENT_ID = ?";
if (updatedFrom != null && updatedFrom != 0 && updatedTo != null && updatedTo != 0) {
sql = sql + " AND dm.UPDATED_TIMESTAMP BETWEEN ? AND ?";
isUpdatedDayProvided = true;
}
sql = sql + ") om ON o.ID = om.OPERATION_ID ";
if (createdFrom != null && !createdFrom.isEmpty() && createdTo != null && !createdTo.isEmpty()) {
sql = sql + " WHERE o.CREATED_TIMESTAMP BETWEEN ? AND ?";
isCreatedDayProvided = true;
}
if ((isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " AND (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
} else if ((!isCreatedDayProvided) && (status != null && !status.isEmpty())) {
int size = status.size();
sql = sql + " WHERE (om.STATUS = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR om.STATUS = ?";
}
sql = sql + ")";
isStatusProvided = true;
}
if ((isCreatedDayProvided || isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
// sql = sql + " AND o.OPERATION_CODE = ? ";
int size = operationCode.size();
sql = sql + " AND (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
} else if ((!isCreatedDayProvided && !isStatusProvided) && (operationCode != null && !operationCode.isEmpty())) {
//sql = sql + " WHERE o.OPERATION_CODE = ? ";
int size = operationCode.size();
sql = sql + " WHERE (o.OPERATION_CODE = ? ";
for (int i = 0; i < size - 1; i++) {
sql = sql + " OR o.OPERATION_CODE = ?";
}
sql = sql + ")";
isOperationCodeProvided = true;
}
sql = sql + " ORDER BY o.CREATED_TIMESTAMP DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
int paramIndex = 1;
try { try {
Connection conn = OperationManagementDAOFactory.getConnection(); Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, " + try (PreparedStatement stmt = conn.prepareStatement(sql)) {
"o.OPERATION_CODE, om.STATUS, om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " + stmt.setInt(paramIndex++, enrolmentId);
"INNER JOIN (SELECT dm.OPERATION_ID, dm.ID, dm.STATUS, dm.UPDATED_TIMESTAMP FROM DM_ENROLMENT_OP_MAPPING dm " + if (isUpdatedDayProvided) {
"WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID ORDER BY o.CREATED_TIMESTAMP DESC " + stmt.setLong(paramIndex++, updatedFrom);
"OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; stmt.setLong(paramIndex++, updatedTo);
stmt = conn.prepareStatement(sql); }
stmt.setInt(1, enrolmentId); if (isCreatedDayProvided) {
stmt.setInt(2, request.getStartIndex()); stmt.setString(paramIndex++, createdFrom);
stmt.setInt(3, request.getRowCount()); stmt.setString(paramIndex++, createdTo);
rs = stmt.executeQuery(); }
if (isStatusProvided) {
while (rs.next()) { int size = status.size();
operation = new Operation(); for (int i = 0; i < size; i++) {
operation.setId(rs.getInt("ID")); stmt.setString(paramIndex++, status.get(i));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE"))); }
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString()); }
if (rs.getLong("UPDATED_TIMESTAMP") == 0) { if (isOperationCodeProvided) {
operation.setReceivedTimeStamp(""); int size = operationCode.size();
} else { for (int i = 0; i < size; i++) {
operation.setReceivedTimeStamp( stmt.setString(paramIndex++, operationCode.get(i));
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); }
}
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(rs.getTimestamp("CREATED_TIMESTAMP").toString());
if (rs.getLong("UPDATED_TIMESTAMP") == 0) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
}
} }
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));
OperationDAOUtil.setActivityId(operation, rs.getInt("ID"));
operations.add(operation);
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new OperationManagementDAOException("SQL error occurred while retrieving the operations " + throw new OperationManagementDAOException("SQL error occurred while retrieving the operations " +
"available for the device '" + enrolmentId + "'", e); "available for the device '" + enrolmentId + "'", e);
} finally {
OperationManagementDAOUtil.cleanupResources(stmt, rs);
} }
return operations; return operations;
} }

@ -153,7 +153,7 @@ public class ComplianceDecisionPointImpl implements ComplianceDecisionPoint {
PolicyOperation policyOperation = new PolicyOperation(); PolicyOperation policyOperation = new PolicyOperation();
policyOperation.setEnabled(true); policyOperation.setEnabled(true);
policyOperation.setType(Operation.Type.POLICY); policyOperation.setType(Operation.Type.POLICY);
policyOperation.setCode(PolicyOperation.POLICY_OPERATION_CODE); policyOperation.setCode(PolicyManagementConstants.MONITOR_POLICY_BUNDLE);
if (complianceData.isCompletePolicy()) { if (complianceData.isCompletePolicy()) {
List<ProfileFeature> effectiveFeatures = policy.getProfile().getProfileFeaturesList(); List<ProfileFeature> effectiveFeatures = policy.getProfile().getProfileFeaturesList();

@ -40,6 +40,7 @@ public final class PolicyManagementConstants {
public static final String DEVICE_CONFIG_XML_NAME = "cdm-config.xml"; public static final String DEVICE_CONFIG_XML_NAME = "cdm-config.xml";
public static final String ANY = "ANY"; public static final String ANY = "ANY";
public static final String POLICY_BUNDLE = "POLICY_BUNDLE"; public static final String POLICY_BUNDLE = "POLICY_BUNDLE";
public static final String MONITOR_POLICY_BUNDLE = "MONITOR_POLICY_BUNDLE";
public static final String TENANT_ID = "TENANT_ID"; public static final String TENANT_ID = "TENANT_ID";

Loading…
Cancel
Save