From aa6bb0212703332234602d116ff253828c9e56ec Mon Sep 17 00:00:00 2001 From: Jayasanka Weerasinghe Date: Sat, 14 Mar 2020 18:17:43 +0530 Subject: [PATCH] Move device location history algorithm to the backend --- .../react-app/src/App.js | 2 +- .../react-app/src/index.js | 2 +- .../react-app/src/scenes/Home/index.js | 22 -- .../Devices/components/DevicesTable/index.js | 15 ++ .../scenes/Geo/components/CustomMap/index.js | 85 ++++---- .../Geo/components/GeoDashboard/index.js | 192 +++--------------- .../src/scenes/Home/scenes/Geo/index.js | 15 +- .../impl/DeviceManagementServiceImpl.java | 48 ++++- .../device/details/DeviceLocationHistory.java | 143 +------------ .../DeviceLocationHistorySnapshot.java | 63 ++++++ .../carbon/device/mgt/core/dao/DeviceDAO.java | 4 +- .../core/dao/impl/AbstractDeviceDAOImpl.java | 5 +- .../dao/util/DeviceManagementDAOUtil.java | 18 +- .../impl/DeviceInformationManagerImpl.java | 2 + .../DeviceManagementProviderService.java | 4 +- .../DeviceManagementProviderServiceImpl.java | 6 +- 16 files changed, 224 insertions(+), 402 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocationHistorySnapshot.java diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js index 12074a611e..61cce9fc07 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/App.js @@ -150,7 +150,7 @@ class App extends React.Component {
- + {this.props.routes.map(route => ( ))} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js index f0433aca5c..4f0862d427 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/index.js @@ -65,7 +65,7 @@ const routes = [ exact: true, }, { - path: '/entgra/geo', + path: '/entgra/geo/history/:deviceType/:deviceIdentifier', component: Geo, exact: true, }, diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/index.js index 80cd6d19d5..7273ee7250 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/index.js @@ -20,7 +20,6 @@ import React from 'react'; import { Layout, Menu, Icon } from 'antd'; import { Switch, Link } from 'react-router-dom'; import RouteWithSubRoutes from '../../components/RouteWithSubRoutes'; -import { Redirect } from 'react-router'; import './styles.css'; import { withConfigContext } from '../../components/ConfigContext'; import NotificationsDrawer from './components/NotificationsDrawer'; @@ -93,26 +92,6 @@ class Home extends React.Component { - - - Geo - - } - > - - - Single Device View - - - - - Device Group View - - - @@ -197,7 +176,6 @@ class Home extends React.Component { - {this.state.routes.map(route => ( ))} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Devices/components/DevicesTable/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Devices/components/DevicesTable/index.js index 11bba00611..e2e1a2b778 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Devices/components/DevicesTable/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Devices/components/DevicesTable/index.js @@ -33,6 +33,7 @@ import TimeAgo from 'javascript-time-ago'; import en from 'javascript-time-ago/locale/en'; import { withConfigContext } from '../../../../../../components/ConfigContext'; import BulkActionBar from './components/BulkActionBar'; +import { Link } from 'react-router-dom'; let config = null; @@ -126,6 +127,20 @@ const columns = [ }, // todo add filtering options }, + { + title: '', + dataIndex: 'deviceIdentifier', + key: 'actions', + // eslint-disable-next-line react/display-name + render: (data, row) => { + const { type, deviceIdentifier } = row; + return ( + + Location History + + ); + }, + }, ]; const getTimeAgo = time => { diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/components/CustomMap/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/components/CustomMap/index.js index 9dc2722e0f..7b3a88bfc2 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/components/CustomMap/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/components/CustomMap/index.js @@ -57,60 +57,42 @@ class CustomMap extends Component { /** * Polyline draw for historical locations - * @param locationData - location data object + * @param locationHistorySnapshots - location data object * @returns content */ - polylineMarker = locationData => { - const locationPoints = [...locationData]; + polylineMarker = locationHistorySnapshots => { const polyLines = []; + locationHistorySnapshots.forEach(locationHistorySnapshots => { + polyLines.push( + { + return [snapshot.latitude, snapshot.longitude]; + })} + smoothFactor={10} + weight={5} + />, + ); + }); - while (locationPoints.length > 0) { - // Array to store positions for next polyline - const positions = []; - // Make a copy of remaining location points - const cachedLocationPoints = [...locationPoints]; - // Iterate the remaining cached locations - for (let i = 0; i < cachedLocationPoints.length; i++) { - positions.push([ - cachedLocationPoints[i].latitude, - cachedLocationPoints[i].longitude, - ]); - const currentPoint = cachedLocationPoints[i]; - // Remove the current location from the locationPoints - locationPoints.shift(); - if (i < cachedLocationPoints.length - 1) { - const nextPoint = cachedLocationPoints[i + 1]; - // Draw a dashed line for long for location points with long interval - if ( - nextPoint.timestamp - currentPoint.timestamp > - this.props.context.geoMap.timeout * 1000 - ) { - // Create a dashed line - polyLines.push( - , - ); - break; - } - } - } - // Create a polyline from provided positions + for (let i = 1; i < locationHistorySnapshots.length; i++) { + const startPosition = locationHistorySnapshots[i][0]; + const endingPosition = + locationHistorySnapshots[i - 1][ + locationHistorySnapshots[i - 1].length - 1 + ]; polyLines.push( , ); } @@ -125,22 +107,23 @@ class CustomMap extends Component { }; render() { - const locationData = this.props.locationData; + const locationHistorySnapshots = this.props.locationHistorySnapshots; const config = this.props.context; const attribution = config.geoMap.attribution; const url = config.geoMap.url; - const startingPoint = [locationData[0].latitude, locationData[0].longitude]; - const endPoint = [ - locationData[locationData.length - 1].latitude, - locationData[locationData.length - 1].longitude, - ]; + const firstSnapshot = locationHistorySnapshots[0][0]; + const lastSnapshotList = + locationHistorySnapshots[locationHistorySnapshots.length - 1]; + const lastSnapshot = lastSnapshotList[lastSnapshotList.length - 1]; + const startingPoint = [firstSnapshot.latitude, firstSnapshot.longitude]; + const endPoint = [lastSnapshot.latitude, lastSnapshot.longitude]; const zoom = config.geoMap.defaultZoomLevel; return (
- {this.polylineMarker(locationData)} + {this.polylineMarker(locationHistorySnapshots)} Start diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/components/GeoDashboard/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/components/GeoDashboard/index.js index 410ce58a90..d8f5951d0a 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/components/GeoDashboard/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/components/GeoDashboard/index.js @@ -18,16 +18,7 @@ import React from 'react'; import moment from 'moment'; -import { - Button, - Select, - message, - notification, - Tag, - Tooltip, - Empty, - DatePicker, -} from 'antd'; +import { message, notification, Empty, DatePicker } from 'antd'; import axios from 'axios'; import { withConfigContext } from '../../../../../../components/ConfigContext'; import GeoCustomMap from '../CustomMap'; @@ -53,7 +44,7 @@ class GeoDashboard extends React.Component { this.state = { deviceData: [], selectedDevice: '', - locationData: [], + locationHistorySnapshots: [], loading: false, start: start, end: end, @@ -62,119 +53,23 @@ class GeoDashboard extends React.Component { } componentDidMount() { - this.fetchDevices(); - // this.fetchCurrentLocation(); + this.fetchLocationHistory(); } - /** * Call back on apply button in the date time picker * @param startDate - start date * @param endDate - end date */ applyCallback = (dates, dateStrings) => { - console.log('Apply Callback'); this.setState({ start: dateStrings[0], end: dateStrings[1], }); }; - /** - * Api call handle on fetch location date button - */ - handleApiCall = () => { - if (this.state.selectedDevice && this.state.start && this.state.end) { - const toInMills = moment(this.state.end); - const fromInMills = moment(this.state.start); - const deviceType = this.state.selectedDevice.type; - const deviceId = this.state.selectedDevice.deviceIdentifier; - const config = this.props.context; - this.setState({ loading: true }); - - axios - .get( - window.location.origin + - config.serverConfig.invoker.uri + - config.serverConfig.invoker.deviceMgt + - '/devices/' + - deviceType + - '/' + - deviceId + - '/location-history?' + - 'from=' + - fromInMills + - '&to=' + - toInMills, - ) - .then(res => { - if (res.status === 200) { - const locationData = JSON.parse(res.data.data); - this.setState({ - loading: false, - locationData, - }); - } - }) - .catch(error => { - if ( - error.hasOwnProperty('response') && - error.response.status === 401 - ) { - message.error('You are not logged in'); - window.location.href = window.location.origin + '/entgra/login'; - } else { - notification.error({ - message: 'There was a problem', - duration: 0, - description: - 'Error occurred while trying to fetch locations......', - }); - } - - this.setState({ loading: false }); - console.log(error); - }); - } else { - notification.error({ - message: 'There was a problem', - duration: 0, - description: 'Please provide a date range and a device.', - }); - } - }; - - /** - * Device dropdown list handler - * @param e - selected device data - */ - handleDeviceList = e => { - let selectedDevice = this.state.deviceData[e]; - this.setState({ selectedDevice }); - }; - - /** - * render fetch location button - */ - fetchLocationButton = () => { - let flag; - let toolTip = ''; - if (this.state.selectedDevice === '') { - flag = true; - toolTip = 'Please select a Device'; - } - return ( - - - - ); - }; - - /** - * fetches device data to populate the dropdown list - */ - fetchDevices = () => { + fetchLocationHistory = () => { + const toInMills = moment(this.state.end); + const fromInMills = moment(this.state.start); const config = this.props.context; this.setState({ loading: true }); @@ -183,14 +78,21 @@ class GeoDashboard extends React.Component { window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt + - '/devices?status=ACTIVE&status=INACTIVE&status=UNCLAIMED&status=UNREACHABLE&status=SUSPENDED&' + - 'status=DISENROLLMENT_REQUESTED&status=BLOCKED&status=CREATED', + '/devices/' + + this.props.deviceType + + '/' + + this.props.deviceIdentifier + + '/location-history?' + + 'from=' + + fromInMills + + '&to=' + + toInMills, ) .then(res => { if (res.status === 200) { this.setState({ loading: false, - deviceData: res.data.data.devices, + locationHistorySnapshots: res.data.data.locationHistorySnapshots, }); } }) @@ -202,11 +104,12 @@ class GeoDashboard extends React.Component { notification.error({ message: 'There was a problem', duration: 0, - description: 'Error occurred while trying to load devices.', + description: 'Error occurred while trying to fetch locations......', }); } this.setState({ loading: false }); + console.log(error); }); }; @@ -235,76 +138,29 @@ class GeoDashboard extends React.Component { '1 Month': [moment(start).subtract(1, 'months'), moment(end)], }; - let { deviceData } = this.state; - return (
- - - - {this.fetchLocationButton()}
); }; - /** - * Creates color based tags on device status - * @param device - device object - */ - statusTag = device => { - const status = device.enrolmentInfo.status.toLowerCase(); - let color = '#f9ca24'; - switch (status) { - case 'active': - color = '#badc58'; - break; - case 'created': - color = '#6ab04c'; - break; - case 'inactive': - color = '#f9ca24'; - break; - case 'blocked': - color = '#636e72'; - break; - } - - return {status}; - }; - render() { - const locationData = [...this.state.locationData]; - + const { locationHistorySnapshots } = this.state; return (
{this.controllerBar()} - {locationData.length > 0 ? ( - + {locationHistorySnapshots.length > 0 ? ( + ) : ( )} diff --git a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/index.js b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/index.js index e82b13133b..c313b91252 100644 --- a/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/index.js +++ b/components/device-mgt/io.entgra.device.mgt.ui/react-app/src/scenes/Home/scenes/Geo/index.js @@ -32,6 +32,7 @@ class Geo extends React.Component { } render() { + const { deviceIdentifier, deviceType } = this.props.match.params; return (
@@ -41,11 +42,14 @@ class Geo extends React.Component { Home - Geo + + Devices + + {`Location History - ${deviceType} / ${deviceIdentifier}`}
-

Geo

- Geo Location Service +

Location History

+ {`${deviceType} / ${deviceIdentifier}`}
- +
); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 520013f740..4de4d5a2ff 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -36,6 +36,8 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl; +import java.util.LinkedList; +import java.util.Queue; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -46,6 +48,8 @@ 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.MonitoringOperation; +import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; 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; @@ -56,6 +60,7 @@ import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; +import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; 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.exceptions.InvalidConfigurationException; @@ -494,8 +499,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @PathParam("deviceId") String deviceId, @QueryParam("from") long from, @QueryParam("to") long to) { - List deviceLocationHistory; String errorMessage; + DeviceLocationHistory deviceLocationHistory = new DeviceLocationHistory(); try { RequestValidationUtil.validateDeviceIdentifier(deviceType, deviceId); @@ -521,7 +526,46 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage(errorMessage)).build(); } - deviceLocationHistory = dms.getDeviceLocationInfo(deviceIdentifier, from, to); + List> locationHistorySnapshotList = new ArrayList<>(); + // Get the location history snapshots for the given period + List deviceLocationHistorySnapshots = dms.getDeviceLocationInfo(deviceIdentifier, from, to); + + OperationMonitoringTaskConfig operationMonitoringTaskConfig = dms.getDeviceMonitoringConfig(deviceType); + int taskFrequency = operationMonitoringTaskConfig.getFrequency(); + int operationRecurrentTimes = 0; + + List monitoringOperations = operationMonitoringTaskConfig.getMonitoringOperation(); + for (MonitoringOperation monitoringOperation : + monitoringOperations) { + if (monitoringOperation.getTaskName().equals("DEVICE_LOCATION")) { + operationRecurrentTimes = monitoringOperation.getRecurrentTimes(); + break; + } + } + // Device Location operation frequency in milliseconds. Adding 100000 ms as an error + long operationFrequency = taskFrequency * operationRecurrentTimes + 100000; + + Queue deviceLocationHistorySnapshotsQueue = new LinkedList<>(deviceLocationHistorySnapshots); + + while (deviceLocationHistorySnapshotsQueue.size() > 0) { + List snapshots = new ArrayList<>(); + // Make a copy of remaining snapshots + List cachedSnapshots = new ArrayList<>(deviceLocationHistorySnapshotsQueue); + + for (int i = 0; i < cachedSnapshots.size(); i++) { + DeviceLocationHistorySnapshot currentSnapshot = deviceLocationHistorySnapshotsQueue.poll(); + snapshots.add(currentSnapshot); + if (deviceLocationHistorySnapshotsQueue.size() > 0) { + DeviceLocationHistorySnapshot nextSnapshot = deviceLocationHistorySnapshotsQueue.peek(); + if (nextSnapshot.getUpdatedTime().getTime() - currentSnapshot.getUpdatedTime().getTime() > operationFrequency) { + break; + } + } + } + locationHistorySnapshotList.add(snapshots); + } + deviceLocationHistory.setLocationHistorySnapshots(locationHistorySnapshotList); + } catch (DeviceManagementException e) { errorMessage = "Error occurred while fetching the device information."; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocationHistory.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocationHistory.java index e5d1af9681..2d0c3f58dd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocationHistory.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocationHistory.java @@ -18,147 +18,18 @@ package org.wso2.carbon.device.mgt.common.device.details; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - import java.io.Serializable; - -@ApiModel(value = "DeviceLocationHistory", description = "This class carries all information related to the device location History" + - "details provided by a device.") +import java.util.ArrayList; +import java.util.List; public class DeviceLocationHistory implements Serializable { + private List> locationHistorySnapshots = new ArrayList<>(); - @ApiModelProperty(name = "deviceId", value = "Device id", required = true) - private int deviceId; - @ApiModelProperty(name = "geoHash", value = "Geo Hash", required = true) - private String geoHash; - @ApiModelProperty(name = "deviceType", value = "Device type", required = true) - private String deviceType; - @ApiModelProperty(name = "deviceIdentifier", value = "Device Id Name", required = true) - private String deviceIdentifier; - @ApiModelProperty(name = "latitude", value = "Device GPS latitude.", required = true) - private Double latitude; - @ApiModelProperty(name = "longitude", value = "Device GPS longitude.", required = true) - private Double longitude; - @ApiModelProperty(name = "tenantId", value = "Tenant Id.", required = true) - private int tenantId; - @ApiModelProperty(name = "altitude", value = "Device altitude.", required = true) - private Double altitude; - @ApiModelProperty(name = "speed", value = "Device speed.", required = true) - private Float speed; - @ApiModelProperty(name = "bearing", value = "Device bearing.", required = true) - private Float bearing; - @ApiModelProperty(name = "distance", value = "Device distance.", required = true) - private Double distance; - @ApiModelProperty(name = "timestamp", value = "Timestamp.", required = true) - private Long timestamp; - @ApiModelProperty(name = "owner", value = "Owner.", required = true) - private String owner; - - public DeviceLocationHistory() { - } - - public String getGeoHash() { - return geoHash; - } - - public void setGeoHash(String geoHash) { - this.geoHash = geoHash; - } - - public String getDeviceType() { - return deviceType; - } - - public void setDeviceType(String deviceType) { - this.deviceType = deviceType; - } - - public int getDeviceId() { - return deviceId; - } - - public void setDeviceId(int deviceId) { - this.deviceId = deviceId; - } - - public String getDeviceIdentifier() { - return deviceIdentifier; - } - - public void setDeviceIdentifier(String deviceIdentifier) { - this.deviceIdentifier = deviceIdentifier; - } - - public Double getLatitude() { - return latitude; - } - - public void setLatitude(Double latitude) { - this.latitude = latitude; - } - - public Double getLongitude() { - return longitude; - } - - public void setLongitude(Double longitude) { - this.longitude = longitude; - } - - public int getTenantId() { - return tenantId; - } - - public void setTenantId(int tenantId) { - this.tenantId = tenantId; - } - - public Double getAltitude() { - return altitude; - } - - public void setAltitude(double altitude) { - this.altitude = altitude; - } - - public Float getSpeed() { - return speed; - } - - public void setSpeed(Float speed) { - this.speed = speed; - } - - public Float getBearing() { - return bearing; - } - - public void setBearing(Float bearing) { - this.bearing = bearing; - } - - public Double getDistance() { - return distance; - } - - public void setDistance(Double distance) { - this.distance = distance; - } - - public Long getTimestamp() { - return timestamp; - } - - public void setTimestamp(Long timestamp) { - this.timestamp = timestamp; - } - - public String getOwner() { - return owner; + public List> getLocationHistorySnapshots() { + return locationHistorySnapshots; } - public void setOwner(String owner) { - this.owner = owner; + public void setLocationHistorySnapshots(List> locationHistorySnapshots) { + this.locationHistorySnapshots = locationHistorySnapshots; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocationHistorySnapshot.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocationHistorySnapshot.java new file mode 100644 index 0000000000..70ce46f601 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/device/details/DeviceLocationHistorySnapshot.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://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.device.details; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +@ApiModel(value = "DeviceLocationHistory", description = "This class carries all information related to the device location History" + + "details provided by a device.") + +public class DeviceLocationHistorySnapshot extends DeviceLocation implements Serializable { + + @ApiModelProperty(name = "geoHash", value = "Geo Hash", required = true) + private String geoHash; + @ApiModelProperty(name = "tenantId", value = "Tenant Id.", required = true) + private int tenantId; + @ApiModelProperty(name = "owner", value = "Owner.", required = true) + private String owner; + + public DeviceLocationHistorySnapshot() { + } + + public String getGeoHash() { + return geoHash; + } + + public void setGeoHash(String geoHash) { + this.geoHash = geoHash; + } + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java index 4eb94b606b..3cfa66baf1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -41,9 +41,9 @@ import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.Count; -import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceData; +import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.geo.GeoCluster; import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; @@ -595,7 +595,7 @@ public interface DeviceDAO { * @return * @throws DeviceManagementDAOException */ - List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) + List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) throws DeviceManagementDAOException; /** diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index d3f6569faa..1a8e168730 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -46,6 +46,7 @@ import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; +import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; @@ -1800,13 +1801,13 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { } @Override - public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) + public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) throws DeviceManagementDAOException { Connection conn; PreparedStatement stmt = null; ResultSet rs = null; - List deviceLocationHistories = new ArrayList<>(); + List deviceLocationHistories = new ArrayList<>(); try { conn = this.getConnection(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/DeviceManagementDAOUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/DeviceManagementDAOUtil.java index e92e2e814f..f5e37ee778 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/DeviceManagementDAOUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/util/DeviceManagementDAOUtil.java @@ -17,14 +17,15 @@ */ package org.wso2.carbon.device.mgt.core.dao.util; +import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; -import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; -import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; +import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; @@ -248,12 +249,13 @@ public final class DeviceManagementDAOUtil { return deviceInfo; } - public static DeviceLocationHistory loadDeviceLocation(ResultSet rs) throws SQLException { - DeviceLocationHistory deviceLocationHistory = new DeviceLocationHistory(); - deviceLocationHistory.setDeviceId(rs.getInt("DEVICE_ID")); - deviceLocationHistory.setDeviceIdentifier(rs.getString("DEVICE_ID_NAME")); + public static DeviceLocationHistorySnapshot loadDeviceLocation(ResultSet rs) throws SQLException { + DeviceLocationHistorySnapshot deviceLocationHistory = new DeviceLocationHistorySnapshot(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(rs.getString("DEVICE_ID_NAME")); + deviceIdentifier.setType(rs.getString("DEVICE_TYPE_NAME")); + deviceLocationHistory.setDeviceIdentifier(deviceIdentifier); deviceLocationHistory.setTenantId(rs.getInt("TENANT_ID")); - deviceLocationHistory.setDeviceType(rs.getString("DEVICE_TYPE_NAME")); deviceLocationHistory.setLatitude(rs.getDouble("LATITUDE")); deviceLocationHistory.setLongitude(rs.getDouble("LONGITUDE")); deviceLocationHistory.setSpeed(rs.getFloat("SPEED")); @@ -261,7 +263,7 @@ public final class DeviceManagementDAOUtil { deviceLocationHistory.setAltitude(rs.getDouble("DEVICE_ALTITUDE")); deviceLocationHistory.setDistance(rs.getDouble("DISTANCE")); deviceLocationHistory.setOwner(rs.getString("DEVICE_OWNER")); - deviceLocationHistory.setTimestamp(rs.getLong("TIMESTAMP")); + deviceLocationHistory.setUpdatedTime(new Date(rs.getLong("TIMESTAMP"))); deviceLocationHistory.setGeoHash(rs.getString("GEO_HASH")); return deviceLocationHistory; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java index c6c5e9f270..5261b56246 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/device/details/mgt/impl/DeviceInformationManagerImpl.java @@ -268,6 +268,8 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager { } else { deviceDetailsDAO.updateDeviceLocation(deviceLocation, device.getEnrolmentInfo().getId()); } + deviceDetailsDAO.addDeviceLocationInfo(device, deviceLocation, + CarbonContext.getThreadLocalCarbonContext().getTenantId()); if (DeviceManagerUtil.isPublishLocationResponseEnabled()) { Object[] metaData = {device.getDeviceIdentifier(), device.getEnrolmentInfo().getOwner(), device.getType()}; Object[] payload = new Object[]{ diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index 4389119dbf..cbeedfa98e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -46,6 +46,7 @@ import org.wso2.carbon.device.mgt.common.MonitoringOperation; import org.wso2.carbon.device.mgt.common.StartupOperationConfig; import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; @@ -56,7 +57,6 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.AmbiguousConfiguratio import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; -import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; @@ -765,7 +765,7 @@ public interface DeviceManagementProviderService { * @throws DeviceManagementException * @return list of device's location histories */ - List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) + List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) throws DeviceManagementException; /** diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index d5adc3538a..eeb78e14f0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -64,6 +64,7 @@ import org.wso2.carbon.device.mgt.common.DevicePropertyNotification; import org.wso2.carbon.device.mgt.common.DeviceEnrollmentInfoNotification; import org.wso2.carbon.device.mgt.common.DeviceNotification; import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; @@ -81,7 +82,6 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; -import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory; import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotificationConfiguration; import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotifier; import org.wso2.carbon.device.mgt.common.enrollment.notification.EnrollmentNotifierException; @@ -3013,14 +3013,14 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } @Override - public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) + public List getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to) throws DeviceManagementException { if (log.isDebugEnabled()) { log.debug("Get device location information"); } - List deviceLocationHistory; + List deviceLocationHistory; String errMessage; try {