Merge branch 'geo-backend' into 'master'

Move device location history grouping logic to the backend

Closes product-iots#343

See merge request entgra/carbon-device-mgt!468
feature/appm-store/pbac
Charitha Goonetilleke 5 years ago
commit da5c7e307f

@ -150,7 +150,7 @@ class App extends React.Component {
<ConfigContext.Provider value={this.state.config}>
<div>
<Switch>
<Redirect exact from="/entgra" to="/entgra/reports" />
<Redirect exact from="/entgra" to="/entgra/devices" />
{this.props.routes.map(route => (
<RouteWithSubRoutes key={route.path} {...route} />
))}

@ -65,7 +65,7 @@ const routes = [
exact: true,
},
{
path: '/entgra/geo',
path: '/entgra/geo/history/:deviceType/:deviceIdentifier',
component: Geo,
exact: true,
},

@ -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 Logout from './components/Logout';
@ -92,26 +91,6 @@ class Home extends React.Component {
</Link>
</Menu.Item>
</SubMenu>
<SubMenu
key="geo"
title={
<span>
<Icon type="environment" />
<span>Geo</span>
</span>
}
>
<Menu.Item key="singleDevice">
<Link to="/entgra/geo">
<span>Single Device View</span>
</Link>
</Menu.Item>
<Menu.Item key="deviceGroup">
<Link to="#">
<span>Device Group View</span>
</Link>
</Menu.Item>
</SubMenu>
<Menu.Item key="reports">
<Link to="/entgra/reports">
<Icon type="bar-chart" />
@ -198,7 +177,6 @@ class Home extends React.Component {
<Content>
<Switch>
<Redirect exact from="/entgra/devices" to="/entgra/reports" />
{this.state.routes.map(route => (
<RouteWithSubRoutes key={route.path} {...route} />
))}

@ -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 (
<Link to={`/entgra/geo/history/${type}/${deviceIdentifier}`}>
<Icon type="environment" /> Location History
</Link>
);
},
},
];
const getTimeAgo = time => {

@ -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 = [];
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
locationHistorySnapshots.forEach(locationHistorySnapshots => {
polyLines.push(
<Polyline
key={polyLines.length}
color="#414042"
positions={[
[currentPoint.latitude, currentPoint.longitude],
[nextPoint.latitude, nextPoint.longitude],
]}
positions={locationHistorySnapshots.map(snapshot => {
return [snapshot.latitude, snapshot.longitude];
})}
smoothFactor={10}
weight={5}
dashArray="7"
/>,
);
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(
<Polyline
key={polyLines.length}
color="#414042"
positions={positions}
positions={[
[startPosition.latitude, startPosition.longitude],
[endingPosition.latitude, endingPosition.longitude],
]}
smoothFactor={10}
weight={5}
dashArray="7"
/>,
);
}
@ -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 (
<div style={{ backgroundColor: '#ffffff', borderRadius: 5, padding: 5 }}>
<Map center={startingPoint} zoom={zoom}>
<TileLayer url={url} attribution={attribution} />
<Fragment>
{this.polylineMarker(locationData)}
{this.polylineMarker(locationHistorySnapshots)}
<Marker icon={pinStart} position={startingPoint}>
<Popup keepInView={true}>Start</Popup>
<Tooltip direction="top" permanent={true}>

@ -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,32 +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) {
fetchLocationHistory = () => {
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 });
@ -97,9 +79,9 @@ class GeoDashboard extends React.Component {
config.serverConfig.invoker.uri +
config.serverConfig.invoker.deviceMgt +
'/devices/' +
deviceType +
this.props.deviceType +
'/' +
deviceId +
this.props.deviceIdentifier +
'/location-history?' +
'from=' +
fromInMills +
@ -108,89 +90,9 @@ class GeoDashboard extends React.Component {
)
.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 (
<Tooltip placement="rightBottom" title={toolTip}>
<Button disabled={flag} onClick={this.handleApiCall}>
Fetch Locations
</Button>
</Tooltip>
);
};
/**
* fetches device data to populate the dropdown list
*/
fetchDevices = () => {
const config = this.props.context;
this.setState({ loading: true });
axios
.get(
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',
)
.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 (
<div className="controllerDiv">
<RangePicker
ranges={ranges}
style={{ marginRight: 20 }}
style={{ marginRight: 20, width: 400 }}
showTime
format="YYYY-MM-DD HH:mm:ss"
defaultValue={[this.state.start, this.state.end]}
onChange={this.applyCallback}
onOk={this.fetchLocationHistory}
size="large"
/>
<Select
showSearch
style={{ width: 220, marginRight: 20 }}
placeholder="Select a Device"
optionFilterProp="children"
onChange={this.handleDeviceList}
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >=
0
}
>
{deviceData.map((device, index) => (
<Select.Option key={index} value={index}>
{device.name + ' '}
{this.statusTag(device)}
</Select.Option>
))}
</Select>
{this.fetchLocationButton()}
</div>
);
};
/**
* 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 <Tag color={color}>{status}</Tag>;
};
render() {
const locationData = [...this.state.locationData];
const { locationHistorySnapshots } = this.state;
return (
<div className="container">
{this.controllerBar()}
{locationData.length > 0 ? (
<GeoCustomMap locationData={locationData} />
{locationHistorySnapshots.length > 0 ? (
<GeoCustomMap locationHistorySnapshots={locationHistorySnapshots} />
) : (
<Empty />
)}

@ -32,6 +32,7 @@ class Geo extends React.Component {
}
render() {
const { deviceIdentifier, deviceType } = this.props.match.params;
return (
<div>
<PageHeader style={{ paddingTop: 0 }}>
@ -41,11 +42,14 @@ class Geo extends React.Component {
<Icon type="home" /> Home
</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>Geo</Breadcrumb.Item>
<Breadcrumb.Item>
<Link to="/entgra">Devices</Link>
</Breadcrumb.Item>
<Breadcrumb.Item>{`Location History - ${deviceType} / ${deviceIdentifier}`}</Breadcrumb.Item>
</Breadcrumb>
<div className="wrap">
<h3>Geo</h3>
<Paragraph>Geo Location Service</Paragraph>
<h3>Location History </h3>
<Paragraph>{`${deviceType} / ${deviceIdentifier}`}</Paragraph>
</div>
</PageHeader>
<div
@ -56,7 +60,10 @@ class Geo extends React.Component {
alignItems: 'center',
}}
>
<GeoDashboard />
<GeoDashboard
deviceIdentifier={deviceIdentifier}
deviceType={deviceType}
/>
</div>
</div>
);

@ -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> 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<List<DeviceLocationHistorySnapshot>> locationHistorySnapshotList = new ArrayList<>();
// Get the location history snapshots for the given period
List<DeviceLocationHistorySnapshot> deviceLocationHistorySnapshots = dms.getDeviceLocationInfo(deviceIdentifier, from, to);
OperationMonitoringTaskConfig operationMonitoringTaskConfig = dms.getDeviceMonitoringConfig(deviceType);
int taskFrequency = operationMonitoringTaskConfig.getFrequency();
int operationRecurrentTimes = 0;
List<MonitoringOperation> 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<DeviceLocationHistorySnapshot> deviceLocationHistorySnapshotsQueue = new LinkedList<>(deviceLocationHistorySnapshots);
while (deviceLocationHistorySnapshotsQueue.size() > 0) {
List<DeviceLocationHistorySnapshot> snapshots = new ArrayList<>();
// Make a copy of remaining snapshots
List<DeviceLocationHistorySnapshot> 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.";

@ -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<List<DeviceLocationHistorySnapshot>> 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<List<DeviceLocationHistorySnapshot>> getLocationHistorySnapshots() {
return locationHistorySnapshots;
}
public void setOwner(String owner) {
this.owner = owner;
public void setLocationHistorySnapshots(List<List<DeviceLocationHistorySnapshot>> locationHistorySnapshots) {
this.locationHistorySnapshots = locationHistorySnapshots;
}
}

@ -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;
}
}

@ -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<DeviceLocationHistory> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
List<DeviceLocationHistorySnapshot> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
throws DeviceManagementDAOException;
/**

@ -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<DeviceLocationHistory> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
public List<DeviceLocationHistorySnapshot> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
List<DeviceLocationHistory> deviceLocationHistories = new ArrayList<>();
List<DeviceLocationHistorySnapshot> deviceLocationHistories = new ArrayList<>();
try {
conn = this.getConnection();

@ -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;
}

@ -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[]{

@ -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<DeviceLocationHistory> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
List<DeviceLocationHistorySnapshot> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
throws DeviceManagementException;
/**

@ -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<DeviceLocationHistory> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
public List<DeviceLocationHistorySnapshot> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
throws DeviceManagementException {
if (log.isDebugEnabled()) {
log.debug("Get device location information");
}
List<DeviceLocationHistory> deviceLocationHistory;
List<DeviceLocationHistorySnapshot> deviceLocationHistory;
String errMessage;
try {

Loading…
Cancel
Save