mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Implement reports for device enrollment and policy compliance
This commit is contained in:
parent
76912b6492
commit
39e3e7fa1d
@ -148,7 +148,7 @@ class App extends React.Component {
|
|||||||
<ConfigContext.Provider value={this.state.config}>
|
<ConfigContext.Provider value={this.state.config}>
|
||||||
<div>
|
<div>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Redirect exact from="/entgra" to="/entgra/devices" />
|
<Redirect exact from="/entgra" to="/entgra/reports" />
|
||||||
{this.props.routes.map(route => (
|
{this.props.routes.map(route => (
|
||||||
<RouteWithSubRoutes key={route.path} {...route} />
|
<RouteWithSubRoutes key={route.path} {...route} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -33,28 +33,27 @@ class DateRangePicker extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
return (
|
return (
|
||||||
<RangePicker
|
<div>
|
||||||
ranges={{
|
<RangePicker
|
||||||
Today: [moment(), moment()],
|
ranges={{
|
||||||
Yesterday: [
|
Today: [moment(), moment()],
|
||||||
moment().subtract(1, 'days'),
|
Yesterday: [moment().subtract(1, 'days'), moment()],
|
||||||
moment().subtract(1, 'days'),
|
'Last 7 Days': [moment().subtract(7, 'days'), moment()],
|
||||||
],
|
'Last 30 Days': [moment().subtract(30, 'days'), moment()],
|
||||||
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
|
'This Month': [moment().startOf('month'), moment().endOf('month')],
|
||||||
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
|
'Last Month': [
|
||||||
'This Month': [moment().startOf('month'), moment().endOf('month')],
|
moment()
|
||||||
'Last Month': [
|
.subtract(1, 'month')
|
||||||
moment()
|
.startOf('month'),
|
||||||
.subtract(1, 'month')
|
moment()
|
||||||
.startOf('month'),
|
.subtract(1, 'month')
|
||||||
moment()
|
.endOf('month'),
|
||||||
.subtract(1, 'month')
|
],
|
||||||
.endOf('month'),
|
}}
|
||||||
],
|
format="YYYY-MM-DD"
|
||||||
}}
|
onChange={this.onChange}
|
||||||
format="YYYY-MM-DD"
|
/>
|
||||||
onChange={this.onChange}
|
</div>
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
@ -17,14 +17,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PageHeader, Breadcrumb, Icon, Select, Button, Card } from 'antd';
|
import { PageHeader, Breadcrumb, Icon, Radio, Popover, Button } from 'antd';
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import ReportDeviceTable from '../../../components/Devices/ReportDevicesTable';
|
|
||||||
import PieChart from '../../../components/Reports/Widgets/PieChart';
|
|
||||||
import { withConfigContext } from '../../../context/ConfigContext';
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import axios from 'axios';
|
||||||
const { Option } = Select;
|
import DateRangePicker from '../DateRangePicker';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { Chart, Geom, Axis, Tooltip, Legend } from 'bizcharts';
|
||||||
|
import DataSet from '@antv/data-set';
|
||||||
|
import { handleApiError } from '../../../js/Utils';
|
||||||
|
|
||||||
class DeviceStatusReport extends React.Component {
|
class DeviceStatusReport extends React.Component {
|
||||||
routes;
|
routes;
|
||||||
@ -32,37 +34,145 @@ class DeviceStatusReport extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.routes = props.routes;
|
this.routes = props.routes;
|
||||||
const { reportData } = this.props.location;
|
|
||||||
this.state = {
|
this.state = {
|
||||||
selectedTags: ['Enrolled'],
|
|
||||||
paramsObject: {
|
paramsObject: {
|
||||||
from: reportData.duration[0],
|
from: moment()
|
||||||
to: reportData.duration[1],
|
.subtract(7, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
to: moment().format('YYYY-MM-DD'),
|
||||||
},
|
},
|
||||||
statsObject: {},
|
data: [],
|
||||||
statArray: [
|
fields: [],
|
||||||
{ item: 'ACTIVE', count: 0 },
|
durationMode: 'weekly',
|
||||||
{ item: 'INACTIVE', count: 0 },
|
visible: false,
|
||||||
{ item: 'REMOVED', count: 0 },
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickPieChart = value => {
|
handleDurationModeChange = e => {
|
||||||
console.log(value.data.point.item);
|
const durationMode = e.target.value;
|
||||||
const chartValue = value.data.point.item;
|
switch (durationMode) {
|
||||||
|
case 'daily':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
moment()
|
||||||
|
.add(1, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'weekly':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(7, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'monthly':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(30, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.setState({ durationMode });
|
||||||
|
};
|
||||||
|
|
||||||
|
handlePopoverVisibleChange = visible => {
|
||||||
|
this.setState({ visible });
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fetchData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get modified value from datepicker and set it to paramsObject
|
||||||
|
updateDurationValue = (modifiedFromDate, modifiedToDate) => {
|
||||||
let tempParamObj = this.state.paramsObject;
|
let tempParamObj = this.state.paramsObject;
|
||||||
|
tempParamObj.from = modifiedFromDate;
|
||||||
tempParamObj.status = chartValue;
|
tempParamObj.to = modifiedToDate;
|
||||||
|
|
||||||
this.setState({ paramsObject: tempParamObj });
|
this.setState({ paramsObject: tempParamObj });
|
||||||
console.log(this.state.paramsObject);
|
this.fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Call count APIs and get count for given parameters, then create data object to build pie chart
|
||||||
|
fetchData = () => {
|
||||||
|
this.setState({ loading: true });
|
||||||
|
|
||||||
|
const { paramsObject } = this.state;
|
||||||
|
const config = this.props.context;
|
||||||
|
|
||||||
|
const encodedExtraParams = Object.keys(paramsObject)
|
||||||
|
.map(key => key + '=' + paramsObject[key])
|
||||||
|
.join('&');
|
||||||
|
|
||||||
|
axios
|
||||||
|
.all([
|
||||||
|
axios.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/reports/count?status=ACTIVE&' +
|
||||||
|
encodedExtraParams,
|
||||||
|
'Active',
|
||||||
|
),
|
||||||
|
axios.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/reports/count?status=INACTIVE&' +
|
||||||
|
encodedExtraParams,
|
||||||
|
'Inactive',
|
||||||
|
),
|
||||||
|
axios.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/reports/count?status=REMOVED&' +
|
||||||
|
encodedExtraParams,
|
||||||
|
'Removed',
|
||||||
|
),
|
||||||
|
])
|
||||||
|
.then(res => {
|
||||||
|
let keys = Object.keys(res[0].data.data);
|
||||||
|
let active = res[0].data.data;
|
||||||
|
let inactive = res[1].data.data;
|
||||||
|
let removed = res[2].data.data;
|
||||||
|
|
||||||
|
if (Object.keys(active).length != 0) {
|
||||||
|
active.name = 'Active';
|
||||||
|
inactive.name = 'Inactive';
|
||||||
|
removed.name = 'Removed';
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalData = [active, inactive, removed];
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
data: finalData,
|
||||||
|
fields: keys,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
handleApiError(
|
||||||
|
error,
|
||||||
|
'Error occurred while trying to get device count.',
|
||||||
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { reportData } = this.props.location;
|
const { durationMode } = this.state;
|
||||||
|
|
||||||
|
const ds = new DataSet();
|
||||||
|
const dv = ds.createView().source(this.state.data);
|
||||||
|
dv.transform({
|
||||||
|
type: 'fold',
|
||||||
|
fields: this.state.fields,
|
||||||
|
key: 'Time',
|
||||||
|
value: 'Number of Devices',
|
||||||
|
});
|
||||||
|
|
||||||
const params = { ...this.state.paramsObject };
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<PageHeader style={{ paddingTop: 0 }}>
|
<PageHeader style={{ paddingTop: 0 }}>
|
||||||
@ -75,45 +185,63 @@ class DeviceStatusReport extends React.Component {
|
|||||||
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
<div className="wrap" style={{ marginBottom: '10px' }}>
|
<div className="wrap" style={{ marginBottom: '10px' }}>
|
||||||
<h3>Summary of enrollments</h3>
|
<h3>Device Status Report</h3>
|
||||||
<div style={{ marginBottom: '10px' }}>
|
|
||||||
<Select
|
|
||||||
defaultValue="android"
|
|
||||||
style={{ width: 120, marginRight: 10 }}
|
|
||||||
>
|
|
||||||
<Option value="android">Android</Option>
|
|
||||||
<Option value="ios">IOS</Option>
|
|
||||||
<Option value="windows">Windows</Option>
|
|
||||||
</Select>
|
|
||||||
<Button
|
|
||||||
onClick={this.onSubmitReport}
|
|
||||||
style={{ marginLeft: 10 }}
|
|
||||||
type="primary"
|
|
||||||
>
|
|
||||||
Generate Report
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<Radio.Group
|
||||||
<Card
|
onChange={this.handleDurationModeChange}
|
||||||
bordered={true}
|
defaultValue={'weekly'}
|
||||||
hoverable={true}
|
value={durationMode}
|
||||||
|
style={{ marginBottom: 8, marginRight: 5 }}
|
||||||
|
>
|
||||||
|
<Radio.Button value={'daily'}>Today</Radio.Button>
|
||||||
|
<Radio.Button value={'weekly'}>Last Week</Radio.Button>
|
||||||
|
<Radio.Button value={'monthly'}>Last Month</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
|
||||||
|
<Popover
|
||||||
|
trigger="hover"
|
||||||
|
content={
|
||||||
|
<div>
|
||||||
|
<DateRangePicker
|
||||||
|
updateDurationValue={this.updateDurationValue}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
visible={this.state.visible}
|
||||||
|
onVisibleChange={this.handlePopoverVisibleChange}
|
||||||
|
>
|
||||||
|
<Button style={{ marginRight: 10 }}>Custom Date</Button>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
marginBottom: 10,
|
marginTop: 10,
|
||||||
height: window.innerHeight * 0.5,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PieChart
|
<Chart height={400} data={dv} forceFit>
|
||||||
onClickPieChart={this.onClickPieChart}
|
<Axis name="Time" />
|
||||||
reportData={reportData}
|
<Axis name="Number of Devices" />
|
||||||
/>
|
<Legend />
|
||||||
</Card>
|
<Tooltip
|
||||||
</div>
|
crosshairs={{
|
||||||
|
type: 'y',
|
||||||
<div style={{ backgroundColor: '#ffffff', borderRadius: 5 }}>
|
}}
|
||||||
<ReportDeviceTable paramsObject={params} />
|
/>
|
||||||
|
<Geom
|
||||||
|
type="interval"
|
||||||
|
position="Time*Number of Devices"
|
||||||
|
color={'name'}
|
||||||
|
adjust={[
|
||||||
|
{
|
||||||
|
type: 'dodge',
|
||||||
|
marginRatio: 1 / 32,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Chart>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
@ -17,12 +17,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PageHeader, Breadcrumb, Icon, Card } from 'antd';
|
import { PageHeader, Breadcrumb, Icon, Radio, Popover, Button } from 'antd';
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import ReportDeviceTable from '../../../components/Devices/ReportDevicesTable';
|
|
||||||
import PieChart from '../../../components/Reports/Widgets/PieChart';
|
|
||||||
import { withConfigContext } from '../../../context/ConfigContext';
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import axios from 'axios';
|
||||||
|
import DateRangePicker from '../DateRangePicker';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { Chart, Geom, Axis, Tooltip, Legend } from 'bizcharts';
|
||||||
|
import DataSet from '@antv/data-set';
|
||||||
|
import { handleApiError } from '../../../js/Utils';
|
||||||
|
|
||||||
class EnrollmentTypeReport extends React.Component {
|
class EnrollmentTypeReport extends React.Component {
|
||||||
routes;
|
routes;
|
||||||
@ -30,32 +34,134 @@ class EnrollmentTypeReport extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.routes = props.routes;
|
this.routes = props.routes;
|
||||||
const { reportData } = this.props.location;
|
|
||||||
this.state = {
|
this.state = {
|
||||||
paramsObject: {
|
paramsObject: {
|
||||||
from: reportData.duration[0],
|
from: moment()
|
||||||
to: reportData.duration[1],
|
.subtract(7, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
to: moment().format('YYYY-MM-DD'),
|
||||||
},
|
},
|
||||||
|
data: [],
|
||||||
|
fields: [],
|
||||||
|
durationMode: 'weekly',
|
||||||
|
visible: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(reportData.duration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickPieChart = value => {
|
componentDidMount() {
|
||||||
const chartValue = value.data.point.item;
|
this.fetchData();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDurationModeChange = e => {
|
||||||
|
const durationMode = e.target.value;
|
||||||
|
switch (durationMode) {
|
||||||
|
case 'daily':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
moment()
|
||||||
|
.add(1, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'weekly':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(7, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'monthly':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(30, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.setState({ durationMode });
|
||||||
|
};
|
||||||
|
|
||||||
|
handlePopoverVisibleChange = visible => {
|
||||||
|
this.setState({ visible });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get modified value from datepicker and set it to paramsObject
|
||||||
|
updateDurationValue = (modifiedFromDate, modifiedToDate) => {
|
||||||
let tempParamObj = this.state.paramsObject;
|
let tempParamObj = this.state.paramsObject;
|
||||||
|
tempParamObj.from = modifiedFromDate;
|
||||||
console.log(chartValue);
|
tempParamObj.to = modifiedToDate;
|
||||||
|
|
||||||
tempParamObj.ownership = chartValue;
|
|
||||||
|
|
||||||
this.setState({ paramsObject: tempParamObj });
|
this.setState({ paramsObject: tempParamObj });
|
||||||
|
this.fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Call count APIs and get count for given parameters, then create data object to build pie chart
|
||||||
|
fetchData = () => {
|
||||||
|
this.setState({ loading: true });
|
||||||
|
|
||||||
|
const { paramsObject } = this.state;
|
||||||
|
const config = this.props.context;
|
||||||
|
|
||||||
|
const encodedExtraParams = Object.keys(paramsObject)
|
||||||
|
.map(key => key + '=' + paramsObject[key])
|
||||||
|
.join('&');
|
||||||
|
|
||||||
|
axios
|
||||||
|
.all([
|
||||||
|
axios.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/reports/count?ownership=BYOD&' +
|
||||||
|
encodedExtraParams,
|
||||||
|
'BYOD',
|
||||||
|
),
|
||||||
|
axios.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/reports/count?ownership=COPE&' +
|
||||||
|
encodedExtraParams,
|
||||||
|
'COPE',
|
||||||
|
),
|
||||||
|
])
|
||||||
|
.then(res => {
|
||||||
|
let keys = Object.keys(res[0].data.data);
|
||||||
|
let byod = res[0].data.data;
|
||||||
|
let cope = res[1].data.data;
|
||||||
|
if (Object.keys(byod).length != 0) {
|
||||||
|
byod.name = 'BYOD';
|
||||||
|
cope.name = 'COPE';
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalData = [byod, cope];
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
data: finalData,
|
||||||
|
fields: keys,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
handleApiError(
|
||||||
|
error,
|
||||||
|
'Error occurred while trying to get device count.',
|
||||||
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { reportData } = this.props.location;
|
const { durationMode } = this.state;
|
||||||
|
|
||||||
|
const ds = new DataSet();
|
||||||
|
const dv = ds.createView().source(this.state.data);
|
||||||
|
dv.transform({
|
||||||
|
type: 'fold',
|
||||||
|
fields: this.state.fields,
|
||||||
|
key: 'Time',
|
||||||
|
value: 'Number of Devices',
|
||||||
|
});
|
||||||
|
|
||||||
const params = { ...this.state.paramsObject };
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<PageHeader style={{ paddingTop: 0 }}>
|
<PageHeader style={{ paddingTop: 0 }}>
|
||||||
@ -68,28 +174,62 @@ class EnrollmentTypeReport extends React.Component {
|
|||||||
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
<div className="wrap" style={{ marginBottom: '10px' }}>
|
<div className="wrap" style={{ marginBottom: '10px' }}>
|
||||||
<h3>Summary of enrollments</h3>
|
<h3>Device Enrollment Type Report</h3>
|
||||||
</div>
|
<Radio.Group
|
||||||
|
onChange={this.handleDurationModeChange}
|
||||||
|
defaultValue={'weekly'}
|
||||||
|
value={durationMode}
|
||||||
|
style={{ marginBottom: 8, marginRight: 5 }}
|
||||||
|
>
|
||||||
|
<Radio.Button value={'daily'}>Today</Radio.Button>
|
||||||
|
<Radio.Button value={'weekly'}>Last Week</Radio.Button>
|
||||||
|
<Radio.Button value={'monthly'}>Last Month</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
|
||||||
<div>
|
<Popover
|
||||||
<Card
|
trigger="hover"
|
||||||
bordered={true}
|
content={
|
||||||
hoverable={true}
|
<div>
|
||||||
|
<DateRangePicker
|
||||||
|
updateDurationValue={this.updateDurationValue}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
visible={this.state.visible}
|
||||||
|
onVisibleChange={this.handlePopoverVisibleChange}
|
||||||
|
>
|
||||||
|
<Button style={{ marginRight: 10 }}>Custom Date</Button>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
marginBottom: 10,
|
marginTop: 10,
|
||||||
height: window.innerHeight * 0.5,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PieChart
|
<Chart height={400} data={dv} forceFit>
|
||||||
onClickPieChart={this.onClickPieChart}
|
<Axis name="Time" />
|
||||||
reportData={reportData}
|
<Axis name="Number of Devices" />
|
||||||
/>
|
<Legend />
|
||||||
</Card>
|
<Tooltip
|
||||||
</div>
|
crosshairs={{
|
||||||
|
type: 'y',
|
||||||
<div style={{ backgroundColor: '#ffffff', borderRadius: 5 }}>
|
}}
|
||||||
<ReportDeviceTable paramsObject={params} />
|
/>
|
||||||
|
<Geom
|
||||||
|
type="interval"
|
||||||
|
position="Time*Number of Devices"
|
||||||
|
color={'name'}
|
||||||
|
adjust={[
|
||||||
|
{
|
||||||
|
type: 'dodge',
|
||||||
|
marginRatio: 1 / 32,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Chart>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
|
||||||
* Version 2.0 (the "License"); you may not use this file except
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
@ -17,12 +17,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PageHeader, Breadcrumb, Icon, Card } from 'antd';
|
import { PageHeader, Breadcrumb, Icon, Radio, Popover, Button } from 'antd';
|
||||||
|
|
||||||
import { Link, Redirect } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import ReportDeviceTable from '../../../components/Devices/ReportDevicesTable';
|
|
||||||
import PieChart from '../../../components/Reports/Widgets/PieChart';
|
|
||||||
import { withConfigContext } from '../../../context/ConfigContext';
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import axios from 'axios';
|
||||||
|
import DateRangePicker from '../DateRangePicker';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { Chart, Geom, Axis, Tooltip, Legend } from 'bizcharts';
|
||||||
|
import DataSet from '@antv/data-set';
|
||||||
|
import { handleApiError } from '../../../js/Utils';
|
||||||
|
|
||||||
class EnrollmentsVsUnenrollmentsReport extends React.Component {
|
class EnrollmentsVsUnenrollmentsReport extends React.Component {
|
||||||
routes;
|
routes;
|
||||||
@ -30,94 +34,208 @@ class EnrollmentsVsUnenrollmentsReport extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.routes = props.routes;
|
this.routes = props.routes;
|
||||||
const { reportData } = this.props.location;
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
paramsObject: {
|
paramsObject: {
|
||||||
from: reportData ? reportData.duration[0] : '2019-01-01',
|
from: moment()
|
||||||
to: reportData ? reportData.duration[1] : '2019-01-01',
|
.subtract(7, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
to: moment().format('YYYY-MM-DD'),
|
||||||
},
|
},
|
||||||
redirect: false,
|
data: [],
|
||||||
|
fields: [],
|
||||||
|
durationMode: 'weekly',
|
||||||
|
visible: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.redirectToHome();
|
|
||||||
console.log(this.state.paramsObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redirectToHome = () => {
|
componentDidMount() {
|
||||||
return <Redirect to="/entgra" />;
|
this.fetchData();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDurationModeChange = e => {
|
||||||
|
const durationMode = e.target.value;
|
||||||
|
switch (durationMode) {
|
||||||
|
case 'daily':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
moment()
|
||||||
|
.add(1, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'weekly':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(7, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'monthly':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(30, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.setState({ durationMode });
|
||||||
};
|
};
|
||||||
|
|
||||||
onClickPieChart = value => {
|
handlePopoverVisibleChange = visible => {
|
||||||
const chartValue = value.data.point.item;
|
this.setState({ visible });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get modified value from datepicker and set it to paramsObject
|
||||||
|
updateDurationValue = (modifiedFromDate, modifiedToDate) => {
|
||||||
let tempParamObj = this.state.paramsObject;
|
let tempParamObj = this.state.paramsObject;
|
||||||
|
tempParamObj.from = modifiedFromDate;
|
||||||
console.log(chartValue);
|
tempParamObj.to = modifiedToDate;
|
||||||
|
|
||||||
if (chartValue === 'Enrollments') {
|
|
||||||
tempParamObj.status = 'ACTIVE&status=INACTIVE';
|
|
||||||
} else {
|
|
||||||
tempParamObj.status = 'REMOVED';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ paramsObject: tempParamObj });
|
this.setState({ paramsObject: tempParamObj });
|
||||||
|
this.fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Call count APIs and get count for given parameters, then create data object to build pie chart
|
||||||
|
fetchData = () => {
|
||||||
|
this.setState({ loading: true });
|
||||||
|
|
||||||
|
const { paramsObject } = this.state;
|
||||||
|
const config = this.props.context;
|
||||||
|
|
||||||
|
const encodedExtraParams = Object.keys(paramsObject)
|
||||||
|
.map(key => key + '=' + paramsObject[key])
|
||||||
|
.join('&');
|
||||||
|
|
||||||
|
axios
|
||||||
|
.all([
|
||||||
|
axios.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/reports/count?status=ACTIVE&status=INACTIVE&' +
|
||||||
|
encodedExtraParams,
|
||||||
|
'Enrollments',
|
||||||
|
),
|
||||||
|
axios.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/reports/count?status=REMOVED&' +
|
||||||
|
encodedExtraParams,
|
||||||
|
'Unenrollments',
|
||||||
|
),
|
||||||
|
])
|
||||||
|
.then(res => {
|
||||||
|
let keys = Object.keys(res[0].data.data);
|
||||||
|
let enrollments = res[0].data.data;
|
||||||
|
let unenrollments = res[1].data.data;
|
||||||
|
if (Object.keys(enrollments).length != 0) {
|
||||||
|
enrollments.name = 'Enrollments';
|
||||||
|
unenrollments.name = 'Unenrollments';
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalData = [enrollments, unenrollments];
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
data: finalData,
|
||||||
|
fields: keys,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
handleApiError(
|
||||||
|
error,
|
||||||
|
'Error occurred while trying to get device count.',
|
||||||
|
);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { reportData } = this.props.location;
|
const { durationMode } = this.state;
|
||||||
|
|
||||||
console.log('======');
|
const ds = new DataSet();
|
||||||
console.log(reportData);
|
const dv = ds.createView().source(this.state.data);
|
||||||
console.log('======');
|
dv.transform({
|
||||||
|
type: 'fold',
|
||||||
|
fields: this.state.fields,
|
||||||
|
key: 'Time',
|
||||||
|
value: 'Number of Devices',
|
||||||
|
});
|
||||||
|
|
||||||
let reportDataClone = {
|
|
||||||
params: ['ACTIVE'],
|
|
||||||
duration: ['2020-01-01', '2020-01-01'],
|
|
||||||
};
|
|
||||||
|
|
||||||
const params = { ...this.state.paramsObject };
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<PageHeader style={{ paddingTop: 0 }}>
|
||||||
{!reportData ? (
|
<Breadcrumb style={{ paddingBottom: 16 }}>
|
||||||
<Redirect to="/entgra/reports" />
|
<Breadcrumb.Item>
|
||||||
) : (
|
<Link to="/entgra">
|
||||||
<PageHeader style={{ paddingTop: 0 }}>
|
<Icon type="home" /> Home
|
||||||
<Breadcrumb style={{ paddingBottom: 16 }}>
|
</Link>
|
||||||
<Breadcrumb.Item>
|
</Breadcrumb.Item>
|
||||||
<Link to="/entgra">
|
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
||||||
<Icon type="home" /> Home
|
</Breadcrumb>
|
||||||
</Link>
|
<div className="wrap" style={{ marginBottom: '10px' }}>
|
||||||
</Breadcrumb.Item>
|
<h3>Enrollments vs Unenrollments Report</h3>
|
||||||
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
|
||||||
</Breadcrumb>
|
|
||||||
<div className="wrap" style={{ marginBottom: '10px' }}>
|
|
||||||
<h3>Summary of enrollments</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<Radio.Group
|
||||||
<Card
|
onChange={this.handleDurationModeChange}
|
||||||
bordered={true}
|
defaultValue={'weekly'}
|
||||||
hoverable={true}
|
value={durationMode}
|
||||||
style={{
|
style={{ marginBottom: 8, marginRight: 5 }}
|
||||||
borderRadius: 5,
|
>
|
||||||
marginBottom: 10,
|
<Radio.Button value={'daily'}>Today</Radio.Button>
|
||||||
height: window.innerHeight * 0.5,
|
<Radio.Button value={'weekly'}>Last Week</Radio.Button>
|
||||||
}}
|
<Radio.Button value={'monthly'}>Last Month</Radio.Button>
|
||||||
>
|
</Radio.Group>
|
||||||
<PieChart
|
|
||||||
onClickPieChart={this.onClickPieChart}
|
<Popover
|
||||||
reportData={reportData ? reportData : reportDataClone}
|
trigger="hover"
|
||||||
|
content={
|
||||||
|
<div>
|
||||||
|
<DateRangePicker
|
||||||
|
updateDurationValue={this.updateDurationValue}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</div>
|
||||||
</div>
|
}
|
||||||
|
visible={this.state.visible}
|
||||||
|
onVisibleChange={this.handlePopoverVisibleChange}
|
||||||
|
>
|
||||||
|
<Button style={{ marginRight: 10 }}>Custom Date</Button>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
<div style={{ backgroundColor: '#ffffff', borderRadius: 5 }}>
|
<div
|
||||||
<ReportDeviceTable paramsObject={params} />
|
style={{
|
||||||
</div>
|
backgroundColor: '#ffffff',
|
||||||
</PageHeader>
|
borderRadius: 5,
|
||||||
)}
|
marginTop: 10,
|
||||||
</div>
|
}}
|
||||||
|
>
|
||||||
|
<Chart height={400} data={dv} forceFit>
|
||||||
|
<Axis name="Time" />
|
||||||
|
<Axis name="Number of Devices" />
|
||||||
|
<Legend />
|
||||||
|
<Tooltip
|
||||||
|
crosshairs={{
|
||||||
|
type: 'y',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Geom
|
||||||
|
type="interval"
|
||||||
|
position="Time*Number of Devices"
|
||||||
|
color={'name'}
|
||||||
|
adjust={[
|
||||||
|
{
|
||||||
|
type: 'dodge',
|
||||||
|
marginRatio: 1 / 32,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Chart>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PageHeader>
|
||||||
|
<div
|
||||||
|
style={{ background: '#f0f2f5', padding: 24, minHeight: 720 }}
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { PageHeader, Breadcrumb, Icon, Radio, Popover, Button } from 'antd';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import PolicyDevicesTable from '../Widgets/PolicyDevicesTable';
|
||||||
|
import moment from 'moment';
|
||||||
|
import DateRangePicker from '../DateRangePicker';
|
||||||
|
import SelectPolicyDropDown from '../Widgets/SelectPolicyDropDown';
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
let config = null;
|
||||||
|
|
||||||
|
class PolicyReport extends React.Component {
|
||||||
|
routes;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.routes = props.routes;
|
||||||
|
config = this.props.context;
|
||||||
|
this.state = {
|
||||||
|
durationMode: 'weekly',
|
||||||
|
isCompliant: true,
|
||||||
|
// This object contains parameters which pass into API endpoint
|
||||||
|
policyReportData: {
|
||||||
|
from: moment()
|
||||||
|
.subtract(7, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
to: moment().format('YYYY-MM-DD'),
|
||||||
|
},
|
||||||
|
visible: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleModeChange = e => {
|
||||||
|
const isCompliant = e.target.value;
|
||||||
|
this.setState({ isCompliant });
|
||||||
|
};
|
||||||
|
|
||||||
|
handleDurationModeChange = e => {
|
||||||
|
const durationMode = e.target.value;
|
||||||
|
switch (durationMode) {
|
||||||
|
case 'daily':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(1, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'weekly':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(7, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'monthly':
|
||||||
|
this.updateDurationValue(
|
||||||
|
moment()
|
||||||
|
.subtract(30, 'days')
|
||||||
|
.format('YYYY-MM-DD'),
|
||||||
|
moment().format('YYYY-MM-DD'),
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.setState({ durationMode });
|
||||||
|
};
|
||||||
|
|
||||||
|
hidePopover = () => {
|
||||||
|
this.setState({
|
||||||
|
visible: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handlePopoverVisibleChange = visible => {
|
||||||
|
this.setState({ visible });
|
||||||
|
};
|
||||||
|
|
||||||
|
getPolicyId = policyId => {
|
||||||
|
let tempParamObj = this.state.policyReportData;
|
||||||
|
if (policyId === 'all') {
|
||||||
|
delete tempParamObj.policy;
|
||||||
|
} else {
|
||||||
|
tempParamObj.policy = policyId;
|
||||||
|
}
|
||||||
|
this.setState({ policyReportData: tempParamObj });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get modified value from datepicker and set it to paramsObject
|
||||||
|
updateDurationValue = (modifiedFromDate, modifiedToDate) => {
|
||||||
|
let tempParamObj = this.state.policyReportData;
|
||||||
|
tempParamObj.from = modifiedFromDate;
|
||||||
|
tempParamObj.to = modifiedToDate;
|
||||||
|
this.setState({ policyReportData: tempParamObj });
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { isCompliant, durationMode } = this.state;
|
||||||
|
const policyData = { ...this.state.policyReportData };
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<PageHeader style={{ paddingTop: 0 }}>
|
||||||
|
<Breadcrumb style={{ paddingBottom: 16 }}>
|
||||||
|
<Breadcrumb.Item>
|
||||||
|
<Link to="/entgra">
|
||||||
|
<Icon type="home" /> Home
|
||||||
|
</Link>
|
||||||
|
</Breadcrumb.Item>
|
||||||
|
<Breadcrumb.Item>Report</Breadcrumb.Item>
|
||||||
|
</Breadcrumb>
|
||||||
|
<div className="wrap" style={{ marginBottom: '10px' }}>
|
||||||
|
<h3>Policy Report</h3>
|
||||||
|
|
||||||
|
<Radio.Group
|
||||||
|
onChange={this.handleModeChange}
|
||||||
|
defaultValue={true}
|
||||||
|
value={isCompliant}
|
||||||
|
style={{ marginBottom: 8, marginRight: 10 }}
|
||||||
|
>
|
||||||
|
<Radio.Button value={true}>Policy Compliant Devices</Radio.Button>
|
||||||
|
<Radio.Button value={false}>
|
||||||
|
Policy Non-Compliant Devices
|
||||||
|
</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
|
||||||
|
<Radio.Group
|
||||||
|
onChange={this.handleDurationModeChange}
|
||||||
|
defaultValue={'weekly'}
|
||||||
|
value={durationMode}
|
||||||
|
style={{ marginBottom: 8, marginRight: 5 }}
|
||||||
|
>
|
||||||
|
<Radio.Button value={'daily'}>Today</Radio.Button>
|
||||||
|
<Radio.Button value={'weekly'}>Last Week</Radio.Button>
|
||||||
|
<Radio.Button value={'monthly'}>Last Month</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
<Popover
|
||||||
|
trigger="hover"
|
||||||
|
content={
|
||||||
|
<div>
|
||||||
|
<DateRangePicker
|
||||||
|
updateDurationValue={this.updateDurationValue}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
visible={this.state.visible}
|
||||||
|
onVisibleChange={this.handlePopoverVisibleChange}
|
||||||
|
>
|
||||||
|
<Button style={{ marginRight: 10 }}>Custom Date</Button>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
<SelectPolicyDropDown getPolicyId={this.getPolicyId} />
|
||||||
|
|
||||||
|
<div style={{ backgroundColor: '#ffffff', borderRadius: 5 }}>
|
||||||
|
<PolicyDevicesTable
|
||||||
|
policyReportData={policyData}
|
||||||
|
isCompliant={isCompliant}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PageHeader>
|
||||||
|
<div
|
||||||
|
style={{ background: '#f0f2f5', padding: 24, minHeight: 720 }}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(PolicyReport);
|
||||||
@ -33,8 +33,6 @@ class CountWidget extends React.Component {
|
|||||||
<b>{data.item}</b>
|
<b>{data.item}</b>
|
||||||
</h2>
|
</h2>
|
||||||
<h1>{data.count}</h1>
|
<h1>{data.count}</h1>
|
||||||
{/* <p>{data.duration}</p>*/}
|
|
||||||
{/* <ReportFilterModal/>*/}
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Button, message, Modal, notification, List, Typography } from 'antd';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
|
||||||
|
class FeatureListModal extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
modalVisible: false,
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
features: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchViolatedFeatures = id => {
|
||||||
|
const config = this.props.context;
|
||||||
|
|
||||||
|
axios
|
||||||
|
.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/devices/' +
|
||||||
|
id +
|
||||||
|
'/features',
|
||||||
|
)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.setState({
|
||||||
|
features: JSON.parse(res.data.data),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
||||||
|
// todo display a popop with error
|
||||||
|
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 load non compliance feature list.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
openModal = () => {
|
||||||
|
this.fetchViolatedFeatures(this.props.id);
|
||||||
|
this.setState({
|
||||||
|
modalVisible: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleOk = e => {
|
||||||
|
this.setState({
|
||||||
|
modalVisible: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { features, modalVisible } = this.state;
|
||||||
|
|
||||||
|
let featureList = features.map(data => (
|
||||||
|
<List.Item key={data.featureCodes}>
|
||||||
|
<Typography.Text key={data.featureCodes} mark>
|
||||||
|
{data.featureCode}
|
||||||
|
</Typography.Text>
|
||||||
|
</List.Item>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size={'small'}
|
||||||
|
icon="book"
|
||||||
|
onClick={this.openModal}
|
||||||
|
>
|
||||||
|
Violated Features
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Modal
|
||||||
|
title="VIOLATED FEATURES"
|
||||||
|
width="40%"
|
||||||
|
visible={modalVisible}
|
||||||
|
onOk={this.handleOk}
|
||||||
|
footer={[
|
||||||
|
<Button key="submit" type="primary" onClick={this.handleOk}>
|
||||||
|
OK
|
||||||
|
</Button>,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<List size="large" bordered>
|
||||||
|
{featureList}
|
||||||
|
</List>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(FeatureListModal);
|
||||||
@ -39,8 +39,6 @@ class PieChart extends React.Component {
|
|||||||
duration: reportData.duration,
|
duration: reportData.duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(urlSet);
|
|
||||||
|
|
||||||
if (reportData.params[0] === 'Enrollments') {
|
if (reportData.params[0] === 'Enrollments') {
|
||||||
this.getEnrollmentsVsUnenrollmentsCount(params, urlSet);
|
this.getEnrollmentsVsUnenrollmentsCount(params, urlSet);
|
||||||
} else if (reportData.params[0] === 'BYOD') {
|
} else if (reportData.params[0] === 'BYOD') {
|
||||||
@ -50,10 +48,6 @@ class PieChart extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clicked = () => {
|
|
||||||
console.log('Clicked...!!');
|
|
||||||
};
|
|
||||||
|
|
||||||
onChartChange = data => {
|
onChartChange = data => {
|
||||||
this.props.onClickPieChart(data);
|
this.props.onClickPieChart(data);
|
||||||
};
|
};
|
||||||
@ -66,8 +60,6 @@ class PieChart extends React.Component {
|
|||||||
|
|
||||||
let { statArray } = this.state;
|
let { statArray } = this.state;
|
||||||
|
|
||||||
console.log(urlSet);
|
|
||||||
|
|
||||||
const urlArray = [];
|
const urlArray = [];
|
||||||
|
|
||||||
urlSet.paramsList.map(data => {
|
urlSet.paramsList.map(data => {
|
||||||
@ -76,7 +68,6 @@ class PieChart extends React.Component {
|
|||||||
from: urlSet.duration[0],
|
from: urlSet.duration[0],
|
||||||
to: urlSet.duration[1],
|
to: urlSet.duration[1],
|
||||||
};
|
};
|
||||||
// console.log(paramsObj)
|
|
||||||
const encodedExtraParams = Object.keys(paramsObj)
|
const encodedExtraParams = Object.keys(paramsObj)
|
||||||
.map(key => key + '=' + paramsObj[key])
|
.map(key => key + '=' + paramsObj[key])
|
||||||
.join('&');
|
.join('&');
|
||||||
@ -90,8 +81,6 @@ class PieChart extends React.Component {
|
|||||||
urlArray.push(axios.get(apiUrl, data));
|
urlArray.push(axios.get(apiUrl, data));
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(urlArray);
|
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.all(urlArray)
|
.all(urlArray)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
@ -128,8 +117,6 @@ class PieChart extends React.Component {
|
|||||||
|
|
||||||
let { statArray } = this.state;
|
let { statArray } = this.state;
|
||||||
|
|
||||||
console.log(urlSet);
|
|
||||||
|
|
||||||
const urlArray = [];
|
const urlArray = [];
|
||||||
|
|
||||||
urlSet.paramsList.map(data => {
|
urlSet.paramsList.map(data => {
|
||||||
@ -161,8 +148,6 @@ class PieChart extends React.Component {
|
|||||||
urlArray.push(axios.get(apiUrl, data));
|
urlArray.push(axios.get(apiUrl, data));
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(urlArray);
|
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.all(urlArray)
|
.all(urlArray)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
@ -199,8 +184,6 @@ class PieChart extends React.Component {
|
|||||||
|
|
||||||
let { statArray } = this.state;
|
let { statArray } = this.state;
|
||||||
|
|
||||||
console.log(urlSet);
|
|
||||||
|
|
||||||
const urlArray = [];
|
const urlArray = [];
|
||||||
|
|
||||||
urlSet.paramsList.map(data => {
|
urlSet.paramsList.map(data => {
|
||||||
@ -222,8 +205,6 @@ class PieChart extends React.Component {
|
|||||||
urlArray.push(axios.get(apiUrl, data));
|
urlArray.push(axios.get(apiUrl, data));
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(urlArray);
|
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.all(urlArray)
|
.all(urlArray)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
|
|||||||
@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
import { Button, Icon, Table, Tooltip } from 'antd';
|
||||||
|
import TimeAgo from 'javascript-time-ago';
|
||||||
|
import moment from 'moment';
|
||||||
|
// Load locale-specific relative date/time formatting rules.
|
||||||
|
import en from 'javascript-time-ago/locale/en';
|
||||||
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import FeatureListModal from './FeatureListModal';
|
||||||
|
import { handleApiError } from '../../../js/Utils';
|
||||||
|
|
||||||
|
let config = null;
|
||||||
|
|
||||||
|
// Table columns for non compliant devices
|
||||||
|
const columnsNonCompliant = [
|
||||||
|
{
|
||||||
|
title: 'Device',
|
||||||
|
dataIndex: 'deviceName',
|
||||||
|
width: 100,
|
||||||
|
sorter: (a, b) => a.deviceName.localeCompare(b.deviceName),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Type',
|
||||||
|
dataIndex: 'deviceType',
|
||||||
|
key: 'type',
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
|
render: type => {
|
||||||
|
const defaultPlatformIcons = config.defaultPlatformIcons;
|
||||||
|
let icon = defaultPlatformIcons.default.icon;
|
||||||
|
let color = defaultPlatformIcons.default.color;
|
||||||
|
let theme = defaultPlatformIcons.default.theme;
|
||||||
|
|
||||||
|
if (defaultPlatformIcons.hasOwnProperty(type)) {
|
||||||
|
icon = defaultPlatformIcons[type].icon;
|
||||||
|
color = defaultPlatformIcons[type].color;
|
||||||
|
theme = defaultPlatformIcons[type].theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span style={{ fontSize: 20, color: color, textAlign: 'center' }}>
|
||||||
|
<Icon type={icon} theme={theme} />
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Owner',
|
||||||
|
dataIndex: 'owner',
|
||||||
|
key: 'owner',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Policy',
|
||||||
|
dataIndex: 'policyName',
|
||||||
|
key: 'policy',
|
||||||
|
sorter: (a, b) => a.policyName.localeCompare(b.policyName),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Last Failed Time',
|
||||||
|
dataIndex: 'lastFailedTime',
|
||||||
|
key: 'lastFailedTime',
|
||||||
|
render: data => {
|
||||||
|
if (data) {
|
||||||
|
return (
|
||||||
|
<Tooltip title={new Date(data).toString()}>
|
||||||
|
{moment(data).fromNow()}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return 'Not available';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Last Success Time',
|
||||||
|
dataIndex: 'lastSucceededTime',
|
||||||
|
key: 'lastSucceededTime',
|
||||||
|
render: data => {
|
||||||
|
if (data) {
|
||||||
|
return (
|
||||||
|
<Tooltip title={new Date(data).toString()}>
|
||||||
|
{moment(data).fromNow()}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return 'Not available';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Attempts',
|
||||||
|
dataIndex: 'attempts',
|
||||||
|
key: 'attempts',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Violated Features',
|
||||||
|
dataIndex: 'id',
|
||||||
|
key: 'violated_features',
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
|
render: id => <FeatureListModal id={id} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Device Details',
|
||||||
|
dataIndex: 'id',
|
||||||
|
key: 'device_details',
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
|
render: id => (
|
||||||
|
<Button type="primary" size={'small'} icon="book">
|
||||||
|
Device Details
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Table columns for compliant devices
|
||||||
|
const columnsCompliant = [
|
||||||
|
{
|
||||||
|
title: 'Device',
|
||||||
|
dataIndex: 'deviceName',
|
||||||
|
width: 100,
|
||||||
|
sorter: (a, b) => a.deviceName.localeCompare(b.deviceName),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Type',
|
||||||
|
dataIndex: 'deviceType',
|
||||||
|
key: 'type',
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
|
render: type => {
|
||||||
|
const defaultPlatformIcons = config.defaultPlatformIcons;
|
||||||
|
let icon = defaultPlatformIcons.default.icon;
|
||||||
|
let color = defaultPlatformIcons.default.color;
|
||||||
|
let theme = defaultPlatformIcons.default.theme;
|
||||||
|
|
||||||
|
if (defaultPlatformIcons.hasOwnProperty(type)) {
|
||||||
|
icon = defaultPlatformIcons[type].icon;
|
||||||
|
color = defaultPlatformIcons[type].color;
|
||||||
|
theme = defaultPlatformIcons[type].theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span style={{ fontSize: 20, color: color, textAlign: 'center' }}>
|
||||||
|
<Icon type={icon} theme={theme} />
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Owner',
|
||||||
|
dataIndex: 'owner',
|
||||||
|
key: 'owner',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Policy',
|
||||||
|
dataIndex: 'policyName',
|
||||||
|
key: 'policy',
|
||||||
|
sorter: (a, b) => a.policyName.localeCompare(b.policyName),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Last Success Time',
|
||||||
|
dataIndex: 'lastSucceededTime',
|
||||||
|
key: 'lastSucceededTime',
|
||||||
|
render: data => {
|
||||||
|
if (data) {
|
||||||
|
return (
|
||||||
|
<Tooltip title={new Date(data).toString()}>
|
||||||
|
{moment(data).fromNow()}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return 'Not available';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Attempts',
|
||||||
|
dataIndex: 'attempts',
|
||||||
|
key: 'attempts',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Device Details',
|
||||||
|
dataIndex: 'id',
|
||||||
|
key: 'device_details',
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
|
render: id => (
|
||||||
|
<Button type="primary" size={'small'} icon="book">
|
||||||
|
Device Details
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
class PolicyDevicesTable extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
config = this.props.context;
|
||||||
|
TimeAgo.addLocale(en);
|
||||||
|
this.state = {
|
||||||
|
data: [],
|
||||||
|
pagination: {},
|
||||||
|
loading: false,
|
||||||
|
selectedRows: [],
|
||||||
|
paramsObj: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rowSelection = {
|
||||||
|
onChange: (selectedRowKeys, selectedRows) => {
|
||||||
|
this.setState({
|
||||||
|
selectedRows: selectedRows,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fetchData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rerender component when parameters change
|
||||||
|
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||||
|
if (
|
||||||
|
prevProps.isCompliant !== this.props.isCompliant ||
|
||||||
|
prevProps.policyReportData !== this.props.policyReportData
|
||||||
|
) {
|
||||||
|
this.fetchData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch data from api
|
||||||
|
fetchData = (params = {}) => {
|
||||||
|
// const policyReportData = this.props;
|
||||||
|
this.setState({ loading: true });
|
||||||
|
// get current page
|
||||||
|
const currentPage = params.hasOwnProperty('page') ? params.page : 1;
|
||||||
|
|
||||||
|
let extraParams;
|
||||||
|
|
||||||
|
if (this.props.policyReportData.policy) {
|
||||||
|
extraParams = {
|
||||||
|
policy: this.props.policyReportData.policy,
|
||||||
|
from: this.props.policyReportData.from,
|
||||||
|
to: this.props.policyReportData.to,
|
||||||
|
offset: 10 * (currentPage - 1), // calculate the offset
|
||||||
|
limit: 10,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
extraParams = {
|
||||||
|
from: this.props.policyReportData.from,
|
||||||
|
to: this.props.policyReportData.to,
|
||||||
|
offset: 10 * (currentPage - 1), // calculate the offset
|
||||||
|
limit: 10,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const encodedExtraParams = Object.keys(extraParams)
|
||||||
|
.map(key => key + '=' + extraParams[key])
|
||||||
|
.join('&');
|
||||||
|
|
||||||
|
let apiUrl;
|
||||||
|
|
||||||
|
if (this.props.isCompliant) {
|
||||||
|
apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/devices/compliance/true?' +
|
||||||
|
encodedExtraParams;
|
||||||
|
} else {
|
||||||
|
apiUrl =
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/devices/compliance/false?' +
|
||||||
|
encodedExtraParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send request to the invoker
|
||||||
|
axios
|
||||||
|
.get(apiUrl)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
const pagination = { ...this.state.pagination };
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
data: res.data.data,
|
||||||
|
pagination,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
handleApiError(error, 'Error occurred while trying to load devices.');
|
||||||
|
this.setState({ loading: false });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleTableChange = (pagination, filters, sorter) => {
|
||||||
|
const pager = { ...this.state.pagination };
|
||||||
|
pager.current = pagination.current;
|
||||||
|
this.setState({
|
||||||
|
pagination: pager,
|
||||||
|
});
|
||||||
|
this.fetchData({
|
||||||
|
results: pagination.pageSize,
|
||||||
|
page: pagination.current,
|
||||||
|
sortField: sorter.field,
|
||||||
|
sortOrder: sorter.order,
|
||||||
|
...filters,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let { data, pagination, loading } = this.state;
|
||||||
|
const { isCompliant } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
columns={isCompliant ? columnsCompliant : columnsNonCompliant}
|
||||||
|
rowKey={record => record.id}
|
||||||
|
dataSource={data.complianceData}
|
||||||
|
pagination={{
|
||||||
|
...pagination,
|
||||||
|
size: 'small',
|
||||||
|
// position: "top",
|
||||||
|
total: data.count,
|
||||||
|
showTotal: (total, range) =>
|
||||||
|
`showing ${range[0]}-${range[1]} of ${total} devices`,
|
||||||
|
// showQuickJumper: true
|
||||||
|
}}
|
||||||
|
loading={loading}
|
||||||
|
onChange={this.handleTableChange}
|
||||||
|
rowSelection={this.rowSelection}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(PolicyDevicesTable);
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Select, message, notification } from 'antd';
|
||||||
|
|
||||||
|
import { withConfigContext } from '../../../context/ConfigContext';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
|
class SelectPolicyDropDown extends React.Component {
|
||||||
|
routes;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.routes = props.routes;
|
||||||
|
this.state = {
|
||||||
|
isOpen: false,
|
||||||
|
currentPage: 1,
|
||||||
|
data: [],
|
||||||
|
pagination: {},
|
||||||
|
loading: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.fetchPolicies();
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch data from api
|
||||||
|
fetchPolicies = (params = {}) => {
|
||||||
|
const config = this.props.context;
|
||||||
|
this.setState({ loading: true });
|
||||||
|
|
||||||
|
// send request to the invokerss
|
||||||
|
axios
|
||||||
|
.get(
|
||||||
|
window.location.origin +
|
||||||
|
config.serverConfig.invoker.uri +
|
||||||
|
config.serverConfig.invoker.deviceMgt +
|
||||||
|
'/policies',
|
||||||
|
)
|
||||||
|
.then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
data: JSON.parse(res.data.data),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
||||||
|
// todo display a popop with error
|
||||||
|
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 load policies.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ loading: false });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleChange = value => {
|
||||||
|
this.props.getPolicyId(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let item;
|
||||||
|
if (this.state.data) {
|
||||||
|
item = this.state.data.map(data => (
|
||||||
|
<Select.Option value={data.id} key={data.id}>
|
||||||
|
{data.profile.profileName}
|
||||||
|
</Select.Option>
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
defaultValue="all"
|
||||||
|
style={{ width: 200 }}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
>
|
||||||
|
<Option value="all">All</Option>
|
||||||
|
{item}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withConfigContext(SelectPolicyDropDown);
|
||||||
@ -23,21 +23,14 @@ import App from './App';
|
|||||||
import Login from './pages/Login';
|
import Login from './pages/Login';
|
||||||
import Dashboard from './pages/Dashboard/Dashboard';
|
import Dashboard from './pages/Dashboard/Dashboard';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import Devices from './pages/Dashboard/Devices/Devices';
|
|
||||||
import Reports from './pages/Dashboard/Reports/Reports';
|
import Reports from './pages/Dashboard/Reports/Reports';
|
||||||
import Geo from './pages/Dashboard/Geo/Geo';
|
import Geo from './pages/Dashboard/Geo/Geo';
|
||||||
import Groups from './pages/Dashboard/Groups/Groups';
|
|
||||||
import Users from './pages/Dashboard/Users/Users';
|
|
||||||
import Policies from './pages/Dashboard/Policies/Policies';
|
|
||||||
import Roles from './pages/Dashboard/Roles/Roles';
|
|
||||||
import DeviceTypes from './pages/Dashboard/DeviceTypes/DeviceTypes';
|
|
||||||
import DeviceEnroll from './pages/Dashboard/Devices/DeviceEnroll';
|
|
||||||
import AddNewPolicy from './pages/Dashboard/Policies/AddNewPolicy';
|
|
||||||
import Certificates from './pages/Dashboard/Configurations/Certificates/Certificates';
|
|
||||||
import ReportDurationItemList from './pages/Dashboard/Reports/ReportDurationItemList';
|
|
||||||
import EnrollmentsVsUnenrollmentsReport from './components/Reports/Templates/EnrollmentsVsUnenrollmentsReport';
|
import EnrollmentsVsUnenrollmentsReport from './components/Reports/Templates/EnrollmentsVsUnenrollmentsReport';
|
||||||
import EnrollmentTypeReport from './components/Reports/Templates/EnrollmentTypeReport';
|
import EnrollmentTypeReport from './components/Reports/Templates/EnrollmentTypeReport';
|
||||||
|
import PolicyReport from './components/Reports/Templates/PolicyReport';
|
||||||
import DeviceStatusReport from './components/Reports/Templates/DeviceStatusReport';
|
import DeviceStatusReport from './components/Reports/Templates/DeviceStatusReport';
|
||||||
|
import PolicyReportHome from './pages/Dashboard/Reports/PolicyReportHome';
|
||||||
|
import ReportDurationItemList from './pages/Dashboard/Reports/ReportDurationItemList';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@ -50,16 +43,16 @@ const routes = [
|
|||||||
exact: false,
|
exact: false,
|
||||||
component: Dashboard,
|
component: Dashboard,
|
||||||
routes: [
|
routes: [
|
||||||
{
|
// {
|
||||||
path: '/entgra/devices',
|
// path: '/entgra/devices',
|
||||||
component: Devices,
|
// component: Devices,
|
||||||
exact: true,
|
// exact: true,
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
path: '/entgra/devices/enroll',
|
// path: '/entgra/devices/enroll',
|
||||||
component: DeviceEnroll,
|
// component: DeviceEnroll,
|
||||||
exact: true,
|
// exact: true,
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: '/entgra/geo',
|
path: '/entgra/geo',
|
||||||
component: Geo,
|
component: Geo,
|
||||||
@ -70,58 +63,68 @@ const routes = [
|
|||||||
component: Reports,
|
component: Reports,
|
||||||
exact: true,
|
exact: true,
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// path: '/entgra/groups',
|
||||||
|
// component: Groups,
|
||||||
|
// exact: true,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/entgra/users',
|
||||||
|
// component: Users,
|
||||||
|
// exact: true,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/entgra/policies',
|
||||||
|
// component: Policies,
|
||||||
|
// exact: true,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/entgra/policy/add',
|
||||||
|
// component: AddNewPolicy,
|
||||||
|
// exact: true,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/entgra/roles',
|
||||||
|
// component: Roles,
|
||||||
|
// exact: true,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/entgra/devicetypes',
|
||||||
|
// component: DeviceTypes,
|
||||||
|
// exact: true,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: '/entgra/certificates',
|
||||||
|
// component: Certificates,
|
||||||
|
// exact: true,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
path: '/entgra/groups',
|
path: '/entgra/reports/list',
|
||||||
component: Groups,
|
|
||||||
exact: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/entgra/users',
|
|
||||||
component: Users,
|
|
||||||
exact: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/entgra/policies',
|
|
||||||
component: Policies,
|
|
||||||
exact: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/entgra/policy/add',
|
|
||||||
component: AddNewPolicy,
|
|
||||||
exact: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/entgra/roles',
|
|
||||||
component: Roles,
|
|
||||||
exact: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/entgra/devicetypes',
|
|
||||||
component: DeviceTypes,
|
|
||||||
exact: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/entgra/certificates',
|
|
||||||
component: Certificates,
|
|
||||||
exact: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/entgra/reportList',
|
|
||||||
component: ReportDurationItemList,
|
component: ReportDurationItemList,
|
||||||
exact: true,
|
exact: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/entgra/enrollmentsvsunenrollments',
|
path: '/entgra/reports/enrollments',
|
||||||
component: EnrollmentsVsUnenrollmentsReport,
|
component: EnrollmentsVsUnenrollmentsReport,
|
||||||
exact: true,
|
exact: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/entgra/enrollmenttype',
|
path: '/entgra/reports/enrollment-type',
|
||||||
component: EnrollmentTypeReport,
|
component: EnrollmentTypeReport,
|
||||||
exact: true,
|
exact: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/entgra/devicestatus',
|
path: '/entgra/reports/policy',
|
||||||
|
component: PolicyReportHome,
|
||||||
|
exact: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/entgra/reports/policy/compliance',
|
||||||
|
component: PolicyReport,
|
||||||
|
exact: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/entgra/reports/device-status',
|
||||||
component: DeviceStatusReport,
|
component: DeviceStatusReport,
|
||||||
exact: true,
|
exact: true,
|
||||||
},
|
},
|
||||||
|
|||||||
45
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/js/Utils.js
vendored
Normal file
45
components/device-mgt/io.entgra.device.mgt.ui/react-app/src/js/Utils.js
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { message, notification } from 'antd';
|
||||||
|
|
||||||
|
export const handleApiError = (
|
||||||
|
error,
|
||||||
|
errorMessage,
|
||||||
|
isForbiddenMessageSilent = false,
|
||||||
|
) => {
|
||||||
|
if (error.hasOwnProperty('response') && error.response.status === 401) {
|
||||||
|
message.error('You are not logged in');
|
||||||
|
const redirectUrl = encodeURI(window.location.href);
|
||||||
|
window.location.href =
|
||||||
|
window.location.origin + `/entgra/login?redirect=${redirectUrl}`;
|
||||||
|
// silence 403 forbidden message
|
||||||
|
} else if (
|
||||||
|
!(
|
||||||
|
isForbiddenMessageSilent &&
|
||||||
|
error.hasOwnProperty('response') &&
|
||||||
|
error.response.status === 403
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
notification.error({
|
||||||
|
message: 'There was a problem',
|
||||||
|
duration: 10,
|
||||||
|
description: errorMessage,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -59,7 +59,7 @@ class Dashboard extends React.Component {
|
|||||||
<Layout>
|
<Layout>
|
||||||
<Header style={{ background: '#fff', padding: 0 }}>
|
<Header style={{ background: '#fff', padding: 0 }}>
|
||||||
<div className="logo-image">
|
<div className="logo-image">
|
||||||
<Link to="/entgra/devices">
|
<Link to="/entgra/reports">
|
||||||
<img alt="logo" src={this.logo} />
|
<img alt="logo" src={this.logo} />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@ -72,26 +72,26 @@ class Dashboard extends React.Component {
|
|||||||
marginRight: 110,
|
marginRight: 110,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SubMenu
|
{/* <SubMenu*/}
|
||||||
key="devices"
|
{/* key="devices"*/}
|
||||||
title={
|
{/* title={*/}
|
||||||
<span>
|
{/* <span>*/}
|
||||||
<Icon type="appstore" />
|
{/* <Icon type="appstore" />*/}
|
||||||
<span>Devices</span>
|
{/* <span>Devices</span>*/}
|
||||||
</span>
|
{/* </span>*/}
|
||||||
}
|
{/* }*/}
|
||||||
>
|
{/* >*/}
|
||||||
<Menu.Item key="devices">
|
{/* <Menu.Item key="devices">*/}
|
||||||
<Link to="/entgra/devices">
|
{/* <Link to="/entgra/devices">*/}
|
||||||
<span>View</span>
|
{/* <span>View</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
<Menu.Item key="deviceEnroll">
|
{/* <Menu.Item key="deviceEnroll">*/}
|
||||||
<Link to="/entgra/devices/enroll">
|
{/* <Link to="/entgra/devices/enroll">*/}
|
||||||
<span>Enroll</span>
|
{/* <span>Enroll</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
</SubMenu>
|
{/* </SubMenu>*/}
|
||||||
<SubMenu
|
<SubMenu
|
||||||
key="geo"
|
key="geo"
|
||||||
title={
|
title={
|
||||||
@ -118,65 +118,65 @@ class Dashboard extends React.Component {
|
|||||||
<span>Reports</span>
|
<span>Reports</span>
|
||||||
</Link>
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="groups">
|
{/* <Menu.Item key="groups">*/}
|
||||||
<Link to="/entgra/groups">
|
{/* <Link to="/entgra/groups">*/}
|
||||||
<Icon type="deployment-unit" />
|
{/* <Icon type="deployment-unit" />*/}
|
||||||
<span>Groups</span>
|
{/* <span>Groups</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
<Menu.Item key="users">
|
{/* <Menu.Item key="users">*/}
|
||||||
<Link to="/entgra/users">
|
{/* <Link to="/entgra/users">*/}
|
||||||
<Icon type="user" />
|
{/* <Icon type="user" />*/}
|
||||||
<span>Users</span>
|
{/* <span>Users</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
<SubMenu
|
{/* <SubMenu*/}
|
||||||
key="policies"
|
{/* key="policies"*/}
|
||||||
title={
|
{/* title={*/}
|
||||||
<span>
|
{/* <span>*/}
|
||||||
<Icon type="audit" />
|
{/* <Icon type="audit" />*/}
|
||||||
<span>Policies</span>
|
{/* <span>Policies</span>*/}
|
||||||
</span>
|
{/* </span>*/}
|
||||||
}
|
{/* }*/}
|
||||||
>
|
{/* >*/}
|
||||||
<Menu.Item key="policiesList">
|
{/* <Menu.Item key="policiesList">*/}
|
||||||
<Link to="/entgra/policies">
|
{/* <Link to="/entgra/policies">*/}
|
||||||
<span>View</span>
|
{/* <span>View</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
<Menu.Item key="addPolicy">
|
{/* <Menu.Item key="addPolicy">*/}
|
||||||
<Link to="/entgra/policy/add">
|
{/* <Link to="/entgra/policy/add">*/}
|
||||||
<span>Add New Policy</span>
|
{/* <span>Add New Policy</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
</SubMenu>
|
{/* </SubMenu>*/}
|
||||||
<Menu.Item key="roles">
|
{/* <Menu.Item key="roles">*/}
|
||||||
<Link to="/entgra/roles">
|
{/* <Link to="/entgra/roles">*/}
|
||||||
<Icon type="book" />
|
{/* <Icon type="book" />*/}
|
||||||
<span>Roles</span>
|
{/* <span>Roles</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
<Menu.Item key="devicetypes">
|
{/* <Menu.Item key="devicetypes">*/}
|
||||||
<Link to="/entgra/devicetypes">
|
{/* <Link to="/entgra/devicetypes">*/}
|
||||||
<Icon type="desktop" />
|
{/* <Icon type="desktop" />*/}
|
||||||
<span>Device Types</span>
|
{/* <span>Device Types</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
<SubMenu
|
{/* <SubMenu*/}
|
||||||
key="configurations"
|
{/* key="configurations"*/}
|
||||||
title={
|
{/* title={*/}
|
||||||
<span>
|
{/* <span>*/}
|
||||||
<Icon type="setting" />
|
{/* <Icon type="setting" />*/}
|
||||||
<span>Configurations</span>
|
{/* <span>Configurations</span>*/}
|
||||||
</span>
|
{/* </span>*/}
|
||||||
}
|
{/* }*/}
|
||||||
>
|
{/* >*/}
|
||||||
<Menu.Item key="certificates">
|
{/* <Menu.Item key="certificates">*/}
|
||||||
<Link to="/entgra/certificates">
|
{/* <Link to="/entgra/certificates">*/}
|
||||||
<span>Certificates</span>
|
{/* <span>Certificates</span>*/}
|
||||||
</Link>
|
{/* </Link>*/}
|
||||||
</Menu.Item>
|
{/* </Menu.Item>*/}
|
||||||
</SubMenu>
|
{/* </SubMenu>*/}
|
||||||
<Menu.Item key="trigger"></Menu.Item>
|
<Menu.Item key="trigger"></Menu.Item>
|
||||||
<SubMenu
|
<SubMenu
|
||||||
className="profile"
|
className="profile"
|
||||||
@ -192,9 +192,9 @@ class Dashboard extends React.Component {
|
|||||||
</Menu>
|
</Menu>
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
<Content style={{ marginTop: 10 }}>
|
<Content>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Redirect exact from="/entgra" to="/entgra/devices" />
|
<Redirect exact from="/entgra/devices" to="/entgra/reports" />
|
||||||
{this.state.routes.map(route => (
|
{this.state.routes.map(route => (
|
||||||
<RouteWithSubRoutes key={route.path} {...route} />
|
<RouteWithSubRoutes key={route.path} {...route} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Icon, Col, Row, Card } from 'antd';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
class PolicyReportHome extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{ borderRadius: 5 }}>
|
||||||
|
<Row gutter={16}>
|
||||||
|
<Col span={8}>
|
||||||
|
<Link
|
||||||
|
to={{
|
||||||
|
// Path to respective report page
|
||||||
|
pathname: '/entgra/reports/policy/compliance',
|
||||||
|
data: {
|
||||||
|
name: 'all_policy_compliance_report',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
bordered={true}
|
||||||
|
hoverable={true}
|
||||||
|
style={{ borderRadius: 10, marginBottom: 16 }}
|
||||||
|
>
|
||||||
|
<div align="center">
|
||||||
|
<Icon
|
||||||
|
type="desktop"
|
||||||
|
style={{ fontSize: '25px', color: '#08c' }}
|
||||||
|
/>
|
||||||
|
<h2>
|
||||||
|
<b>Policy Compliance Report</b>
|
||||||
|
</h2>
|
||||||
|
<p>Policy compliance details of all enrolled devices</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
</Col>
|
||||||
|
<Col span={8}>
|
||||||
|
<Link
|
||||||
|
to={{
|
||||||
|
// Path to respective report page
|
||||||
|
pathname: '/entgra/reports/enrollments',
|
||||||
|
data: {
|
||||||
|
name: 'enrollments_vs_unenrollments_report',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
bordered={true}
|
||||||
|
hoverable={true}
|
||||||
|
style={{ borderRadius: 10, marginBottom: 16 }}
|
||||||
|
>
|
||||||
|
<div align="center">
|
||||||
|
<Icon
|
||||||
|
type="desktop"
|
||||||
|
style={{ fontSize: '25px', color: '#08c' }}
|
||||||
|
/>
|
||||||
|
<h2>
|
||||||
|
<b>Enrollments vs Unenrollments</b>
|
||||||
|
</h2>
|
||||||
|
<p>Details on device enrollments vs unenrollments</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={8}>
|
||||||
|
<Link
|
||||||
|
to={{
|
||||||
|
// Path to respective report page
|
||||||
|
pathname: '/entgra/reports/device-status',
|
||||||
|
data: {
|
||||||
|
name: 'enrollment_status_report',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
bordered={true}
|
||||||
|
hoverable={true}
|
||||||
|
style={{ borderRadius: 10, marginBottom: 16 }}
|
||||||
|
>
|
||||||
|
<div align="center">
|
||||||
|
<Icon
|
||||||
|
type="desktop"
|
||||||
|
style={{ fontSize: '25px', color: '#08c' }}
|
||||||
|
/>
|
||||||
|
<h2>
|
||||||
|
<b>Device Status Report</b>
|
||||||
|
</h2>
|
||||||
|
<p>Report based on device status</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col span={8}>
|
||||||
|
<Link
|
||||||
|
to={{
|
||||||
|
// Path to respective report page
|
||||||
|
pathname: '/entgra/reports/enrollment-type',
|
||||||
|
data: {
|
||||||
|
name: 'enrollemt_type_report',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
bordered={true}
|
||||||
|
hoverable={true}
|
||||||
|
style={{ borderRadius: 10, marginBottom: 16 }}
|
||||||
|
>
|
||||||
|
<div align="center">
|
||||||
|
<Icon
|
||||||
|
type="desktop"
|
||||||
|
style={{ fontSize: '25px', color: '#08c' }}
|
||||||
|
/>
|
||||||
|
<h2>
|
||||||
|
<b>Device Type Report</b>
|
||||||
|
</h2>
|
||||||
|
<p>Report for all device types</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PolicyReportHome;
|
||||||
@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Icon, Col, Row, Card } from 'antd';
|
import { Icon, Col, Row, Card, PageHeader, Breadcrumb } from 'antd';
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
@ -32,10 +32,11 @@ class ReportDurationItemList extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Array for pre defined date durations
|
||||||
durationItemArray = [
|
durationItemArray = [
|
||||||
{
|
{
|
||||||
name: 'Daily Report',
|
name: 'Daily Report',
|
||||||
description: 'Enrollments of today',
|
description: 'Report of today',
|
||||||
duration: [
|
duration: [
|
||||||
moment().format('YYYY-MM-DD'),
|
moment().format('YYYY-MM-DD'),
|
||||||
moment()
|
moment()
|
||||||
@ -45,7 +46,7 @@ class ReportDurationItemList extends React.Component {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Weekly Report',
|
name: 'Weekly Report',
|
||||||
description: 'Enrollments of last 7 days',
|
description: 'Report of last 7 days',
|
||||||
duration: [
|
duration: [
|
||||||
moment()
|
moment()
|
||||||
.subtract(6, 'days')
|
.subtract(6, 'days')
|
||||||
@ -57,7 +58,7 @@ class ReportDurationItemList extends React.Component {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Monthly Report',
|
name: 'Monthly Report',
|
||||||
description: 'Enrollments of last month',
|
description: 'Report of last month',
|
||||||
duration: [
|
duration: [
|
||||||
moment()
|
moment()
|
||||||
.subtract(29, 'days')
|
.subtract(29, 'days')
|
||||||
@ -69,7 +70,104 @@ class ReportDurationItemList extends React.Component {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Map durationItemArray and additional parameters to antd cards
|
||||||
|
mapDurationCards = data => {
|
||||||
|
return this.durationItemArray.map(item => (
|
||||||
|
<Col key={item.name} span={6}>
|
||||||
|
<Link
|
||||||
|
to={{
|
||||||
|
// Path to respective report page
|
||||||
|
pathname: '/entgra/reports/policy',
|
||||||
|
reportData: {
|
||||||
|
duration: item.duration,
|
||||||
|
data: data,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
key={item.name}
|
||||||
|
bordered={true}
|
||||||
|
hoverable={true}
|
||||||
|
style={{ borderRadius: 10, marginBottom: 16 }}
|
||||||
|
>
|
||||||
|
<div align="center">
|
||||||
|
<Icon
|
||||||
|
type="desktop"
|
||||||
|
style={{ fontSize: '25px', color: '#08c' }}
|
||||||
|
/>
|
||||||
|
<h2>
|
||||||
|
<b>{item.name}</b>
|
||||||
|
</h2>
|
||||||
|
<p>{item.description}</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
</Col>
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
itemAllPolicyCompliance = this.durationItemArray.map(data => (
|
||||||
|
<Col key={data.name} span={6}>
|
||||||
|
<Link
|
||||||
|
to={{
|
||||||
|
// Path to respective report page
|
||||||
|
pathname: '/entgra/policyreport',
|
||||||
|
reportData: {
|
||||||
|
duration: data.duration,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
key={data.name}
|
||||||
|
bordered={true}
|
||||||
|
hoverable={true}
|
||||||
|
style={{ borderRadius: 10, marginBottom: 16 }}
|
||||||
|
>
|
||||||
|
<div align="center">
|
||||||
|
<Icon type="desktop" style={{ fontSize: '25px', color: '#08c' }} />
|
||||||
|
<h2>
|
||||||
|
<b>{data.name}</b>
|
||||||
|
</h2>
|
||||||
|
<p>{data.description}</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
</Col>
|
||||||
|
));
|
||||||
|
|
||||||
|
itemPerPolicyCompliance = this.durationItemArray.map(data => (
|
||||||
|
<Col key={data.name} span={6}>
|
||||||
|
<Link
|
||||||
|
to={{
|
||||||
|
// Path to respective report page
|
||||||
|
pathname: '/entgra/policyreport',
|
||||||
|
reportData: {
|
||||||
|
duration: data.duration,
|
||||||
|
policyId: 6,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card
|
||||||
|
key={data.name}
|
||||||
|
bordered={true}
|
||||||
|
hoverable={true}
|
||||||
|
style={{ borderRadius: 10, marginBottom: 16 }}
|
||||||
|
>
|
||||||
|
<div align="center">
|
||||||
|
<Icon type="desktop" style={{ fontSize: '25px', color: '#08c' }} />
|
||||||
|
<h2>
|
||||||
|
<b>{data.name}</b>
|
||||||
|
</h2>
|
||||||
|
<p>{data.description}</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
|
</Col>
|
||||||
|
));
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { data } = this.props.location;
|
||||||
|
|
||||||
let itemStatus = this.durationItemArray.map(data => (
|
let itemStatus = this.durationItemArray.map(data => (
|
||||||
<Col key={data.name} span={6}>
|
<Col key={data.name} span={6}>
|
||||||
<Link
|
<Link
|
||||||
@ -175,18 +273,53 @@ class ReportDurationItemList extends React.Component {
|
|||||||
</Link>
|
</Link>
|
||||||
</Col>
|
</Col>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let cardItem = this.itemAllPolicyCompliance;
|
||||||
|
|
||||||
|
switch (data.name) {
|
||||||
|
case 'all_policy_compliance_report':
|
||||||
|
cardItem = this.itemAllPolicyCompliance;
|
||||||
|
// cardItem = this.mapDurationCards({});
|
||||||
|
break;
|
||||||
|
case 'per_policy_compliance_report':
|
||||||
|
cardItem = this.itemPerPolicyCompliance;
|
||||||
|
// cardItem = this.mapDurationCards({
|
||||||
|
// policyId: 6,
|
||||||
|
// });
|
||||||
|
break;
|
||||||
|
case 'enrollments_vs_unenrollments_report':
|
||||||
|
cardItem = itemEnrollmentsVsUnenrollments;
|
||||||
|
break;
|
||||||
|
case 'enrollment_status_report':
|
||||||
|
cardItem = itemStatus;
|
||||||
|
break;
|
||||||
|
case 'enrollemt_type_report':
|
||||||
|
cardItem = itemEnrollmentType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div style={{ borderRadius: 5 }}>
|
<div>
|
||||||
<Row gutter={16}>{itemStatus}</Row>
|
<PageHeader style={{ paddingTop: 0 }}>
|
||||||
</div>
|
<Breadcrumb style={{ paddingBottom: 16 }}>
|
||||||
|
<Breadcrumb.Item>
|
||||||
<div style={{ borderRadius: 5 }}>
|
<Link to="/entgra">
|
||||||
<Row gutter={16}>{itemEnrollmentsVsUnenrollments}</Row>
|
<Icon type="home" /> Home
|
||||||
</div>
|
</Link>
|
||||||
|
</Breadcrumb.Item>
|
||||||
<div style={{ borderRadius: 5 }}>
|
<Breadcrumb.Item>Reports</Breadcrumb.Item>
|
||||||
<Row gutter={16}>{itemEnrollmentType}</Row>
|
</Breadcrumb>
|
||||||
|
<div className="wrap">
|
||||||
|
<h3>Reports</h3>
|
||||||
|
<div style={{ borderRadius: 5 }}>
|
||||||
|
<Row gutter={16}>{cardItem}</Row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PageHeader>
|
||||||
|
<div
|
||||||
|
style={{ background: '#f0f2f5', padding: 24, minHeight: 720 }}
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PageHeader, Breadcrumb, Icon } from 'antd';
|
import { PageHeader, Breadcrumb, Icon } from 'antd';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import ReportDurationItemList from './ReportDurationItemList';
|
import PolicyReportHome from './PolicyReportHome';
|
||||||
|
|
||||||
class Reports extends React.Component {
|
class Reports extends React.Component {
|
||||||
routes;
|
routes;
|
||||||
@ -70,7 +70,7 @@ class Reports extends React.Component {
|
|||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
<div className="wrap">
|
<div className="wrap">
|
||||||
<h3>Reports</h3>
|
<h3>Reports</h3>
|
||||||
<ReportDurationItemList />
|
<PolicyReportHome />
|
||||||
</div>
|
</div>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.wso2.carbon.device.mgt.jaxrs.beans;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceData;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ComplianceDeviceList extends BasePaginatedResult{
|
||||||
|
private List<ComplianceData> complianceData = new ArrayList<>();
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "List of devices returned")
|
||||||
|
@JsonProperty("devices")
|
||||||
|
public List<ComplianceData> getList() {
|
||||||
|
return complianceData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setList(List<ComplianceData> complianceData) {
|
||||||
|
this.complianceData = complianceData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("{\n");
|
||||||
|
sb.append(" count: ").append(getCount()).append(",\n");
|
||||||
|
sb.append(" devices: [").append(complianceData).append("\n");
|
||||||
|
sb.append("]}\n");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1906,4 +1906,110 @@ public interface DeviceManagementService {
|
|||||||
@PathParam("status") String status,
|
@PathParam("status") String status,
|
||||||
@ApiParam(name = "deviceList", value = "The payload containing the new name of the device.", required = true)
|
@ApiParam(name = "deviceList", value = "The payload containing the new name of the device.", required = true)
|
||||||
@Valid List<String> deviceList);
|
@Valid List<String> deviceList);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/compliance/{compliance-status}")
|
||||||
|
@ApiOperation(
|
||||||
|
produces = MediaType.APPLICATION_JSON,
|
||||||
|
httpMethod = "GET",
|
||||||
|
value = "Getting Policy Compliance Status of all devices",
|
||||||
|
notes = "A policy is enforced on the devices that register with Entgra IoTS. " +
|
||||||
|
"The server checks if the settings in the device comply with the policy that is enforced on the device using this REST API.",
|
||||||
|
tags = "Device Management",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:compliance-data")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
code = 200,
|
||||||
|
message = "OK",
|
||||||
|
response = NonComplianceData.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 400,
|
||||||
|
message = "Bad Request. \n Invalid request or validation error.",
|
||||||
|
response = ErrorResponse.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 500,
|
||||||
|
message = "Error occurred while getting the compliance data.",
|
||||||
|
response = ErrorResponse.class)
|
||||||
|
})
|
||||||
|
Response getPolicyCompliance(
|
||||||
|
@ApiParam(
|
||||||
|
name = "compliance-status",
|
||||||
|
value = "Compliance status for devices. If true, devices which are compliant with policies. " +
|
||||||
|
"If false, devices which are not compliant",
|
||||||
|
required = true)
|
||||||
|
@PathParam("compliance-status")
|
||||||
|
boolean complianceStatus,
|
||||||
|
@ApiParam(
|
||||||
|
name = "policy",
|
||||||
|
value = "Policy ID")
|
||||||
|
@QueryParam("policy") String policyId,
|
||||||
|
@ApiParam(
|
||||||
|
name = "is-pending",
|
||||||
|
value = "Check for devices in pending status")
|
||||||
|
@QueryParam("pending") boolean isPending,
|
||||||
|
@ApiParam(
|
||||||
|
name = "fromDate",
|
||||||
|
value = "Start date of the duration")
|
||||||
|
@QueryParam("from") String fromDate,
|
||||||
|
@ApiParam(
|
||||||
|
name = "toDate",
|
||||||
|
value = "end date of the duration")
|
||||||
|
@QueryParam("to") String toDate,
|
||||||
|
@ApiParam(
|
||||||
|
name = "offset",
|
||||||
|
value = "The starting pagination index for the complete list of qualified items.",
|
||||||
|
defaultValue = "0")
|
||||||
|
@QueryParam("offset")
|
||||||
|
int offset,
|
||||||
|
@ApiParam(
|
||||||
|
name = "limit",
|
||||||
|
value = "Provide how many device details you require from the starting pagination index/offset.",
|
||||||
|
defaultValue = "5")
|
||||||
|
@QueryParam("limit")
|
||||||
|
int limit);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/{id}/features")
|
||||||
|
@ApiOperation(
|
||||||
|
produces = MediaType.APPLICATION_JSON,
|
||||||
|
httpMethod = "GET",
|
||||||
|
value = "Getting Policy Compliance Status of all devices",
|
||||||
|
notes = "A policy is enforced on the devices that register with Entgra IoTS. " +
|
||||||
|
"The server checks if the settings in the device comply with the policy that is enforced on the device using this REST API.",
|
||||||
|
tags = "Device Management",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:compliance-data")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
code = 200,
|
||||||
|
message = "OK",
|
||||||
|
response = NonComplianceData.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 400,
|
||||||
|
message = "Bad Request. \n Invalid request or validation error.",
|
||||||
|
response = ErrorResponse.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 500,
|
||||||
|
message = "Error occurred while getting the compliance data.",
|
||||||
|
response = ErrorResponse.class)
|
||||||
|
})
|
||||||
|
Response getNoneComplianceFeatures(
|
||||||
|
@ApiParam(
|
||||||
|
name = "id",
|
||||||
|
value = "The device identifier of the device you wish to get details.\n" +
|
||||||
|
"INFO: Make sure to add the ID of a device that is already registered with Entgra IoTS.",
|
||||||
|
required = true)
|
||||||
|
@PathParam("id")
|
||||||
|
int id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,7 +82,7 @@ public interface ReportManagementService {
|
|||||||
produces = MediaType.APPLICATION_JSON,
|
produces = MediaType.APPLICATION_JSON,
|
||||||
httpMethod = "GET",
|
httpMethod = "GET",
|
||||||
value = "Getting Details of Registered Devices",
|
value = "Getting Details of Registered Devices",
|
||||||
notes = "Provides details of all the devices enrolled with WSO2 IoT Server.",
|
notes = "Provides details of all the devices enrolled with Entgra IoT Server.",
|
||||||
tags = "Device Management",
|
tags = "Device Management",
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(properties = {
|
@Extension(properties = {
|
||||||
@ -161,12 +161,12 @@ public interface ReportManagementService {
|
|||||||
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/devices/count")
|
@Path("/count")
|
||||||
@ApiOperation(
|
@ApiOperation(
|
||||||
produces = MediaType.APPLICATION_JSON,
|
produces = MediaType.APPLICATION_JSON,
|
||||||
httpMethod = "GET",
|
httpMethod = "GET",
|
||||||
value = "Getting Details of Registered Devices",
|
value = "Getting Details of Registered Devices",
|
||||||
notes = "Provides details of all the devices enrolled with WSO2 IoT Server.",
|
notes = "Provides details of all the devices enrolled with Entgra IoT Server.",
|
||||||
tags = "Device Management",
|
tags = "Device Management",
|
||||||
extensions = {
|
extensions = {
|
||||||
@Extension(properties = {
|
@Extension(properties = {
|
||||||
@ -230,4 +230,83 @@ public interface ReportManagementService {
|
|||||||
value = "end date of the duration",
|
value = "end date of the duration",
|
||||||
required = true)
|
required = true)
|
||||||
@QueryParam("to") String toDate) throws ReportManagementException;
|
@QueryParam("to") String toDate) throws ReportManagementException;
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/devices/count")
|
||||||
|
@ApiOperation(
|
||||||
|
produces = MediaType.APPLICATION_JSON,
|
||||||
|
httpMethod = "GET",
|
||||||
|
value = "Getting Details of Registered Devices",
|
||||||
|
notes = "Provides details of all the devices enrolled with Entgra IoT Server.",
|
||||||
|
tags = "Device Management",
|
||||||
|
extensions = {
|
||||||
|
@Extension(properties = {
|
||||||
|
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:view")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@ApiResponses(
|
||||||
|
value = {
|
||||||
|
@ApiResponse(
|
||||||
|
code = 200,
|
||||||
|
message = "OK. \n Successfully fetched the list of devices.",
|
||||||
|
response = DeviceList.class,
|
||||||
|
responseHeaders = {
|
||||||
|
@ResponseHeader(
|
||||||
|
name = "Content-Type",
|
||||||
|
description = "The content type of the body"),
|
||||||
|
@ResponseHeader(
|
||||||
|
name = "ETag",
|
||||||
|
description = "Entity Tag of the response resource.\n" +
|
||||||
|
"Used by caches, or in conditional requests."),
|
||||||
|
@ResponseHeader(
|
||||||
|
name = "Last-Modified",
|
||||||
|
description = "Date and time the resource was last modified.\n" +
|
||||||
|
"Used by caches, or in conditional requests."),
|
||||||
|
}),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 400,
|
||||||
|
message = "Bad Request. \n Invalid device status type received. \n" +
|
||||||
|
"Valid status types are NEW | CHECKED",
|
||||||
|
response = ErrorResponse.class),
|
||||||
|
@ApiResponse(
|
||||||
|
code = 500,
|
||||||
|
message = "Internal Server Error. " +
|
||||||
|
"\n Server error occurred while fetching the device list.",
|
||||||
|
response = ErrorResponse.class)
|
||||||
|
})
|
||||||
|
Response getCountOfDevicesByDuration(
|
||||||
|
@ApiParam(
|
||||||
|
name = "status",
|
||||||
|
value = "Provide the device status details, such as active or inactive.")
|
||||||
|
@QueryParam("status") List<String> status,
|
||||||
|
@ApiParam(
|
||||||
|
name = "ownership",
|
||||||
|
allowableValues = "BYOD, COPE",
|
||||||
|
value = "Provide the ownership status of the device. The following values can be assigned:\n" +
|
||||||
|
"- BYOD: Bring Your Own Device\n" +
|
||||||
|
"- COPE: Corporate-Owned, Personally-Enabled")
|
||||||
|
@QueryParam("ownership") String ownership,
|
||||||
|
@ApiParam(
|
||||||
|
name = "fromDate",
|
||||||
|
value = "Start date of the duration",
|
||||||
|
required = true)
|
||||||
|
@QueryParam("from") String fromDate,
|
||||||
|
@ApiParam(
|
||||||
|
name = "toDate",
|
||||||
|
value = "end date of the duration",
|
||||||
|
required = true)
|
||||||
|
@QueryParam("to") String toDate,
|
||||||
|
@ApiParam(
|
||||||
|
name = "offset",
|
||||||
|
value = "The starting pagination index for the complete list of qualified items.",
|
||||||
|
defaultValue = "0")
|
||||||
|
@QueryParam("offset")
|
||||||
|
int offset,
|
||||||
|
@ApiParam(
|
||||||
|
name = "limit",
|
||||||
|
value = "Provide how many device details you require from the starting pagination index/offset.")
|
||||||
|
@QueryParam("limit")
|
||||||
|
int limit) throws ReportManagementException;
|
||||||
}
|
}
|
||||||
@ -66,6 +66,8 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
|
|||||||
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
||||||
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
|
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
|
||||||
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceData;
|
||||||
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
|
||||||
import org.wso2.carbon.device.mgt.common.search.PropertyMap;
|
import org.wso2.carbon.device.mgt.common.search.PropertyMap;
|
||||||
@ -84,6 +86,7 @@ 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.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;
|
||||||
@ -106,13 +109,12 @@ import javax.ws.rs.Path;
|
|||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
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.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -1056,4 +1058,66 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
|
|||||||
}
|
}
|
||||||
return Response.status(Response.Status.OK).build();
|
return Response.status(Response.Status.OK).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Override
|
||||||
|
@Path("/compliance/{compliance-status}")
|
||||||
|
public Response getPolicyCompliance(
|
||||||
|
@PathParam("compliance-status") boolean complianceStatus,
|
||||||
|
@QueryParam("policy") String policyId,
|
||||||
|
@DefaultValue("false")
|
||||||
|
@QueryParam("pending") boolean isPending,
|
||||||
|
@QueryParam("from") String fromDate,
|
||||||
|
@QueryParam("to") String toDate,
|
||||||
|
@DefaultValue("0")
|
||||||
|
@QueryParam("offset") int offset,
|
||||||
|
@DefaultValue("10")
|
||||||
|
@QueryParam("limit") int limit) {
|
||||||
|
|
||||||
|
PaginationRequest request = new PaginationRequest(offset, limit);
|
||||||
|
ComplianceDeviceList complianceDeviceList = new ComplianceDeviceList();
|
||||||
|
PaginationResult paginationResult;
|
||||||
|
try {
|
||||||
|
|
||||||
|
PolicyManagerService policyManagerService = DeviceMgtAPIUtils.getPolicyManagementService();
|
||||||
|
paginationResult = policyManagerService.getPolicyCompliance(request, policyId, complianceStatus, isPending, fromDate, toDate);
|
||||||
|
|
||||||
|
if (paginationResult.getData().isEmpty()) {
|
||||||
|
return Response.status(Response.Status.OK)
|
||||||
|
.entity("No policy compliance or non compliance devices are available").build();
|
||||||
|
} else {
|
||||||
|
complianceDeviceList.setList((List<ComplianceData>) paginationResult.getData());
|
||||||
|
complianceDeviceList.setCount(paginationResult.getRecordsTotal());
|
||||||
|
return Response.status(Response.Status.OK).entity(complianceDeviceList).build();
|
||||||
|
}
|
||||||
|
} catch (PolicyComplianceException e) {
|
||||||
|
String msg = "Error occurred while retrieving compliance data";
|
||||||
|
log.error(msg, e);
|
||||||
|
return Response.serverError().entity(
|
||||||
|
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Override
|
||||||
|
@Path("/{id}/features")
|
||||||
|
public Response getNoneComplianceFeatures(
|
||||||
|
@PathParam("id") int id) {
|
||||||
|
List<ComplianceFeature> complianceFeatureList;
|
||||||
|
try {
|
||||||
|
PolicyManagerService policyManagerService = DeviceMgtAPIUtils.getPolicyManagementService();
|
||||||
|
complianceFeatureList = policyManagerService.getNoneComplianceFeatures(id);
|
||||||
|
|
||||||
|
if (complianceFeatureList.isEmpty()) {
|
||||||
|
return Response.status(Response.Status.OK).entity("No non compliance features are available").build();
|
||||||
|
} else {
|
||||||
|
return Response.status(Response.Status.OK).entity(complianceFeatureList).build();
|
||||||
|
}
|
||||||
|
} catch (PolicyComplianceException e) {
|
||||||
|
String msg = "Error occurred while retrieving non compliance features";
|
||||||
|
log.error(msg, e);
|
||||||
|
return Response.serverError().entity(
|
||||||
|
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,9 +169,14 @@ public class PolicyManagementServiceImpl implements PolicyManagementService {
|
|||||||
try {
|
try {
|
||||||
PolicyAdministratorPoint policyAdministratorPoint = policyManagementService.getPAP();
|
PolicyAdministratorPoint policyAdministratorPoint = policyManagementService.getPAP();
|
||||||
policies = policyAdministratorPoint.getPolicies();
|
policies = policyAdministratorPoint.getPolicies();
|
||||||
targetPolicies.setCount(policies.size());
|
if(offset == 0 && limit == 0){
|
||||||
filteredPolicies = FilteringUtil.getFilteredList(policies, offset, limit);
|
return Response.status(Response.Status.OK).entity(policies).build();
|
||||||
targetPolicies.setList(filteredPolicies);
|
}else{
|
||||||
|
targetPolicies.setCount(policies.size());
|
||||||
|
filteredPolicies = FilteringUtil.getFilteredList(policies, offset, limit);
|
||||||
|
targetPolicies.setList(filteredPolicies);
|
||||||
|
return Response.status(Response.Status.OK).entity(targetPolicies).build();
|
||||||
|
}
|
||||||
} catch (PolicyManagementException e) {
|
} catch (PolicyManagementException e) {
|
||||||
String msg = "Error occurred while retrieving all available policies";
|
String msg = "Error occurred while retrieving all available policies";
|
||||||
log.error(msg, e);
|
log.error(msg, e);
|
||||||
@ -179,7 +184,7 @@ public class PolicyManagementServiceImpl implements PolicyManagementService {
|
|||||||
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.status(Response.Status.OK).entity(targetPolicies).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|||||||
@ -15,15 +15,16 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.wso2.carbon.device.mgt.jaxrs.service.impl;
|
package org.wso2.carbon.device.mgt.jaxrs.service.impl;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
|
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.ReportManagementException;
|
import org.wso2.carbon.device.mgt.common.exceptions.ReportManagementException;
|
||||||
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList;
|
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;
|
||||||
@ -103,7 +104,8 @@ public class ReportManagementServiceImpl implements ReportManagementService {
|
|||||||
@QueryParam("to") String toDate) {
|
@QueryParam("to") String toDate) {
|
||||||
int deviceCount;
|
int deviceCount;
|
||||||
try {
|
try {
|
||||||
deviceCount = DeviceMgtAPIUtils.getReportManagementService().getDevicesByDurationCount(status, ownership, fromDate, toDate);
|
deviceCount = DeviceMgtAPIUtils.getReportManagementService()
|
||||||
|
.getDevicesByDurationCount(status, ownership, fromDate, toDate);
|
||||||
return Response.status(Response.Status.OK).entity(deviceCount).build();
|
return Response.status(Response.Status.OK).entity(deviceCount).build();
|
||||||
} catch (ReportManagementException e) {
|
} catch (ReportManagementException e) {
|
||||||
String errorMessage = "Error while retrieving device count.";
|
String errorMessage = "Error while retrieving device count.";
|
||||||
@ -112,4 +114,39 @@ public class ReportManagementServiceImpl implements ReportManagementService {
|
|||||||
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
|
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/count")
|
||||||
|
@Override
|
||||||
|
public Response getCountOfDevicesByDuration(
|
||||||
|
@QueryParam("status") List<String> status,
|
||||||
|
@QueryParam("ownership") String ownership,
|
||||||
|
@QueryParam("from") String fromDate,
|
||||||
|
@QueryParam("to") String toDate,
|
||||||
|
@DefaultValue("0")
|
||||||
|
@QueryParam("offset") int offset,
|
||||||
|
@QueryParam("limit") int limit) {
|
||||||
|
try {
|
||||||
|
RequestValidationUtil.validatePaginationParameters(offset, limit);
|
||||||
|
PaginationRequest request = new PaginationRequest(offset, limit);
|
||||||
|
|
||||||
|
if (!StringUtils.isBlank(ownership)) {
|
||||||
|
request.setOwnership(ownership);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject countList = DeviceMgtAPIUtils.getReportManagementService()
|
||||||
|
.getCountOfDevicesByDuration(request, status, fromDate, toDate);
|
||||||
|
if (countList.isJsonNull()) {
|
||||||
|
return Response.status(Response.Status.OK)
|
||||||
|
.entity("No devices have been enrolled between the given date range").build();
|
||||||
|
} else {
|
||||||
|
return Response.status(Response.Status.OK).entity(countList).build();
|
||||||
|
}
|
||||||
|
} catch (ReportManagementException e) {
|
||||||
|
String msg = "Error occurred while retrieving device list";
|
||||||
|
log.error(msg, e);
|
||||||
|
return Response.serverError().entity(
|
||||||
|
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
public class Count {
|
||||||
|
private String date;
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
public Count(String date, int count) {
|
||||||
|
this.date = date;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(String date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCount(int count) {
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* 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.policy.mgt.monitor;
|
||||||
|
|
||||||
|
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ComplianceData {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private int deviceId;
|
||||||
|
private String deviceName;
|
||||||
|
private String deviceType;
|
||||||
|
private String owner;
|
||||||
|
private int enrolmentId;
|
||||||
|
private int policyId;
|
||||||
|
private String policyName;
|
||||||
|
List<ComplianceFeature> complianceFeatures;
|
||||||
|
private boolean status;
|
||||||
|
private Timestamp lastRequestedTime;
|
||||||
|
private Timestamp lastSucceededTime;
|
||||||
|
private Timestamp lastFailedTime;
|
||||||
|
private int attempts;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This parameter is to inform the policy core, weather related device type plugins does need the full policy or
|
||||||
|
* the part which is none compliance.
|
||||||
|
*/
|
||||||
|
private boolean completePolicy;
|
||||||
|
private Policy policy;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEnrolmentId() {
|
||||||
|
return enrolmentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnrolmentId(int enrolmentId) {
|
||||||
|
this.enrolmentId = enrolmentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timestamp getLastRequestedTime() {
|
||||||
|
return lastRequestedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastRequestedTime(Timestamp lastRequestedTime) {
|
||||||
|
this.lastRequestedTime = lastRequestedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timestamp getLastSucceededTime() {
|
||||||
|
return lastSucceededTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastSucceededTime(Timestamp lastSucceededTime) {
|
||||||
|
this.lastSucceededTime = lastSucceededTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timestamp getLastFailedTime() {
|
||||||
|
return lastFailedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastFailedTime(Timestamp lastFailedTime) {
|
||||||
|
this.lastFailedTime = lastFailedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAttempts() {
|
||||||
|
return attempts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttempts(int attempts) {
|
||||||
|
this.attempts = attempts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDeviceId() {
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceId(int deviceId) {
|
||||||
|
this.deviceId = deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPolicyId() {
|
||||||
|
return policyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolicyId(int policyId) {
|
||||||
|
this.policyId = policyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ComplianceFeature> getComplianceFeatures() {
|
||||||
|
return complianceFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComplianceFeatures(List<ComplianceFeature> complianceFeatures) {
|
||||||
|
this.complianceFeatures = complianceFeatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(boolean status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompletePolicy() {
|
||||||
|
return completePolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompletePolicy(boolean completePolicy) {
|
||||||
|
this.completePolicy = completePolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Policy getPolicy() {
|
||||||
|
return policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolicy(Policy policy) {
|
||||||
|
this.policy = policy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceName() {
|
||||||
|
return deviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceName(String deviceName) {
|
||||||
|
this.deviceName = deviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOwner(String owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPolicyName() {
|
||||||
|
return policyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolicyName(String policyName) {
|
||||||
|
this.policyName = policyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceType() {
|
||||||
|
return deviceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceType(String deviceType) {
|
||||||
|
this.deviceType = deviceType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.wso2.carbon.device.mgt.common.report.mgt;
|
package org.wso2.carbon.device.mgt.common.report.mgt;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.ReportManagementException;
|
import org.wso2.carbon.device.mgt.common.exceptions.ReportManagementException;
|
||||||
@ -43,4 +44,7 @@ public interface ReportManagementService {
|
|||||||
|
|
||||||
int getDevicesByDurationCount(List<String> statusList, String ownership, String fromDate, String toDate)
|
int getDevicesByDurationCount(List<String> statusList, String ownership, String fromDate, String toDate)
|
||||||
throws ReportManagementException;
|
throws ReportManagementException;
|
||||||
|
|
||||||
|
JsonObject getCountOfDevicesByDuration(PaginationRequest request, List<String> statusList, String fromDate, String toDate)
|
||||||
|
throws ReportManagementException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,11 +35,8 @@
|
|||||||
|
|
||||||
package org.wso2.carbon.device.mgt.core.dao;
|
package org.wso2.carbon.device.mgt.core.dao;
|
||||||
|
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.*;
|
||||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
|
||||||
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
|
|
||||||
import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status;
|
import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
|
||||||
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistory;
|
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.configuration.mgt.DevicePropertyInfo;
|
||||||
import org.wso2.carbon.device.mgt.common.device.details.DeviceData;
|
import org.wso2.carbon.device.mgt.common.device.details.DeviceData;
|
||||||
@ -561,6 +558,23 @@ public interface DeviceDAO {
|
|||||||
List<String> statusList, String ownership, String fromDate, String toDate, int tenantId)
|
List<String> statusList, String ownership, String fromDate, String toDate, int tenantId)
|
||||||
throws DeviceManagementDAOException;
|
throws DeviceManagementDAOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to get the device count to generate the report graph within a specific time periode
|
||||||
|
*
|
||||||
|
* @param request Pagination request to get paginated result
|
||||||
|
* @param statusList Status list to filter data
|
||||||
|
* @param tenantId ID of the current tenant
|
||||||
|
* @param fromDate Start date to filter devices(YYYY-MM-DD)
|
||||||
|
* @param toDate End date to filter devices(YYYY-MM-DD)
|
||||||
|
* @return returns a list of Count objects
|
||||||
|
* @throws DeviceManagementDAOException
|
||||||
|
*/
|
||||||
|
List<Count> getCountOfDevicesByDuration(PaginationRequest request,
|
||||||
|
List<String> statusList,
|
||||||
|
int tenantId,
|
||||||
|
String fromDate,
|
||||||
|
String toDate) throws DeviceManagementDAOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve device location information
|
* Retrieve device location information
|
||||||
* @param deviceIdentifier Device Identifier object
|
* @param deviceIdentifier Device Identifier object
|
||||||
|
|||||||
@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.core.dao.impl.device;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.mgt.common.Count;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
||||||
@ -529,7 +530,7 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
@Override
|
@Override
|
||||||
public int getDevicesByDurationCount(List<String> statusList, String ownership, String fromDate, String toDate, int tenantId) throws DeviceManagementDAOException {
|
public int getDevicesByDurationCount(List<String> statusList, String ownership, String fromDate, String toDate, int tenantId) throws DeviceManagementDAOException {
|
||||||
int deviceCount = 0;
|
int deviceCount = 0;
|
||||||
boolean isStatusProvided = false;
|
boolean isStatusProvided;
|
||||||
|
|
||||||
String sql = "SELECT " +
|
String sql = "SELECT " +
|
||||||
"COUNT(d.ID) AS DEVICE_COUNT " +
|
"COUNT(d.ID) AS DEVICE_COUNT " +
|
||||||
@ -576,6 +577,70 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return deviceCount;
|
return deviceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Count> getCountOfDevicesByDuration(PaginationRequest request, List<String> statusList, int tenantId,
|
||||||
|
String fromDate, String toDate)
|
||||||
|
throws DeviceManagementDAOException {
|
||||||
|
List<Count> countList = new ArrayList<>();
|
||||||
|
String ownership = request.getOwnership();
|
||||||
|
boolean isStatusProvided;
|
||||||
|
|
||||||
|
String sql =
|
||||||
|
"SELECT " +
|
||||||
|
"SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10) AS ENROLMENT_DATE, " +
|
||||||
|
"COUNT(SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10)) AS ENROLMENT_COUNT " +
|
||||||
|
"FROM DM_DEVICE AS d " +
|
||||||
|
"INNER JOIN DM_ENROLMENT AS e ON d.ID = e.DEVICE_ID " +
|
||||||
|
"INNER JOIN DM_DEVICE_TYPE AS t ON d.DEVICE_TYPE_ID = t.ID " +
|
||||||
|
"AND e.TENANT_ID = ? " +
|
||||||
|
"AND e.DATE_OF_ENROLMENT " +
|
||||||
|
"BETWEEN ? AND ? ";
|
||||||
|
|
||||||
|
//Add the query for status
|
||||||
|
StringBuilder sqlBuilder = new StringBuilder(sql);
|
||||||
|
isStatusProvided = buildStatusQuery(statusList, sqlBuilder);
|
||||||
|
sql = sqlBuilder.toString();
|
||||||
|
|
||||||
|
if (ownership != null) {
|
||||||
|
sql = sql + " AND e.OWNERSHIP = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " GROUP BY SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10) LIMIT ?,?";
|
||||||
|
|
||||||
|
try (Connection conn = this.getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
int paramIdx = 1;
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
stmt.setString(paramIdx++, fromDate);
|
||||||
|
stmt.setString(paramIdx++, toDate);
|
||||||
|
if (isStatusProvided) {
|
||||||
|
for (String status : statusList) {
|
||||||
|
stmt.setString(paramIdx++, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ownership != null) {
|
||||||
|
stmt.setString(paramIdx++, ownership);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx++, request.getStartIndex());
|
||||||
|
stmt.setInt(paramIdx, request.getRowCount());
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
Count count = new Count(
|
||||||
|
rs.getString("ENROLMENT_DATE"),
|
||||||
|
rs.getInt("ENROLMENT_COUNT")
|
||||||
|
);
|
||||||
|
countList.add(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred while retrieving information of all " +
|
||||||
|
"registered devices under tenant id " + tenantId + " between " + fromDate + " to " + toDate;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new DeviceManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
return countList;
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean buildStatusQuery(List<String> statusList, StringBuilder sqlBuilder) {
|
protected boolean buildStatusQuery(List<String> statusList, StringBuilder sqlBuilder) {
|
||||||
if (statusList != null && !statusList.isEmpty() && !statusList.get(0).isEmpty()) {
|
if (statusList != null && !statusList.isEmpty() && !statusList.get(0).isEmpty()) {
|
||||||
sqlBuilder.append(" AND e.STATUS IN(");
|
sqlBuilder.append(" AND e.STATUS IN(");
|
||||||
|
|||||||
@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.core.dao.impl.device;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.mgt.common.Count;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
||||||
@ -527,6 +528,85 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Count> getCountOfDevicesByDuration(PaginationRequest request, List<String> statusList, int tenantId,
|
||||||
|
String fromDate, String toDate)
|
||||||
|
throws DeviceManagementDAOException {
|
||||||
|
List<Count> countList = new ArrayList<>();
|
||||||
|
String ownership = request.getOwnership();
|
||||||
|
boolean isStatusProvided;
|
||||||
|
|
||||||
|
String sql =
|
||||||
|
"SELECT " +
|
||||||
|
"SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10) AS ENROLMENT_DATE, " +
|
||||||
|
"COUNT(SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10)) AS ENROLMENT_COUNT " +
|
||||||
|
"FROM DM_DEVICE AS d " +
|
||||||
|
"INNER JOIN DM_ENROLMENT AS e ON d.ID = e.DEVICE_ID " +
|
||||||
|
"INNER JOIN DM_DEVICE_TYPE AS t ON d.DEVICE_TYPE_ID = t.ID " +
|
||||||
|
"AND e.TENANT_ID = ? " +
|
||||||
|
"AND e.DATE_OF_ENROLMENT BETWEEN ? AND ? ";
|
||||||
|
|
||||||
|
//Add the query for status
|
||||||
|
StringBuilder sqlBuilder = new StringBuilder(sql);
|
||||||
|
isStatusProvided = buildStatusQuery(statusList, sqlBuilder);
|
||||||
|
sql = sqlBuilder.toString();
|
||||||
|
|
||||||
|
if (ownership != null) {
|
||||||
|
sql = sql + " AND e.OWNERSHIP = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " GROUP BY SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10) OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
|
||||||
|
|
||||||
|
try (Connection conn = this.getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
int paramIdx = 1;
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
stmt.setString(paramIdx++, fromDate);
|
||||||
|
stmt.setString(paramIdx++, toDate);
|
||||||
|
if (isStatusProvided) {
|
||||||
|
for (String status : statusList) {
|
||||||
|
stmt.setString(paramIdx++, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ownership != null) {
|
||||||
|
stmt.setString(paramIdx++, ownership);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx++, request.getStartIndex());
|
||||||
|
stmt.setInt(paramIdx, request.getRowCount());
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
Count count = new Count(
|
||||||
|
rs.getString("ENROLMENT_DATE"),
|
||||||
|
rs.getInt("ENROLMENT_COUNT")
|
||||||
|
);
|
||||||
|
countList.add(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred while retrieving information of all " +
|
||||||
|
"registered devices under tenant id " + tenantId + " between " + fromDate + " to " + toDate;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new DeviceManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
return countList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean buildStatusQuery(List<String> statusList, StringBuilder sqlBuilder) {
|
||||||
|
if (statusList != null && !statusList.isEmpty() && !statusList.get(0).isEmpty()) {
|
||||||
|
sqlBuilder.append(" AND e.STATUS IN(");
|
||||||
|
for (int i = 0; i < statusList.size(); i++) {
|
||||||
|
sqlBuilder.append("?");
|
||||||
|
if (i != statusList.size() - 1) {
|
||||||
|
sqlBuilder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlBuilder.append(")");
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of devices that matches with the given device name and (or) device type.
|
* Get the list of devices that matches with the given device name and (or) device type.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.core.dao.impl.device;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.mgt.common.Count;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
||||||
@ -506,6 +507,86 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Count> getCountOfDevicesByDuration(PaginationRequest request, List<String> statusList, int tenantId,
|
||||||
|
String fromDate, String toDate)
|
||||||
|
throws DeviceManagementDAOException {
|
||||||
|
List<Count> countList = new ArrayList<>();
|
||||||
|
String ownership = request.getOwnership();
|
||||||
|
boolean isStatusProvided;
|
||||||
|
|
||||||
|
String sql =
|
||||||
|
"SELECT " +
|
||||||
|
"SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10) AS ENROLMENT_DATE, " +
|
||||||
|
"COUNT(SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10)) AS ENROLMENT_COUNT " +
|
||||||
|
"FROM DM_DEVICE AS d " +
|
||||||
|
"INNER JOIN DM_ENROLMENT AS e ON d.ID = e.DEVICE_ID " +
|
||||||
|
"INNER JOIN DM_DEVICE_TYPE AS t ON d.DEVICE_TYPE_ID = t.ID " +
|
||||||
|
"AND e.TENANT_ID = ? " +
|
||||||
|
"AND e.DATE_OF_ENROLMENT BETWEEN ? AND ? ";
|
||||||
|
|
||||||
|
//Add the query for status
|
||||||
|
StringBuilder sqlBuilder = new StringBuilder(sql);
|
||||||
|
isStatusProvided = buildStatusQuery(statusList, sqlBuilder);
|
||||||
|
sql = sqlBuilder.toString();
|
||||||
|
|
||||||
|
if (ownership != null) {
|
||||||
|
sql = sql + " AND e.OWNERSHIP = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " GROUP BY SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10) LIMIT ? OFFSET ?";
|
||||||
|
|
||||||
|
try (Connection conn = this.getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
int paramIdx = 1;
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
stmt.setString(paramIdx++, fromDate);
|
||||||
|
stmt.setString(paramIdx++, toDate);
|
||||||
|
if (isStatusProvided) {
|
||||||
|
for (String status : statusList) {
|
||||||
|
stmt.setString(paramIdx++, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ownership != null) {
|
||||||
|
stmt.setString(paramIdx++, ownership);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx++, request.getStartIndex());
|
||||||
|
stmt.setInt(paramIdx, request.getRowCount());
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
Count count = new Count(
|
||||||
|
rs.getString("ENROLMENT_DATE"),
|
||||||
|
rs.getInt("ENROLMENT_COUNT")
|
||||||
|
);
|
||||||
|
countList.add(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred while retrieving information of all " +
|
||||||
|
"registered devices under tenant id " + tenantId + " between " + fromDate + " to " + toDate;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new DeviceManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
return countList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean buildStatusQuery(List<String> statusList, StringBuilder sqlBuilder) {
|
||||||
|
if (statusList != null && !statusList.isEmpty() && !statusList.get(0).isEmpty()) {
|
||||||
|
sqlBuilder.append(" AND e.STATUS IN(");
|
||||||
|
for (int i = 0; i < statusList.size(); i++) {
|
||||||
|
sqlBuilder.append("?");
|
||||||
|
if (i != statusList.size() - 1) {
|
||||||
|
sqlBuilder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlBuilder.append(")");
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of devices that matches with the given device name and (or) device type.
|
* Get the list of devices that matches with the given device name and (or) device type.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -21,6 +21,7 @@ package org.wso2.carbon.device.mgt.core.dao.impl.device;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.mgt.common.Count;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
||||||
@ -671,6 +672,85 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Count> getCountOfDevicesByDuration(PaginationRequest request, List<String> statusList, int tenantId,
|
||||||
|
String fromDate, String toDate)
|
||||||
|
throws DeviceManagementDAOException {
|
||||||
|
List<Count> countList = new ArrayList<>();
|
||||||
|
String ownership = request.getOwnership();
|
||||||
|
boolean isStatusProvided;
|
||||||
|
|
||||||
|
String sql =
|
||||||
|
"SELECT " +
|
||||||
|
"SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10) AS ENROLMENT_DATE, " +
|
||||||
|
"COUNT(SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10)) AS ENROLMENT_COUNT " +
|
||||||
|
"FROM DM_DEVICE AS d " +
|
||||||
|
"INNER JOIN DM_ENROLMENT AS e ON d.ID = e.DEVICE_ID " +
|
||||||
|
"INNER JOIN DM_DEVICE_TYPE AS t ON d.DEVICE_TYPE_ID = t.ID " +
|
||||||
|
"AND e.TENANT_ID = ? " +
|
||||||
|
"AND e.DATE_OF_ENROLMENT BETWEEN ? AND ? ";
|
||||||
|
|
||||||
|
//Add the query for status
|
||||||
|
StringBuilder sqlBuilder = new StringBuilder(sql);
|
||||||
|
isStatusProvided = buildStatusQuery(statusList, sqlBuilder);
|
||||||
|
sql = sqlBuilder.toString();
|
||||||
|
|
||||||
|
if (ownership != null) {
|
||||||
|
sql = sql + " AND e.OWNERSHIP = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = sql + " GROUP BY SUBSTRING(e.DATE_OF_ENROLMENT, 1, 10) OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
|
||||||
|
|
||||||
|
try (Connection conn = this.getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
int paramIdx = 1;
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
stmt.setString(paramIdx++, fromDate);
|
||||||
|
stmt.setString(paramIdx++, toDate);
|
||||||
|
if (isStatusProvided) {
|
||||||
|
for (String status : statusList) {
|
||||||
|
stmt.setString(paramIdx++, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ownership != null) {
|
||||||
|
stmt.setString(paramIdx++, ownership);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx++, request.getStartIndex());
|
||||||
|
stmt.setInt(paramIdx, request.getRowCount());
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
Count count = new Count(
|
||||||
|
rs.getString("ENROLMENT_DATE"),
|
||||||
|
rs.getInt("ENROLMENT_COUNT")
|
||||||
|
);
|
||||||
|
countList.add(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred while retrieving information of all " +
|
||||||
|
"registered devices under tenant id " + tenantId + " between " + fromDate + " to " + toDate;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new DeviceManagementDAOException(msg, e);
|
||||||
|
}
|
||||||
|
return countList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean buildStatusQuery(List<String> statusList, StringBuilder sqlBuilder) {
|
||||||
|
if (statusList != null && !statusList.isEmpty() && !statusList.get(0).isEmpty()) {
|
||||||
|
sqlBuilder.append(" AND e.STATUS IN(");
|
||||||
|
for (int i = 0; i < statusList.size(); i++) {
|
||||||
|
sqlBuilder.append("?");
|
||||||
|
if (i != statusList.size() - 1) {
|
||||||
|
sqlBuilder.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlBuilder.append(")");
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSubscribedDeviceCount(List<Integer> deviceIds, int tenantId, String status)
|
public int getSubscribedDeviceCount(List<Integer> deviceIds, int tenantId, String status)
|
||||||
throws DeviceManagementDAOException {
|
throws DeviceManagementDAOException {
|
||||||
|
|||||||
@ -17,8 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.wso2.carbon.device.mgt.core.report.mgt;
|
package org.wso2.carbon.device.mgt.core.report.mgt;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.mgt.common.Count;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
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.PaginationRequest;
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
@ -32,7 +34,13 @@ import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
|
|||||||
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
|
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the service class for reports which calls dao classes and its method which are used for
|
* This is the service class for reports which calls dao classes and its method which are used for
|
||||||
@ -92,7 +100,8 @@ public class ReportManagementServiceImpl implements ReportManagementService {
|
|||||||
throws ReportManagementException {
|
throws ReportManagementException {
|
||||||
try {
|
try {
|
||||||
DeviceManagementDAOFactory.openConnection();
|
DeviceManagementDAOFactory.openConnection();
|
||||||
return deviceDAO.getDevicesByDurationCount(statusList, ownership, fromDate, toDate, DeviceManagementDAOUtil.getTenantId());
|
return deviceDAO.getDevicesByDurationCount(
|
||||||
|
statusList, ownership, fromDate, toDate, DeviceManagementDAOUtil.getTenantId());
|
||||||
} catch (DeviceManagementDAOException e) {
|
} catch (DeviceManagementDAOException e) {
|
||||||
String msg = "Error occurred in while retrieving device count by status for " + statusList + "devices.";
|
String msg = "Error occurred in while retrieving device count by status for " + statusList + "devices.";
|
||||||
log.error(msg, e);
|
log.error(msg, e);
|
||||||
@ -105,4 +114,98 @@ public class ReportManagementServiceImpl implements ReportManagementService {
|
|||||||
DeviceManagementDAOFactory.closeConnection();
|
DeviceManagementDAOFactory.closeConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonObject getCountOfDevicesByDuration(PaginationRequest request, List<String> statusList, String fromDate,
|
||||||
|
String toDate)
|
||||||
|
throws ReportManagementException {
|
||||||
|
try {
|
||||||
|
request = DeviceManagerUtil.validateDeviceListPageSize(request);
|
||||||
|
} catch (DeviceManagementException e) {
|
||||||
|
String msg = "Error occurred while validating device list page size";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ReportManagementException(msg, e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
DeviceManagementDAOFactory.openConnection();
|
||||||
|
List<Count> dateList = deviceDAO.getCountOfDevicesByDuration(
|
||||||
|
request,
|
||||||
|
statusList,
|
||||||
|
DeviceManagementDAOUtil.getTenantId(),
|
||||||
|
fromDate,
|
||||||
|
toDate
|
||||||
|
);
|
||||||
|
return buildCount(fromDate, toDate, dateList);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred while opening a connection " +
|
||||||
|
"to the data source";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ReportManagementException(msg, e);
|
||||||
|
} catch (DeviceManagementDAOException e) {
|
||||||
|
String msg = "Error occurred while retrieving Tenant ID between " + fromDate + " to " + toDate;
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ReportManagementException(msg, e);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
String msg = "Error occurred while building count";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new ReportManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
DeviceManagementDAOFactory.closeConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//NOTE: This is just a temporary method for retrieving device counts
|
||||||
|
public JsonObject buildCount(String start, String end, List<Count> countList) throws ParseException {
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
int prevDateAmount = 0;
|
||||||
|
boolean isDaily = false;
|
||||||
|
|
||||||
|
Date startDate = dateFormat.parse(start);
|
||||||
|
Date endDate = dateFormat.parse(end);
|
||||||
|
|
||||||
|
//Check duration between two given dates
|
||||||
|
long gap = endDate.getTime() - startDate.getTime();
|
||||||
|
long diffInDays = TimeUnit.MILLISECONDS.toDays(gap);
|
||||||
|
|
||||||
|
if (diffInDays < 7) {
|
||||||
|
isDaily = true;
|
||||||
|
} else if (diffInDays < 30) {
|
||||||
|
prevDateAmount = -7;
|
||||||
|
} else {
|
||||||
|
prevDateAmount = -30;
|
||||||
|
}
|
||||||
|
JsonObject resultObject = new JsonObject();
|
||||||
|
if (!isDaily) {
|
||||||
|
//Divide date duration into week or month blocks
|
||||||
|
while (endDate.after(startDate)) {
|
||||||
|
int sum = 0;
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(endDate);
|
||||||
|
calendar.add(Calendar.DAY_OF_YEAR, prevDateAmount);
|
||||||
|
Date previousDate = calendar.getTime();
|
||||||
|
if (startDate.after(previousDate)) {
|
||||||
|
previousDate = startDate;
|
||||||
|
}
|
||||||
|
//Loop count list which came from database to add them into week or month blocks
|
||||||
|
for (Count count : countList) {
|
||||||
|
if (dateFormat.parse(
|
||||||
|
count.getDate()).after(previousDate) &&
|
||||||
|
dateFormat.parse(count.getDate()).before(endDate
|
||||||
|
)) {
|
||||||
|
sum = sum + count.getCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Map date blocks and counts
|
||||||
|
resultObject.addProperty(
|
||||||
|
dateFormat.format(endDate) + " - " + dateFormat.format(previousDate), sum);
|
||||||
|
endDate = previousDate;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (Count count : countList) {
|
||||||
|
resultObject.addProperty(count.getDate(), count.getCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultObject;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,8 @@ package org.wso2.carbon.policy.mgt.core;
|
|||||||
|
|
||||||
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.Feature;
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.Profile;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.Profile;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
|
||||||
@ -81,4 +83,10 @@ public interface PolicyManagerService {
|
|||||||
NonComplianceData getDeviceCompliance(DeviceIdentifier deviceIdentifier) throws PolicyComplianceException;
|
NonComplianceData getDeviceCompliance(DeviceIdentifier deviceIdentifier) throws PolicyComplianceException;
|
||||||
|
|
||||||
boolean isCompliant(DeviceIdentifier deviceIdentifier) throws PolicyComplianceException;
|
boolean isCompliant(DeviceIdentifier deviceIdentifier) throws PolicyComplianceException;
|
||||||
|
|
||||||
|
PaginationResult getPolicyCompliance(
|
||||||
|
PaginationRequest paginationRequest, String policyId, boolean complianceStatus, boolean isPending, String fromDate, String toDate)
|
||||||
|
throws PolicyComplianceException;
|
||||||
|
|
||||||
|
List<ComplianceFeature> getNoneComplianceFeatures(int complianceStatusId) throws PolicyComplianceException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,8 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
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.Feature;
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
|
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
|
||||||
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
|
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.Policy;
|
||||||
@ -248,4 +250,16 @@ public class PolicyManagerServiceImpl implements PolicyManagerService {
|
|||||||
public boolean isCompliant(DeviceIdentifier deviceIdentifier) throws PolicyComplianceException {
|
public boolean isCompliant(DeviceIdentifier deviceIdentifier) throws PolicyComplianceException {
|
||||||
return monitoringManager.isCompliant(deviceIdentifier);
|
return monitoringManager.isCompliant(deviceIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaginationResult getPolicyCompliance(
|
||||||
|
PaginationRequest paginationRequest, String policyId, boolean complianceStatus, boolean isPending, String fromDate, String toDate)
|
||||||
|
throws PolicyComplianceException {
|
||||||
|
return monitoringManager.getPolicyCompliance(paginationRequest, policyId, complianceStatus, isPending, fromDate, toDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ComplianceFeature> getNoneComplianceFeatures(int complianceStatusId) throws PolicyComplianceException {
|
||||||
|
return monitoringManager.getNoneComplianceFeatures(complianceStatusId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package org.wso2.carbon.policy.mgt.core.dao;
|
package org.wso2.carbon.policy.mgt.core.dao;
|
||||||
|
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceData;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
||||||
import org.wso2.carbon.policy.mgt.common.monitor.PolicyDeviceWrapper;
|
import org.wso2.carbon.policy.mgt.common.monitor.PolicyDeviceWrapper;
|
||||||
@ -55,6 +57,10 @@ public interface MonitoringDAO {
|
|||||||
|
|
||||||
List<NonComplianceData> getCompliance() throws MonitoringDAOException;
|
List<NonComplianceData> getCompliance() throws MonitoringDAOException;
|
||||||
|
|
||||||
|
List<ComplianceData> getAllComplianceDevices(
|
||||||
|
PaginationRequest paginationRequest, String policyId, boolean complianceStatus, boolean isPending, String fromDate, String toDate)
|
||||||
|
throws MonitoringDAOException;
|
||||||
|
|
||||||
List<ComplianceFeature> getNoneComplianceFeatures(int policyComplianceStatusId) throws MonitoringDAOException;
|
List<ComplianceFeature> getNoneComplianceFeatures(int policyComplianceStatusId) throws MonitoringDAOException;
|
||||||
|
|
||||||
void deleteNoneComplianceData(int policyComplianceStatusId) throws MonitoringDAOException;
|
void deleteNoneComplianceData(int policyComplianceStatusId) throws MonitoringDAOException;
|
||||||
|
|||||||
@ -22,6 +22,8 @@ package org.wso2.carbon.policy.mgt.core.dao.impl;
|
|||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
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.policy.mgt.monitor.ComplianceData;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
||||||
import org.wso2.carbon.policy.mgt.common.monitor.PolicyDeviceWrapper;
|
import org.wso2.carbon.policy.mgt.common.monitor.PolicyDeviceWrapper;
|
||||||
@ -347,6 +349,97 @@ public class MonitoringDAOImpl implements MonitoringDAO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ComplianceData> getAllComplianceDevices(
|
||||||
|
PaginationRequest paginationRequest,
|
||||||
|
String policyId,
|
||||||
|
boolean complianceStatus,
|
||||||
|
boolean isPending,
|
||||||
|
String fromDate,
|
||||||
|
String toDate)
|
||||||
|
throws MonitoringDAOException {
|
||||||
|
List<ComplianceData> complianceDataList = new ArrayList<>();
|
||||||
|
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||||
|
|
||||||
|
String query =
|
||||||
|
"SELECT " +
|
||||||
|
"DEVICE.NAME, " +
|
||||||
|
"DM_DEVICE_TYPE.NAME AS DEVICE_TYPE, " +
|
||||||
|
"ENROLLMENT.OWNER, " +
|
||||||
|
"DM_POLICY.NAME AS POLICY_NAME, " +
|
||||||
|
"POLICY.* " +
|
||||||
|
"FROM DM_POLICY_COMPLIANCE_STATUS AS POLICY, DM_DEVICE AS DEVICE, " +
|
||||||
|
"DM_ENROLMENT AS ENROLLMENT, DM_POLICY, DM_DEVICE_TYPE " +
|
||||||
|
"WHERE DEVICE.ID=POLICY.DEVICE_ID " +
|
||||||
|
"AND DEVICE.ID=ENROLLMENT.DEVICE_ID " +
|
||||||
|
"AND POLICY.POLICY_ID=DM_POLICY.ID " +
|
||||||
|
"AND DEVICE.DEVICE_TYPE_ID=DM_DEVICE_TYPE.ID " +
|
||||||
|
"AND POLICY.TENANT_ID = ? AND POLICY.STATUS = ?";
|
||||||
|
|
||||||
|
if (isPending) {
|
||||||
|
query = query + " AND POLICY.LAST_SUCCESS_TIME IS NULL " +
|
||||||
|
"AND POLICY.LAST_FAILED_TIME IS NULL";
|
||||||
|
} else {
|
||||||
|
query = query + " AND (POLICY.LAST_SUCCESS_TIME IS NOT NULL " +
|
||||||
|
"OR POLICY.LAST_FAILED_TIME IS NOT NULL)";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policyId != null) {
|
||||||
|
query = query + " AND POLICY.POLICY_ID = ?";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromDate != null && toDate != null) {
|
||||||
|
if (!complianceStatus) {
|
||||||
|
query = query + " AND POLICY.LAST_FAILED_TIME BETWEEN ? AND ?";
|
||||||
|
} else {
|
||||||
|
query = query + " AND POLICY.LAST_SUCCESS_TIME BETWEEN ? AND ?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query = query + " LIMIT ?,?";
|
||||||
|
|
||||||
|
try (Connection conn = this.getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(query);) {
|
||||||
|
int paramIdx = 1;
|
||||||
|
stmt.setInt(paramIdx++, tenantId);
|
||||||
|
stmt.setBoolean(paramIdx++, complianceStatus);
|
||||||
|
if (policyId != null) {
|
||||||
|
stmt.setInt(paramIdx++, Integer.parseInt(policyId));
|
||||||
|
}
|
||||||
|
if (fromDate != null && toDate != null) {
|
||||||
|
stmt.setString(paramIdx++, fromDate);
|
||||||
|
stmt.setString(paramIdx++, toDate);
|
||||||
|
}
|
||||||
|
stmt.setInt(paramIdx++, paginationRequest.getStartIndex());
|
||||||
|
stmt.setInt(paramIdx, paginationRequest.getRowCount());
|
||||||
|
|
||||||
|
try (ResultSet resultSet = stmt.executeQuery()) {
|
||||||
|
while (resultSet.next()) {
|
||||||
|
ComplianceData complianceData = new ComplianceData();
|
||||||
|
complianceData.setId(resultSet.getInt("ID"));
|
||||||
|
complianceData.setDeviceId(resultSet.getInt("DEVICE_ID"));
|
||||||
|
complianceData.setDeviceName(resultSet.getString("NAME"));
|
||||||
|
complianceData.setDeviceType(resultSet.getString("DEVICE_TYPE"));
|
||||||
|
complianceData.setOwner(resultSet.getString("OWNER"));
|
||||||
|
complianceData.setEnrolmentId(resultSet.getInt("ENROLMENT_ID"));
|
||||||
|
complianceData.setPolicyId(resultSet.getInt("POLICY_ID"));
|
||||||
|
complianceData.setPolicyName(resultSet.getString("POLICY_NAME"));
|
||||||
|
complianceData.setStatus(resultSet.getBoolean("STATUS"));
|
||||||
|
complianceData.setAttempts(resultSet.getInt("ATTEMPTS"));
|
||||||
|
complianceData.setLastRequestedTime(resultSet.getTimestamp("LAST_REQUESTED_TIME"));
|
||||||
|
complianceData.setLastFailedTime(resultSet.getTimestamp("LAST_FAILED_TIME"));
|
||||||
|
complianceData.setLastSucceededTime(resultSet.getTimestamp("LAST_SUCCESS_TIME"));
|
||||||
|
complianceDataList.add(complianceData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Unable to retrieve compliance data from database.";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new MonitoringDAOException(msg, e);
|
||||||
|
}
|
||||||
|
return complianceDataList;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ComplianceFeature> getNoneComplianceFeatures(int policyComplianceStatusId) throws
|
public List<ComplianceFeature> getNoneComplianceFeatures(int policyComplianceStatusId) throws
|
||||||
MonitoringDAOException {
|
MonitoringDAOException {
|
||||||
|
|||||||
@ -21,6 +21,8 @@ package org.wso2.carbon.policy.mgt.core.mgt;
|
|||||||
|
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
|
||||||
@ -41,4 +43,11 @@ public interface MonitoringManager {
|
|||||||
|
|
||||||
List<String> getDeviceTypes() throws PolicyComplianceException;
|
List<String> getDeviceTypes() throws PolicyComplianceException;
|
||||||
|
|
||||||
|
PaginationResult getPolicyCompliance(
|
||||||
|
PaginationRequest paginationRequest, String policyId, boolean complianceStatus, boolean isPending, String fromDate, String toDate)
|
||||||
|
throws PolicyComplianceException;
|
||||||
|
|
||||||
|
List<ComplianceFeature> getNoneComplianceFeatures(int complianceStatusId)
|
||||||
|
throws PolicyComplianceException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,11 +22,14 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.wso2.carbon.device.mgt.common.Device;
|
import org.wso2.carbon.device.mgt.common.Device;
|
||||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationRequest;
|
||||||
|
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
|
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
|
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
|
||||||
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
|
||||||
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
|
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
|
||||||
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceData;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData;
|
||||||
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
|
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
|
||||||
@ -371,6 +374,52 @@ public class MonitoringManagerImpl implements MonitoringManager {
|
|||||||
return deviceTypes;
|
return deviceTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PaginationResult getPolicyCompliance(
|
||||||
|
PaginationRequest paginationRequest, String policyId,
|
||||||
|
boolean complianceStatus, boolean isPending, String fromDate, String toDate)
|
||||||
|
throws PolicyComplianceException {
|
||||||
|
PaginationResult paginationResult = new PaginationResult();
|
||||||
|
try {
|
||||||
|
PolicyManagementDAOFactory.openConnection();
|
||||||
|
List<ComplianceData> complianceDataList = monitoringDAO
|
||||||
|
.getAllComplianceDevices(paginationRequest, policyId, complianceStatus, isPending, fromDate, toDate);
|
||||||
|
paginationResult.setData(complianceDataList);
|
||||||
|
paginationResult.setRecordsTotal(complianceDataList.size());
|
||||||
|
} catch (MonitoringDAOException e) {
|
||||||
|
String msg = "Unable to retrieve compliance data";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new PolicyComplianceException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred while opening a connection to the data source";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new PolicyComplianceException(msg, e);
|
||||||
|
} finally {
|
||||||
|
PolicyManagementDAOFactory.closeConnection();
|
||||||
|
}
|
||||||
|
return paginationResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ComplianceFeature> getNoneComplianceFeatures(int complianceStatusId) throws PolicyComplianceException {
|
||||||
|
List<ComplianceFeature> complianceFeatureList;
|
||||||
|
try {
|
||||||
|
PolicyManagementDAOFactory.openConnection();
|
||||||
|
complianceFeatureList = monitoringDAO.getNoneComplianceFeatures(complianceStatusId);
|
||||||
|
} catch (MonitoringDAOException e) {
|
||||||
|
String msg = "Unable to retrieve non compliance features";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new PolicyComplianceException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred while opening a connection to the data source";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new PolicyComplianceException(msg, e);
|
||||||
|
} finally {
|
||||||
|
PolicyManagementDAOFactory.closeConnection();
|
||||||
|
}
|
||||||
|
return complianceFeatureList;
|
||||||
|
}
|
||||||
|
|
||||||
private void addMonitoringOperationsToDatabase(List<Device> devices)
|
private void addMonitoringOperationsToDatabase(List<Device> devices)
|
||||||
throws PolicyComplianceException, OperationManagementException, InvalidDeviceException {
|
throws PolicyComplianceException, OperationManagementException, InvalidDeviceException {
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user