Merge branch 'master' of https://github.com/wso2/carbon-device-mgt-plugins into entgra-master

# Conflicts:
#	pom.xml
revert-dabc3590
charitha 6 years ago
commit 8865404702

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2017, 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.
-->
<eventPublisher name="WSO2IoT-DeviceOperation-Publisher" xmlns="http://wso2.org/carbon/eventpublisher">
<from streamName="org.wso2.iot.operation" version="1.0.0"/>
<mapping customMapping="enable" type="text">
<inline>
{
"deviceIdentifiers": {{meta_deviceIdentifiers}},
"deviceType": "{{meta_deviceType}}",
"operation": {
"code": "{{code}}",
"type": "{{type}}",
"status": "PENDING",
"isEnabled": "{{isEnabled}}",
"payLoad": "{{payLoad}}"
}
}
</inline>
</mapping>
<to eventAdapterType="oauth-http">
<property name="http.client.method">HttpPost</property>
<property name="http.url">https://localhost:9443/api/device-mgt/v1.0/devices/{deviceType}/operations</property>
<property name="http.url.templated">true</property>
</to>
</eventPublisher>

@ -0,0 +1,16 @@
/* Enter a unique ExecutionPlan */
@Plan:name('WSO2IoT-Operation-ExecutionPlan')
/* Enter a unique description for ExecutionPlan */
@Plan:description('Publish operations to devices coming from org.wso2.iot.operation stream')
/* define streams/tables and write queries here ... */
@Plan:trace('false')
@Import('org.wso2.iot.operation:1.0.0')
define stream dataIn (meta_deviceIdentifiers string, meta_deviceType string, code string, type string, isEnabled bool, payLoad string);
from dataIn#device:addOperation(meta_deviceIdentifiers, meta_deviceType, code, type, isEnabled, payLoad)
select *
insert into drop;

@ -1,22 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?><!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2018, 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
~ 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
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name="WSO2IoT-DeviceOperation-Publisher" version="1.0.0" type="event/publisher"
serverRole="DataAnalyticsServer">
<file>WSO2IoT-DeviceOperation-Publisher_1.0.0.xml</file>
<artifact name= "WSO2IoT-Operation-ExecutionPlan" version="1.0.0" type="event/execution-plan" serverRole="DataAnalyticsServer">
<file>WSO2IoT-Operation-ExecutionPlan.siddhiql</file>
</artifact>

@ -30,7 +30,7 @@
serverRole="DataAnalyticsServer"/>
<dependency artifact="WSO2IoT-OperationResponse-Receiver" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
<dependency artifact="WSO2IoT-DeviceOperation-Publisher" version="1.0.0" include="true"
<dependency artifact="WSO2IoT-Operation-ExecutionPlan" version="1.0.0" include="true"
serverRole="DataAnalyticsServer"/>
</artifact>
</artifacts>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>iot-analytics</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -1,29 +0,0 @@
/* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-EventsFusionGenerateNotifications')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* define streams/tables and write queries here ... */
@Plan:trace('false')
@Import('org.wso2.geo.ProcessedSpatialEvents:1.0.0')
define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string, state string, information string );
@Export('iot.per.device.stream.geo.AlertNotifications:1.0.0')
define stream alertsOut ( id string, state string, information string, timeStamp long, latitude double, longitude double, type string);
@Export('iot.per.device.stream.geo.FusedSpatialEvent:1.0.0')
define stream dataOut ( id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, state string, information string, notify bool );
from dataIn#window.geodashboard:eventsFusion(eventId, state, information)
insert into innerStream;
from innerStream
select id, latitude, longitude, timeStamp, type, speed, heading, state , information, geodashboard:needToNotify(id,information) as notify
insert into dataOut;
from dataOut[notify == true]
select id, state, information,timeStamp, latitude, longitude, type
insert into alertsOut;

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><!--
~ Copyright (c) 2016, 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.
-->
<artifact name="Geo-ExecutionPlan-EventsFusionGenerateNotifications" version="1.0.0" type="event/execution-plan" serverRole="GeoDashboard">
<file>Geo-ExecutionPlan-EventsFusionGenerateNotifications-1.0.0.siddhiql</file>
</artifact>

@ -7,11 +7,11 @@
/* define streams/tables and write queries here ... */
@Import('org.wso2.geo.StandardSpatialEvents:1.0.0')
define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string);
define stream dataIn (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string);
@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0')
define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string, state string, information string);
@Export('iot.per.device.stream.geo.FusedSpatialEvent:1.0.0')
define stream dataOut (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, state string, information string, notify bool);
from dataIn#geodashboard:subscribe()
select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "NORMAL" as state, "Normal driving pattern" as information
from dataIn
select id, owner, latitude, longitude,timeStamp, type ,speed, heading, "NORMAL" as state, "Normal driving pattern" as information, false as notify
insert into dataOut;

@ -9,6 +9,14 @@
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>owner</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>true</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>latitude</Name>
<IsFacet>false</IsFacet>

@ -9,6 +9,14 @@
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>owner</Name>
<IsFacet>false</IsFacet>
<EnableIndexing>true</EnableIndexing>
<IsPrimaryKey>false</IsPrimaryKey>
<EnableScoreParam>false</EnableScoreParam>
<Type>STRING</Type>
</ColumnDefinition>
<ColumnDefinition>
<Name>state</Name>
<IsFacet>false</IsFacet>

@ -9,11 +9,14 @@
@Plan:trace('false')
@Import('org.wso2.iot.LocationStream:1.0.0')
define stream dataIn (meta_deviceId string, meta_deviceType string, timeStamp long, latitude double, longitude double);
define stream dataIn (meta_deviceId string, meta_owner string, meta_deviceType string, timeStamp long, latitude double, longitude double);
@Export('org.wso2.geo.StandardSpatialEvents:1.0.0')
define stream dataOut ( id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string );
define stream dataOut (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string);
from dataIn
select meta_deviceId as id, latitude, longitude, timeStamp,
meta_deviceType as type, 0.0f as speed, 0.0f as heading, UUID() as eventId insert into dataOut
from every fs1=dataIn -> fs2=dataIn[fs2.timeStamp > fs1.timeStamp and fs1.meta_deviceId == fs2.meta_deviceId]
select fs1.meta_deviceId as id, fs1.meta_owner as owner, fs2.latitude, fs2.longitude, fs2.timeStamp, fs1.meta_deviceType as type,
convert(geo:distance(fs2.latitude, fs2.longitude, fs1.latitude, fs1.longitude) * 3600/(fs2.timeStamp - fs1.timeStamp), 'float') as speed,
0.0f as heading, UUID() as eventId
group by fs1.meta_deviceId
insert into dataOut

@ -0,0 +1,16 @@
/* Enter a unique ExecutionPlan */
@Plan:name('WSO2IoT-GeoAlerts-ExecutionPlan')
/* Enter a unique description for ExecutionPlan */
@Plan:description('To convert the WSO2 IoT event incoming stream to relavant streams')
/* define streams/tables and write queries here ... */
@Plan:trace('false')
@Import('iot.per.device.stream.geo.AlertNotifications:1.0.0')
define stream dataIn (id string, owner string, state string, information string, timeStamp long, latitude double, longitude double, type string);
from dataIn#device:addNotification(id, type, information)
select *
insert into ignore;

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?><!--
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. licenses this file to you under the Apache License,
@ -6,16 +7,17 @@
~ in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~ 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
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<artifact name="org.wso2.geo.ProcessedSpatialEvents" version="1.0.0" type="event/stream" serverRole="GeoDashboard">
<file>org.wso2.geo.ProcessedSpatialEvents-1.0.0.json</file>
<artifact name= "WSO2IoT-GeoAlerts-ExecutionPlan" version="1.0.0" type="event/execution-plan" serverRole="DataAnalyticsServer">
<file>WSO2IoT-GeoAlerts-ExecutionPlan.siddhiql</file>
</artifact>

@ -22,16 +22,15 @@
<!-- CEP Artifacts -->
<dependency artifact="WSO2IoT-Geo-Event-Receiver" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="WSO2IoT-EventSink-FusedStream" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="Geo-ExecutionPlan-EventsFusionGenerateNotifications" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="Geo-ExecutionPlan-Pass_through" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="WSO2IoT-Geo-ExecutionPlan" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="WSO2IoT-GeoAlerts-ExecutionPlan" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="WSO2IoT-Geo-AlertNotifications" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="Geo-Publisher-WebSocketLocal-FusedSpacialEvent" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="Geo-Publisher-WebSocketLocal-GeoAlertNotifications" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="iot.per.device.stream.geo.AlertNotifications" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="iot.per.device.stream.geo.FusedSpatialEvent" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="org.wso2.iot.LocationStream" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="org.wso2.geo.ProcessedSpatialEvents" version="1.0.0" include="true" serverRole="GeoDashboard"/>
<dependency artifact="org.wso2.geo.StandardSpatialEvents" version="1.0.0" include="true" serverRole="GeoDashboard"/>
</artifact>
</artifacts>

@ -1,48 +0,0 @@
{
"name": "org.wso2.geo.ProcessedSpatialEvents",
"version": "1.0.0",
"nickName": "",
"description": "",
"payloadData": [
{
"name": "id",
"type": "STRING"
},
{
"name": "latitude",
"type": "DOUBLE"
},
{
"name": "longitude",
"type": "DOUBLE"
},
{
"name": "timeStamp",
"type": "LONG"
},
{
"name": "type",
"type": "STRING"
},
{
"name": "speed",
"type": "FLOAT"
},
{
"name": "heading",
"type": "FLOAT"
},
{
"name": "eventId",
"type": "STRING"
},
{
"name": "state",
"type": "STRING"
},
{
"name": "information",
"type": "STRING"
}
]
}

@ -8,6 +8,10 @@
"name": "deviceId",
"type": "STRING"
},
{
"name": "owner",
"type": "STRING"
},
{
"name": "deviceType",
"type": "STRING"

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>analytics</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -3,7 +3,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>androidsense-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>arduino-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>raspberrypi-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,7 +23,7 @@
<parent>
<artifactId>virtual-fire-alarm-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>device-types</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -18,7 +18,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>appm-connector</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -18,7 +18,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>appm-connector</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>cdmf-transport-adapters</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>mb-extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>mb-extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>carbon-device-mgt-plugins-parent</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>pull-notification-listeners</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>remote-session-extension</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>remote-session-extension</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -45,6 +45,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.Map;
/**
@ -72,66 +73,82 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
sessionQueryParamList.add(session.getQueryString());
sessionQueryParam.put(RemoteSessionConstants.QUERY_STRING, sessionQueryParamList);
// Validate the token
OAuthAuthenticator oAuthAuthenticator = RemoteSessionManagementDataHolder.getInstance().getOauthAuthenticator();
AuthenticationInfo authenticationInfo = oAuthAuthenticator.isAuthenticated(sessionQueryParam);
// if session initiated using operation id means request came from device.
if (operationId == null) {
// Validate the token
OAuthAuthenticator oAuthAuthenticator = RemoteSessionManagementDataHolder.getInstance().getOauthAuthenticator();
AuthenticationInfo authenticationInfo = oAuthAuthenticator.isAuthenticated(sessionQueryParam);
if (authenticationInfo != null && authenticationInfo.isAuthenticated()) {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(authenticationInfo
.getTenantDomain()
, true);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(authenticationInfo.getUsername());
if (deviceId != null && !deviceId.isEmpty() && deviceType != null && !deviceType.isEmpty()) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(deviceType);
if (authenticationInfo != null && authenticationInfo.isAuthenticated()) {
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(authenticationInfo
.getTenantDomain()
, true);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(authenticationInfo.getUsername());
if (deviceId != null && !deviceId.isEmpty() && deviceType != null && !deviceType.isEmpty()) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
deviceIdentifier.setId(deviceId);
deviceIdentifier.setType(deviceType);
// Check authorization of user for given device
boolean userAuthorized = RemoteSessionManagementDataHolder.getInstance()
.getDeviceAccessAuthorizationService()
.isUserAuthorized(deviceIdentifier, authenticationInfo.getUsername());
if (userAuthorized) {
// set common settings for session
session.setMaxBinaryMessageBufferSize(RemoteSessionManagementDataHolder.getInstance()
.getMaxMessageBufferSize());
session.setMaxTextMessageBufferSize(RemoteSessionManagementDataHolder.getInstance()
.getMaxMessageBufferSize());
session.setMaxIdleTimeout(RemoteSessionManagementDataHolder.getInstance().getMaxIdleTimeout());
// Check authorization of user for given device
boolean userAuthorized = RemoteSessionManagementDataHolder.getInstance()
.getDeviceAccessAuthorizationService()
.isUserAuthorized(deviceIdentifier, authenticationInfo.getUsername());
if (userAuthorized) {
// set common settings for session
session.setMaxBinaryMessageBufferSize(RemoteSessionManagementDataHolder.getInstance()
.getMaxMessageBufferSize());
session.setMaxTextMessageBufferSize(RemoteSessionManagementDataHolder.getInstance()
.getMaxMessageBufferSize());
session.setMaxIdleTimeout(RemoteSessionManagementDataHolder.getInstance().getMaxIdleTimeout());
initializeClientSession(session, authenticationInfo.getTenantDomain(), deviceType, deviceId);
log.info("Current remote sessions count: " + RemoteSessionManagementDataHolder.getInstance()
.getSessionMap().size());
// if session initiated using operation id means request came from device
if (operationId != null) {
// create new device session
initializeDeviceSession(session, authenticationInfo.getTenantDomain(), deviceType, deviceId,
operationId);
} else {
// create new client session
initializeClientSession(session, authenticationInfo.getTenantDomain(), deviceType,
deviceId);
throw new RemoteSessionManagementException("Missing device Id or type ");
}
log.info("Current remote sessions count: " + RemoteSessionManagementDataHolder.getInstance()
.getSessionMap().size());
} else {
throw new RemoteSessionManagementException("Missing device Id or type ");
throw new RemoteSessionManagementException("Unauthorized Access for the device Type : " + deviceType
+ " , deviceId : " + deviceId);
}
} else {
throw new RemoteSessionManagementException("Unauthorized Access for the device Type : " + deviceType
+ " , deviceId : " + deviceId);
} catch (OperationManagementException | InvalidDeviceException e) {
throw new RemoteSessionManagementException("Error occurred while adding initial operation for the " +
"device Type : " + deviceType + " , deviceId : " + deviceId);
} catch (DeviceAccessAuthorizationException e) {
throw new RemoteSessionManagementException("Error occurred while device access authorization for the " +
"device Type : " + deviceType + " , " + "deviceId : " + deviceId);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
} catch (OperationManagementException | InvalidDeviceException e) {
throw new RemoteSessionManagementException("Error occurred while adding initial operation for the " +
"device Type : " + deviceType + " , deviceId : " + deviceId);
} catch (DeviceAccessAuthorizationException e) {
throw new RemoteSessionManagementException("Error occurred while device access authorization for the " +
"device Type : " + deviceType + " , " + "deviceId : " + deviceId);
} finally {
PrivilegedCarbonContext.endTenantFlow();
} else {
throw new RemoteSessionManagementException("Invalid token");
}
} else {
throw new RemoteSessionManagementException("Invalid token");
// set common settings for session
session.setMaxBinaryMessageBufferSize(RemoteSessionManagementDataHolder.getInstance()
.getMaxMessageBufferSize());
session.setMaxTextMessageBufferSize(RemoteSessionManagementDataHolder.getInstance()
.getMaxMessageBufferSize());
session.setMaxIdleTimeout(RemoteSessionManagementDataHolder.getInstance().getMaxIdleTimeout());
String uuid = session.getQueryString();
if (uuid != null && uuid.isEmpty()) {
log.error("Could not find a UUID related to the remote session");
} else {
String tenantDomain = RemoteSessionManagementDataHolder.getInstance().getUuidToTenantMap().remove(uuid);
if (tenantDomain == null || tenantDomain.isEmpty()) {
log.error("Invalid UUID, could not create the remote session");
} else {
// create new device session
initializeDeviceSession(session, tenantDomain, deviceType, deviceId, operationId, uuid);
}
}
}
}
@ -194,6 +211,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
.getId());
if (remoteSession != null) {
//String operationId = remoteSession.getOperationId();
RemoteSessionManagementDataHolder.getInstance().getUuidToTenantMap().remove(remoteSession.getUuidToValidateDevice());
String deviceKey = remoteSession.getTenantDomain() + "/" + remoteSession.getDeviceType() + "/" +
remoteSession.getDeviceId();
RemoteSession lastSession = RemoteSessionManagementDataHolder.getInstance()
@ -239,8 +257,9 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
private void initializeClientSession(Session session, String tenantDomain, String deviceType, String deviceId) throws RemoteSessionManagementException,
OperationManagementException, InvalidDeviceException {
String uuidToValidateDevice = UUID.randomUUID().toString();
RemoteSession clientRemote = new RemoteSession(session, tenantDomain, deviceType, deviceId, RemoteSessionConstants
.CONNECTION_TYPE.CLIENT);
.CONNECTION_TYPE.CLIENT, uuidToValidateDevice);
String deviceKey = tenantDomain + "/" + deviceType + "/" + deviceId;
// Create new remote control operation to start the session
RemoteSession activeSession = RemoteSessionManagementDataHolder.getInstance().getActiveDeviceClientSessionMap
@ -277,6 +296,13 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
operation.setControl(Operation.Control.NO_REPEAT);
JSONObject payload = new JSONObject();
payload.put("serverUrl", RemoteSessionManagementDataHolder.getInstance().getServerUrl());
payload.put("uuidToValidateDevice", uuidToValidateDevice);
RemoteSessionManagementDataHolder.getInstance().getUuidToTenantMap
().put(uuidToValidateDevice, tenantDomain);
if (log.isDebugEnabled()) {
log.debug("UUID " + uuidToValidateDevice + " is generated against the tenant : " +
RemoteSessionManagementDataHolder.getInstance().getUuidToTenantMap().get(uuidToValidateDevice));
}
operation.setPayLoad(payload.toString());
String date = new SimpleDateFormat(RemoteSessionConstants.DATE_FORMAT_NOW).format(new Date());
operation.setCreatedTimeStamp(date);
@ -287,6 +313,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
clientRemote.setOperationId(activity.getActivityId().replace(DeviceManagementConstants
.OperationAttributes.ACTIVITY, ""));
RemoteSessionManagementDataHolder.getInstance().getSessionMap().put(session.getId(), clientRemote);
log.info("Client remote session opened for session id: " + session.getId() + " device Type : " +
deviceType + " , " + "deviceId : " + deviceId);
} else {
@ -307,7 +334,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
* @throws RemoteSessionManagementException throws when session has errors with accessing device resources
*/
private void initializeDeviceSession(Session session, String tenantDomain, String deviceType, String deviceId,
String operationId) throws RemoteSessionManagementException {
String operationId, String uuidToValidateDevice) throws RemoteSessionManagementException {
String deviceKey = tenantDomain + "/" + deviceType + "/" + deviceId;
RemoteSession activeSession = RemoteSessionManagementDataHolder.getInstance()
.getActiveDeviceClientSessionMap().get(deviceKey);
@ -317,7 +344,7 @@ public class RemoteSessionManagementServiceImpl implements RemoteSessionManageme
if (clientRemote != null) {
if (clientRemote.getOperationId().equals(operationId)) {
RemoteSession deviceRemote = new RemoteSession(session, tenantDomain, deviceType, deviceId,
RemoteSessionConstants.CONNECTION_TYPE.DEVICE);
RemoteSessionConstants.CONNECTION_TYPE.DEVICE, uuidToValidateDevice);
deviceRemote.setOperationId(operationId);
deviceRemote.setPeerSession(clientRemote);
clientRemote.setPeerSession(deviceRemote);

@ -34,7 +34,11 @@ import java.nio.ByteBuffer;
public class RemoteSession {
private static final Log log = LogFactory.getLog(RemoteSession.class);
private String tenantDomain, operationId, deviceType, deviceId;
private String tenantDomain;
private String operationId;
private String deviceType;
private String deviceId;
private String uuidToValidateDevice;
private long lastMessageTimeStamp = System.currentTimeMillis();
private RemoteSession peerSession;
private Session mySession;
@ -45,12 +49,13 @@ public class RemoteSession {
private RemoteSessionConstants.CONNECTION_TYPE connectionType;
public RemoteSession(Session session, String tenantDomain, String deviceType, String deviceId,
RemoteSessionConstants.CONNECTION_TYPE connectionType) {
RemoteSessionConstants.CONNECTION_TYPE connectionType, String uuidToValidateDevice) {
this.mySession = session;
this.deviceType = deviceType;
this.deviceId = deviceId;
this.tenantDomain = tenantDomain;
this.connectionType = connectionType;
this.uuidToValidateDevice = uuidToValidateDevice;
maxMessagesPerSecond = RemoteSessionManagementDataHolder.getInstance().getMaxMessagesPerSecond();
messageAllowance = maxMessagesPerSecond;
messageRatePerSecond = (double) maxMessagesPerSecond / 1000;
@ -109,6 +114,10 @@ public class RemoteSession {
}
}
public String getUuidToValidateDevice() {
return uuidToValidateDevice;
}
public Session getMySession() {
return mySession;
}

@ -43,6 +43,11 @@ public class RemoteSessionManagementDataHolder {
private OAuthAuthenticator oAuthAuthenticator;
private Map<String, RemoteSession> activeDeviceClientSessionMap = new ConcurrentHashMap<String, RemoteSession>();
private Map<String, RemoteSession> sessionMap = new ConcurrentHashMap<String, RemoteSession>();
private Map<String, String> uuidToTenantMap = new ConcurrentHashMap<>();
public Map<String, String> getUuidToTenantMap() {
return uuidToTenantMap;
}
public static RemoteSessionManagementDataHolder getInstance() {
return thisInstance;

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>siddhi-extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -55,6 +55,42 @@
<groupId>org.json.wso2</groupId>
<artifactId>json</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jaxrs</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</dependency>
<dependency>
<groupId>com.h2database.wso2</groupId>
<artifactId>h2-database-engine</artifactId>
@ -125,14 +161,43 @@
org.wso2.extension.siddhi.device.*
</Export-Package>
<Import-Package>
feign,
feign.codec,
feign.auth,
feign.gson,
feign.slf4j,
javax.net.ssl,
javax.xml,
javax.xml.bind,
javax.xml.bind.annotation,
javax.xml.parsers;resolution:=optional,
org.apache.commons.lang,
org.w3c.dom,
org.wso2.carbon.base,
org.wso2.carbon.utils,
org.wso2.carbon.user.api,
org.json;version="${orbit.version.json.range}",
org.wso2.siddhi.core.*,
org.wso2.siddhi.query.api.*,
org.wso2.carbon.device.mgt.core.*,
org.wso2.carbon.device.mgt.common.*,
org.wso2.carbon.identity.jwt.client.*,
org.apache.commons.logging,
org.wso2.carbon.context
org.wso2.carbon.context,
android.util;resolution:=optional,
javax.annotation;resolution:=optional,
javax.net;resolution:=optional,
javax.security.auth.x500;resolution:=optional,
javax.crypto;resolution:=optional,
javax.crypto.spec;resolution:=optional
</Import-Package>
<Embed-Dependency>
jsr311-api,
feign-jaxrs,
feign-okhttp,
okhttp,
okio
</Embed-Dependency>
</instructions>
</configuration>
</plugin>

@ -0,0 +1,172 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.notification.mgt.Notification;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.extension.siddhi.device.utils.DeviceUtils;
import org.wso2.siddhi.core.config.ExecutionPlanContext;
import org.wso2.siddhi.core.exception.ExecutionPlanRuntimeException;
import org.wso2.siddhi.core.executor.ExpressionExecutor;
import org.wso2.siddhi.core.query.processor.stream.function.StreamFunctionProcessor;
import org.wso2.siddhi.query.api.definition.AbstractDefinition;
import org.wso2.siddhi.query.api.definition.Attribute;
import org.wso2.siddhi.query.api.exception.ExecutionPlanValidationException;
import java.util.ArrayList;
import java.util.List;
public class AddNotificationFunctionProcessor extends StreamFunctionProcessor {
private static final Log log = LogFactory.getLog(AddNotificationFunctionProcessor.class);
/**
* The init method of the StreamProcessor, this method will be called before other methods
*
* @param abstractDefinition the incoming stream definition
* @param attributeExpressionExecutors the executors of each function parameters
* @param executionPlanContext the context of the execution plan
* @return the additional output attributes introduced by the function
*/
@Override
protected List<Attribute> init(AbstractDefinition abstractDefinition,
ExpressionExecutor[] attributeExpressionExecutors,
ExecutionPlanContext executionPlanContext) {
if (attributeExpressionExecutors.length != 3) {
throw new ExecutionPlanValidationException(
"Invalid no of arguments passed to device:addNotification() function, required 3 but found " +
attributeExpressionExecutors.length);
}
if (attributeExpressionExecutors[0].getReturnType() != Attribute.Type.STRING) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the first argument (deviceIdentifier) of device:addNotification() " +
"function, required " + Attribute.Type.STRING + " as deviceIdentifier, but found " +
attributeExpressionExecutors[0].getReturnType().toString());
}
if (attributeExpressionExecutors[1].getReturnType() != Attribute.Type.STRING) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the second argument (deviceType) of device:addNotification() " +
"function, required " + Attribute.Type.STRING + " as deviceType, but found " +
attributeExpressionExecutors[1].getReturnType().toString());
}
if (attributeExpressionExecutors[2].getReturnType() != Attribute.Type.STRING) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the third argument (description) of device:addNotification() " +
"function, required " + Attribute.Type.STRING + " as description, but found " +
attributeExpressionExecutors[2].getReturnType().toString());
}
ArrayList<Attribute> attributes = new ArrayList<>();
attributes.add(new Attribute("notified", Attribute.Type.BOOL));
return attributes;
}
/**
* The process method of the StreamFunction, used when more than one function parameters are provided
*
* @param data the data values for the function parameters
* @return the data for additional output attributes introduced by the function
*/
@Override
protected Object[] process(Object[] data) {
if (data[0] == null || data[1] == null || data[2] == null) {
throw new ExecutionPlanRuntimeException("Invalid input given to device:addNotification() function. " +
"Neither of any three arguments cannot be null");
}
boolean isNotified = false;
String deviceId = (String) data[0];
String deviceType = (String) data[1];
String description = (String) data[2];
Notification notification = new Notification();
notification.setStatus(Notification.Status.NEW.name());
notification.setDeviceIdentifier(deviceId);
notification.setDeviceType(deviceType);
notification.setDescription(description);
NotificationManagementService notificationManagementService = DeviceUtils.getNotificationManagementService();
try {
isNotified = notificationManagementService.addNotification(new DeviceIdentifier(deviceId, deviceType), notification);
} catch (NotificationManagementException e) {
// We are not throwing this exception to siddhi runtime as it will break the complete siddhi execution
// flow for the event stream coming in.
log.error("Error occurred while adding notification '" + notification.toString() + "' for " +
deviceType + " device with id " + deviceId, e);
}
return new Object[]{isNotified};
}
/**
* The process method of the StreamFunction, used when zero or one function parameter is provided
*
* @param data null if the function parameter count is zero or runtime data value of the function parameter
* @return the data for additional output attribute introduced by the function
*/
@Override
protected Object[] process(Object data) {
return new Object[0];
}
/**
* This will be called only once and this can be used to acquire
* required resources for the processing element.
* This will be called after initializing the system and before
* starting to process the events.
*/
@Override
public void start() {
}
/**
* This will be called only once and this can be used to release
* the acquired resources for processing.
* This will be called before shutting down the system.
*/
@Override
public void stop() {
}
/**
* Used to collect the serializable state of the processing element, that need to be
* persisted for the reconstructing the element to the same state on a different point of time
*
* @return stateful objects of the processing element as an array
*/
@Override
public Object[] currentState() {
return new Object[0];
}
/**
* Used to restore serialized state of the processing element, for reconstructing
* the element to the same state as if was on a previous point of time.
*
* @param objects the stateful objects of the element as an array on
* the same order provided by currentState().
*/
@Override
public void restoreState(Object[] objects) {
//Since there's no need to maintain a state, nothing needs to be done here.
}
}

@ -0,0 +1,223 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device;
import feign.Feign;
import feign.Logger;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import feign.jaxrs.JAXRSContract;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.extension.siddhi.device.client.OAuthRequestInterceptor;
import org.wso2.extension.siddhi.device.client.configs.SiddhiExtensionConfigReader;
import org.wso2.extension.siddhi.device.client.dto.OperationRequest;
import org.wso2.extension.siddhi.device.client.services.OperationService;
import org.wso2.extension.siddhi.device.utils.ClientUtils;
import org.wso2.siddhi.core.config.ExecutionPlanContext;
import org.wso2.siddhi.core.exception.ExecutionPlanRuntimeException;
import org.wso2.siddhi.core.executor.ExpressionExecutor;
import org.wso2.siddhi.core.query.processor.stream.function.StreamFunctionProcessor;
import org.wso2.siddhi.query.api.definition.AbstractDefinition;
import org.wso2.siddhi.query.api.definition.Attribute;
import org.wso2.siddhi.query.api.exception.ExecutionPlanValidationException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class AddOperationFunctionProcessor extends StreamFunctionProcessor {
private static final Log log = LogFactory.getLog(AddOperationFunctionProcessor.class);
private static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
private static final String DEVICE_MGT_BASE_CONTEXT = "/api/device-mgt/v1.0";
private OperationService operationService;
public AddOperationFunctionProcessor() {
operationService = Feign.builder().client(new OkHttpClient(ClientUtils.getSSLClient()))
.logger(new Slf4jLogger())
.logLevel(Logger.Level.FULL).requestInterceptor(new OAuthRequestInterceptor())
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(OperationService.class, ClientUtils.replaceProperties(
SiddhiExtensionConfigReader.getInstance().getConfig().getGatewayEndpoint() +
DEVICE_MGT_BASE_CONTEXT));
}
/**
* The init method of the StreamProcessor, this method will be called before other methods
*
* @param abstractDefinition the incoming stream definition
* @param attributeExpressionExecutors the executors of each function parameters
* @param executionPlanContext the context of the execution plan
* @return the additional output attributes introduced by the function
*/
@Override
protected List<Attribute> init(AbstractDefinition abstractDefinition,
ExpressionExecutor[] attributeExpressionExecutors,
ExecutionPlanContext executionPlanContext) {
if (attributeExpressionExecutors.length != 6) {
throw new ExecutionPlanValidationException(
"Invalid no of arguments passed to device:addOperation() function, required 3 but found " +
attributeExpressionExecutors.length);
}
if (attributeExpressionExecutors[0].getReturnType() != Attribute.Type.STRING) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the first argument (deviceIdentifiers) of device:addOperation() " +
"function, required " + Attribute.Type.STRING + " as deviceIdentifiers, but found " +
attributeExpressionExecutors[0].getReturnType().toString());
}
if (attributeExpressionExecutors[1].getReturnType() != Attribute.Type.STRING) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the second argument (deviceType) of device:addOperation() " +
"function, required " + Attribute.Type.STRING + " as deviceType, but found " +
attributeExpressionExecutors[1].getReturnType().toString());
}
if (attributeExpressionExecutors[2].getReturnType() != Attribute.Type.STRING) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the third argument (code) of device:addOperation() " +
"function, required " + Attribute.Type.STRING + " as code, but found " +
attributeExpressionExecutors[2].getReturnType().toString());
}
if (attributeExpressionExecutors[3].getReturnType() != Attribute.Type.STRING) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the fourth argument (type) of device:addOperation() " +
"function, required " + Attribute.Type.STRING + " as type, but found " +
attributeExpressionExecutors[3].getReturnType().toString());
}
if (attributeExpressionExecutors[4].getReturnType() != Attribute.Type.BOOL) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the fifth argument (isEnabled) of device:addOperation() " +
"function, required " + Attribute.Type.BOOL + " as isEnabled, but found " +
attributeExpressionExecutors[4].getReturnType().toString());
}
if (attributeExpressionExecutors[5].getReturnType() != Attribute.Type.STRING) {
throw new ExecutionPlanValidationException(
"Invalid parameter type found for the fifth argument (payLoad) of device:addOperation() " +
"function, required " + Attribute.Type.STRING + " as payLoad, but found " +
attributeExpressionExecutors[5].getReturnType().toString());
}
ArrayList<Attribute> attributes = new ArrayList<>();
attributes.add(new Attribute("activity_id", Attribute.Type.STRING));
return attributes;
}
/**
* The process method of the StreamFunction, used when more than one function parameters are provided
*
* @param data the data values for the function parameters
* @return the data for additional output attributes introduced by the function
*/
@Override
protected Object[] process(Object[] data) {
if (data[0] == null || data[1] == null || data[2] == null || data[3] == null || data[4] == null || data[5] == null) {
throw new ExecutionPlanRuntimeException("Invalid input given to device:addOperation() function. " +
"Neither of any three arguments cannot be null");
}
JSONArray deviceIds = new JSONArray((String) data[0]);
String deviceType = (String) data[1];
List<String> deviceIdentifiers = new ArrayList<>();
for (int i = 0; i < deviceIds.length(); i++) {
deviceIdentifiers.add(deviceIds.getString(i));
}
Operation operation = new Operation();
operation.setType(Operation.Type.valueOf((String) data[3]));
operation.setStatus(Operation.Status.PENDING);
operation.setCode((String) data[2]);
operation.setEnabled((Boolean) data[4]);
String payloadString = (String) data[5];
operation.setPayLoad(payloadString.replaceAll("'", "\""));
String date = new SimpleDateFormat(DATE_FORMAT_NOW).format(new Date());
operation.setCreatedTimeStamp(date);
OperationRequest operationRequest = new OperationRequest();
operationRequest.setDeviceIdentifiers(deviceIdentifiers);
operationRequest.setOperation(operation);
try {
Activity activity = operationService.addOperation(deviceType, operationRequest);
return new Object[]{activity.getActivityId()};
} catch (Exception e) {
log.error("Error occurred while adding the operation " + operation.toString(), e);
return new Object[]{null};
}
}
/**
* The process method of the StreamFunction, used when zero or one function parameter is provided
*
* @param data null if the function parameter count is zero or runtime data value of the function parameter
* @return the data for additional output attribute introduced by the function
*/
@Override
protected Object[] process(Object data) {
return new Object[0];
}
/**
* This will be called only once and this can be used to acquire
* required resources for the processing element.
* This will be called after initializing the system and before
* starting to process the events.
*/
@Override
public void start() {
}
/**
* This will be called only once and this can be used to release
* the acquired resources for processing.
* This will be called before shutting down the system.
*/
@Override
public void stop() {
}
/**
* Used to collect the serializable state of the processing element, that need to be
* persisted for the reconstructing the element to the same state on a different point of time
*
* @return stateful objects of the processing element as an array
*/
@Override
public Object[] currentState() {
return new Object[0];
}
/**
* Used to restore serialized state of the processing element, for reconstructing
* the element to the same state as if was on a previous point of time.
*
* @param objects the stateful objects of the element as an array on
* the same order provided by currentState().
*/
@Override
public void restoreState(Object[] objects) {
//Since there's no need to maintain a state, nothing needs to be done here.
}
}

@ -0,0 +1,106 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client;
import feign.Feign;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.auth.BasicAuthRequestInterceptor;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import feign.jaxrs.JAXRSContract;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.extension.siddhi.device.client.configs.SiddhiExtensionConfigReader;
import org.wso2.extension.siddhi.device.client.dto.OAuthApplication;
import org.wso2.extension.siddhi.device.client.dto.RegistrationProfile;
import org.wso2.extension.siddhi.device.client.exception.APIMClientOAuthException;
import org.wso2.extension.siddhi.device.client.services.DCRService;
import org.wso2.extension.siddhi.device.utils.ClientUtils;
import org.wso2.extension.siddhi.device.utils.DeviceUtils;
/**
* This is a request interceptor to add oauth token header.
*/
public class OAuthRequestInterceptor implements RequestInterceptor {
private static final String APPLICATION_NAME = "siddhi_extension_client";
private static final String REQUIRED_SCOPES = "perm:devices:operations";
private static final String[] API_TAGS = {"device_management"};
private DCRService dcrService;
private static OAuthApplication oAuthApplication;
private static final Log log = LogFactory.getLog(OAuthRequestInterceptor.class);
/**
* Creates an interceptor that authenticates all requests.
*/
public OAuthRequestInterceptor() {
String username = SiddhiExtensionConfigReader.getInstance().getConfig().getUsername();
String password = SiddhiExtensionConfigReader.getInstance().getConfig().getPassword();
dcrService = Feign.builder().client(new OkHttpClient(ClientUtils.getSSLClient())).logger(new Slf4jLogger())
.logLevel(Logger.Level.FULL)
.requestInterceptor(new BasicAuthRequestInterceptor(username, password))
.contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder())
.target(DCRService.class, ClientUtils.replaceProperties(
SiddhiExtensionConfigReader.getInstance().getConfig().getDcrEndpoint()));
}
@Override
public void apply(RequestTemplate template) {
if (oAuthApplication == null) {
RegistrationProfile registrationProfile = new RegistrationProfile();
registrationProfile.setApiApplicationName(APPLICATION_NAME);
registrationProfile.setIsAllowedToAllDomains(true);
registrationProfile.setTags(API_TAGS);
oAuthApplication = dcrService.register(registrationProfile);
}
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
try {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration().getAdminUserName();
if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
username = username + "@" + tenantDomain;
}
JWTClient jwtClient = DeviceUtils.getJWTClientManagerService().getJWTClient();
AccessTokenInfo tenantBasedAccessTokenInfo = jwtClient.getAccessToken(oAuthApplication.getClientId(),
oAuthApplication.getClientSecret(), username, REQUIRED_SCOPES);
if (tenantBasedAccessTokenInfo.getAccessToken() != null) {
String headerValue = "Bearer " + tenantBasedAccessTokenInfo.getAccessToken();
template.header("Authorization", headerValue);
}
} catch (JWTClientException e) {
String msg = "Failed to retrieve oauth token using jwt";
log.error(msg, e);
throw new APIMClientOAuthException(msg, e);
} catch (UserStoreException e) {
String msg = "Unable to retrieve realm config for tenant " + tenantDomain;
log.error(msg, e);
throw new APIMClientOAuthException(msg, e);
}
}
}

@ -0,0 +1,70 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.configs;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This holds the configuration api manager integration.
*/
@XmlRootElement(name = "SiddhiExtensionConfiguration")
public class SiddhiExtensionConfig {
String dcrEndpoint;
String gatewayEndpoint;
String username;
String password;
@XmlElement(name = "DCREndpoint", required = true)
public String getDcrEndpoint() {
return dcrEndpoint;
}
public void setDcrEndpoint(String dcrEndpoint) {
this.dcrEndpoint = dcrEndpoint;
}
@XmlElement(name = "GatewayEndpoint", required = true)
public String getGatewayEndpoint() {
return gatewayEndpoint;
}
public void setGatewayEndpoint(String gatewayEndpoint) {
this.gatewayEndpoint = gatewayEndpoint;
}
@XmlElement(name = "Username", required = true)
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@XmlElement(name = "Password", required = true)
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

@ -0,0 +1,95 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.configs;
import org.w3c.dom.Document;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.extension.siddhi.device.client.exception.APIMClientException;
import org.wso2.extension.siddhi.device.client.exception.InvalidConfigurationStateException;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
/**
* This holds the configuration parser for api integration.xml
*/
public class SiddhiExtensionConfigReader {
private static SiddhiExtensionConfig config;
private static SiddhiExtensionConfigReader configReader = new SiddhiExtensionConfigReader();
private static boolean isInitialized = false;
private static final String SIDDHI_INTEGRATION_CONFIG_PATH =
CarbonUtils.getCarbonConfigDirPath() + File.separator + "siddhi-integration.xml";
private SiddhiExtensionConfigReader() {
}
private static String apimIntegrationXmlFilePath = "";
//TOD file may be a part of another file
public static SiddhiExtensionConfigReader getInstance() {
if (!isInitialized) {
try {
init();
} catch (APIMClientException e) {
throw new InvalidConfigurationStateException("Webapp Authenticator Configuration is not " +
"initialized properly");
}
}
return configReader;
}
public static void init() throws APIMClientException {
try {
File siddhiConfigFile = new File(SIDDHI_INTEGRATION_CONFIG_PATH);
Document doc = convertToDocument(siddhiConfigFile);
JAXBContext ctx = JAXBContext.newInstance(SiddhiExtensionConfig.class);
Unmarshaller unmarshaller = ctx.createUnmarshaller();
config = (SiddhiExtensionConfig) unmarshaller.unmarshal(doc);
isInitialized = true;
} catch (JAXBException e) {
throw new APIMClientException("Error occurred while un-marshalling SiddhiExtensionConfig", e);
}
}
private static Document convertToDocument(File file) throws APIMClientException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try {
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder docBuilder = factory.newDocumentBuilder();
return docBuilder.parse(file);
} catch (Exception e) {
throw new APIMClientException("Error occurred while parsing file 'apim-integration.xml' to a org.w3c.dom.Document", e);
}
}
public SiddhiExtensionConfig getConfig() {
return config;
}
}

@ -0,0 +1,50 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.dto;
public class OAuthApplication {
private String client_id;
private String client_secret;
public String getClientId() {
return client_id;
}
public void setClientId(String clientId) {
this.client_id = clientId;
}
public String getClientSecret() {
return client_secret;
}
public void setClientSecret(String clientSecret) {
this.client_secret = clientSecret;
}
@Override
public String toString() {
return "OAuthApplication {\n" +
" clientId: " + client_id + "\n" +
" clientSecret: " + client_secret + "\n" +
"}\n";
}
}

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.dto;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import java.util.List;
public class OperationRequest {
private List<String> deviceIdentifiers;
private Operation operation;
public List<String> getDeviceIdentifiers() {
return deviceIdentifiers;
}
public void setDeviceIdentifiers(List<String> deviceIdentifiers) {
this.deviceIdentifiers = deviceIdentifiers;
}
public Operation getOperation() {
return operation;
}
public void setOperation(Operation operation) {
this.operation = operation;
}
}

@ -0,0 +1,63 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.dto;
/**
* DTO class to be used when registering an ApiM application.
*/
public class RegistrationProfile {
private String applicationName;
private String tags[];
private boolean isAllowedToAllDomains;
private String validityPeriod;
public String getApplicationName() {
return applicationName;
}
public void setApiApplicationName(String apiApplicationName) {
this.applicationName = apiApplicationName;
}
public String[] getTags() {
return tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
public boolean isAllowedToAllDomains() {
return isAllowedToAllDomains;
}
public void setIsAllowedToAllDomains(boolean isAllowedToAllDomains) {
this.isAllowedToAllDomains = isAllowedToAllDomains;
}
public String getValidityPeriod() {
return validityPeriod;
}
public void setValidityPeriod(String validityPeriod) {
this.validityPeriod = validityPeriod;
}
}

@ -0,0 +1,58 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.exception;
/**
* This holds api client exception.
*/
public class APIMClientException extends Exception {
private static final long serialVersionUID = -3976392476319079281L;
private String responseReason;
private int responseStatus;
private String methodKey;
APIMClientException(String methodKey, String reason, int status) {
super("Exception occurred while invoking " + methodKey + " status = " + status + " reason = " + reason);
this.methodKey = methodKey;
this.responseReason = reason;
this.responseStatus = status;
}
APIMClientException(String message) {
super(message);
}
public APIMClientException(String message, Exception e) {
super(message, e);
}
public String getResponseReason() {
return responseReason;
}
public int getResponseStatus() {
return responseStatus;
}
public String getMethodKey() {
return methodKey;
}
}

@ -0,0 +1,58 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.exception;
/**
* This holds api client exception.
*/
public class APIMClientOAuthException extends RuntimeException {
private static final long serialVersionUID = -3976392476319079281L;
private String responseReason;
private int responseStatus;
private String methodKey;
APIMClientOAuthException(String methodKey, String reason, int status) {
super("Exception occurred while invoking " + methodKey + " status = " + status + " reason = " + reason);
this.methodKey = methodKey;
this.responseReason = reason;
this.responseStatus = status;
}
public APIMClientOAuthException(String message) {
super(message);
}
public APIMClientOAuthException(String message, Exception e) {
super(message, e);
}
public String getResponseReason() {
return responseReason;
}
public int getResponseStatus() {
return responseStatus;
}
public String getMethodKey() {
return methodKey;
}
}

@ -0,0 +1,78 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.exception;
/**
* This error is thrown when there is an issue with the client.
*/
public class InvalidConfigurationStateException extends RuntimeException {
private static final long serialVersionUID = -3151279311329070397L;
private String errorMessage;
private int errorCode;
public InvalidConfigurationStateException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public InvalidConfigurationStateException(int errorCode, String message, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public InvalidConfigurationStateException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public InvalidConfigurationStateException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public InvalidConfigurationStateException(String msg) {
super(msg);
setErrorMessage(msg);
}
public InvalidConfigurationStateException() {
super();
}
public InvalidConfigurationStateException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,42 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.services;
import org.wso2.extension.siddhi.device.client.dto.OAuthApplication;
import org.wso2.extension.siddhi.device.client.dto.RegistrationProfile;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* DCR Rest resource.
*/
@Path("/")
public interface DCRService {
// DCR APIs
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
OAuthApplication register(RegistrationProfile registrationProfile);
}

@ -0,0 +1,43 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.client.services;
import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import org.wso2.extension.siddhi.device.client.dto.OperationRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* Add Operation REST resource.
*/
@Path("/devices")
public interface OperationService {
@POST
@Path("/{type}/operations")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
Activity addOperation(@PathParam("type") String type, OperationRequest operationRequest);
}

@ -0,0 +1,223 @@
/*
* Copyright (c) 2018, 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.extension.siddhi.device.utils;
import okhttp3.OkHttpClient;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.ServerConfiguration;
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ClientUtils {
private static final Log log = LogFactory.getLog(ClientUtils.class);
private static final String KEY_STORE_TYPE = "JKS";
/**
* Default truststore type of the client
*/
private static final String TRUST_STORE_TYPE = "JKS";
/**
* Default keymanager type of the client
*/
private static final String KEY_MANAGER_TYPE = "SunX509"; //Default Key Manager Type
/**
* Default trustmanager type of the client
*/
private static final String TRUST_MANAGER_TYPE = "SunX509"; //Default Trust Manager Type
private static final String SSLV3 = "SSLv3";
private static final String DEFAULT_HOST = "localhost";
private static final String DEFAULT_HOST_IP = "127.0.0.1";
//This method is only used if the mb features are within DAS.
public static String replaceProperties(String text) {
String regex = "\\$\\{(.*?)\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matchPattern = pattern.matcher(text);
while (matchPattern.find()) {
String sysPropertyName = matchPattern.group(1);
String sysPropertyValue = System.getProperty(sysPropertyName);
if (sysPropertyValue != null && !sysPropertyName.isEmpty()) {
text = text.replaceAll("\\$\\{(" + sysPropertyName + ")\\}", sysPropertyValue);
}
}
return text;
}
public static OkHttpClient getSSLClient() {
boolean isIgnoreHostnameVerification = Boolean.parseBoolean(System.getProperty("org.wso2"
+ ".ignoreHostnameVerification"));
OkHttpClient okHttpClient;
final String proxyHost = System.getProperty("http.proxyHost");
final String proxyPort = System.getProperty("http.proxyPort");
final String nonProxyHostsValue = System.getProperty("http.nonProxyHosts");
final ProxySelector proxySelector = new ProxySelector() {
@Override
public List<Proxy> select(URI uri) {
List<Proxy> proxyList = new ArrayList<>();
String host = uri.getHost();
if (!StringUtils.isEmpty(host)) {
if (host.startsWith(DEFAULT_HOST_IP) || host.startsWith(DEFAULT_HOST) || StringUtils
.isEmpty(nonProxyHostsValue) || StringUtils.contains(nonProxyHostsValue, host) ||
StringUtils.isEmpty(proxyHost) || StringUtils.isEmpty(proxyPort)) {
proxyList.add(Proxy.NO_PROXY);
} else {
proxyList.add(new Proxy(Proxy.Type.HTTP,
new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort))));
}
} else {
log.error("Host is null. Host could not be empty or null");
}
return proxyList;
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
throw new UnsupportedOperationException("Not supported yet.");
}
};
X509TrustManager trustAllCerts = new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
};
if(isIgnoreHostnameVerification) {
okHttpClient = new OkHttpClient.Builder()
.sslSocketFactory(getSimpleTrustedSSLSocketFactory(), trustAllCerts)
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}).proxySelector(proxySelector).build();
return okHttpClient;
}else {
SSLSocketFactory trustedSSLSocketFactory = getTrustedSSLSocketFactory();
okHttpClient = new OkHttpClient.Builder().sslSocketFactory(trustedSSLSocketFactory)
.proxySelector(proxySelector).build();
return okHttpClient;
}
}
private static SSLSocketFactory getSimpleTrustedSSLSocketFactory() {
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
return null;
}
}
private static SSLSocketFactory getTrustedSSLSocketFactory() {
try {
String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password");
String keyStoreLocation = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Location");
String trustStorePassword = ServerConfiguration.getInstance().getFirstProperty(
"Security.TrustStore.Password");
String trustStoreLocation = ServerConfiguration.getInstance().getFirstProperty(
"Security.TrustStore.Location");
KeyStore keyStore = loadKeyStore(keyStoreLocation,keyStorePassword,KEY_STORE_TYPE);
KeyStore trustStore = loadTrustStore(trustStoreLocation,trustStorePassword);
return initSSLConnection(keyStore,keyStorePassword,trustStore);
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException
|CertificateException | IOException | UnrecoverableKeyException e) {
log.error("Error while creating the SSL socket factory due to "+e.getMessage(),e);
return null;
}
}
private static SSLSocketFactory initSSLConnection(KeyStore keyStore,String keyStorePassword,KeyStore trustStore) throws NoSuchAlgorithmException, UnrecoverableKeyException,
KeyStoreException, KeyManagementException {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE);
keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE);
trustManagerFactory.init(trustStore);
// Create and initialize SSLContext for HTTPS communication
SSLContext sslContext = SSLContext.getInstance(SSLV3);
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
SSLContext.setDefault(sslContext);
return sslContext.getSocketFactory();
}
private static KeyStore loadKeyStore(String keyStorePath, String ksPassword,String type)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
InputStream fileInputStream = null;
try {
char[] keypassChar = ksPassword.toCharArray();
KeyStore keyStore = KeyStore.getInstance(type);
fileInputStream = new FileInputStream(keyStorePath);
keyStore.load(fileInputStream, keypassChar);
return keyStore;
} finally {
if (fileInputStream != null) {
fileInputStream.close();
}
}
}
private static KeyStore loadTrustStore(String trustStorePath, String tsPassword)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
return loadKeyStore(trustStorePath,tsPassword,TRUST_STORE_TYPE);
}
}

@ -20,8 +20,10 @@ package org.wso2.extension.siddhi.device.utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
/**
* This class holds utility methods to retrieve data.
@ -31,6 +33,8 @@ public class DeviceUtils {
private static Log log = LogFactory.getLog(DeviceUtils.class);
private static DeviceManagementProviderService deviceManagementProviderService;
private static GroupManagementProviderService groupManagementProviderService;
private static NotificationManagementService notificationManagementService;
private static JWTClientManagerService jwtClientManagerService;
private DeviceUtils(){
}
@ -64,4 +68,34 @@ public class DeviceUtils {
}
return groupManagementProviderService;
}
public static NotificationManagementService getNotificationManagementService() {
if (notificationManagementService != null) {
return notificationManagementService;
}
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
notificationManagementService =
(NotificationManagementService) ctx.getOSGiService(NotificationManagementService.class, null);
if (notificationManagementService == null) {
String msg = "Notification Management service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return notificationManagementService;
}
public static JWTClientManagerService getJWTClientManagerService() {
if (jwtClientManagerService != null) {
return jwtClientManagerService;
}
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
jwtClientManagerService =
(JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
if (jwtClientManagerService == null) {
String msg = "JWTClient Manager service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return jwtClientManagerService;
}
}

@ -22,3 +22,5 @@ hasDevicesOfUser=org.wso2.extension.siddhi.device.HasDevicesOfUserFunctionExecut
getDevicesOfStatus=org.wso2.extension.siddhi.device.GetDevicesOfStatusFunctionExecutor
hasDevicesOfStatus=org.wso2.extension.siddhi.device.HasDevicesOfStatusFunctionExecutor
isEnrolled=org.wso2.extension.siddhi.device.IsEnrolledFunctionExecutor
addNotification=org.wso2.extension.siddhi.device.AddNotificationFunctionProcessor
addOperation=org.wso2.extension.siddhi.device.AddOperationFunctionProcessor

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>siddhi-extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>siddhi-extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<artifactId>extensions</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,7 +21,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018, 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.mdm.services.android.bean;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
@ApiModel(value = "NotifierFrequency",
description = "This class represents notification frequency configuration.")
public class NotifierFrequency extends AndroidOperation implements Serializable {
@ApiModelProperty(name = "value", value = "Notification polling frequency", required = true)
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}

@ -20,13 +20,20 @@ package org.wso2.carbon.mdm.services.android.services.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
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.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.mdm.services.android.bean.AndroidPlatformConfiguration;
import org.wso2.carbon.mdm.services.android.bean.ErrorResponse;
import org.wso2.carbon.mdm.services.android.bean.NotifierFrequency;
import org.wso2.carbon.mdm.services.android.exception.UnexpectedServerErrorException;
import org.wso2.carbon.mdm.services.android.services.DeviceTypeConfigurationService;
import org.wso2.carbon.mdm.services.android.util.AndroidAPIUtils;
@ -114,6 +121,29 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
AndroidAPIUtils.getDeviceManagementService().addLicense(DeviceManagementConstants.
MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, license);
licenseEntry = entry;
} else if (AndroidConstants.TenantConfigProperties.NOTIFIER_FREQUENCY.equals(entry.getName())) {
List<Device> deviceList = AndroidAPIUtils.
getDeviceManagementService().
getAllDevices(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
List<DeviceIdentifier> deviceIdList = new ArrayList<>();
for (Device device : deviceList) {
deviceIdList.add(new DeviceIdentifier(device.getDeviceIdentifier(),device.getType()));
}
if (entry.getValue() != null) {
NotifierFrequency notifierFrequency = new NotifierFrequency();
notifierFrequency.setValue(Integer.parseInt(entry.getValue().toString()));
ProfileOperation operation = new ProfileOperation();
operation.setCode(AndroidConstants.OperationCodes.NOTIFIER_FREQUENCY);
operation.setPayLoad(notifierFrequency.toJSON());
operation.setType(Operation.Type.CONFIG);
operation.setEnabled(true);
AndroidAPIUtils.getDeviceManagementService().addOperation(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID,
operation, deviceIdList);
} else {
return Response.status(Response.Status.BAD_REQUEST)
.entity("No value specified for notifierFrequency.").build();
}
}
}
@ -122,14 +152,29 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
}
configuration.setConfiguration(configs);
AndroidAPIUtils.getDeviceManagementService().saveConfiguration(configuration);
//AndroidAPIUtils.getGCMService().resetTenantConfigCache();
} catch (DeviceManagementException e) {
msg = "Error occurred while modifying configuration settings of Android platform";
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
} catch (NumberFormatException e) {
msg = "Error occurred while reading notification frequency.";
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
} catch (OperationManagementException e) {
msg = "Error occurred while modifying configuration settings of Android platform.";
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
} catch (InvalidDeviceException e) {
msg = "Error occurred with the device.";
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
}
return Response.status(Response.Status.OK).entity("Android platform configuration has been updated successfully.").build();
return Response.status(Response.Status.OK)
.entity("Android platform configuration has been updated successfully.").build();
}

@ -69,13 +69,14 @@ public class EventReceiverServiceImpl implements EventReceiverService {
if (log.isDebugEnabled()) {
log.debug("Invoking Android device event logging.");
}
Device device;
try {
if (!DeviceManagerUtil.isPublishLocationResponseEnabled()) {
return Response.status(Response.Status.ACCEPTED).entity("Event is publishing has not enabled.").build();
}
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(eventBeanWrapper.getDeviceIdentifier(),
AndroidConstants.DEVICE_TYPE_ANDROID);
Device device = AndroidAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier);
device = AndroidAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier);
if (device != null && EnrolmentInfo.Status.ACTIVE != device.getEnrolmentInfo().getStatus()){
return Response.status(Response.Status.ACCEPTED).entity("Device is not in Active state.").build();
} else if (device == null){
@ -92,7 +93,8 @@ public class EventReceiverServiceImpl implements EventReceiverService {
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
Message message = new Message();
Object[] metaData = {eventBeanWrapper.getDeviceIdentifier(), AndroidConstants.DEVICE_TYPE_ANDROID};
Object[] metaData = {eventBeanWrapper.getDeviceIdentifier(), device.getEnrolmentInfo().getOwner(),
AndroidConstants.DEVICE_TYPE_ANDROID};
String eventPayload = eventBeanWrapper.getPayload();
JsonObject jsonObject = gson.fromJson(eventPayload, JsonObject.class);
Object[] payload = {

@ -104,6 +104,7 @@ public final class AndroidConstants {
public static final String LOGCAT = "LOGCAT";
public static final String APP_RESTRICTION = "APP-RESTRICTION";
public static final String WORK_PROFILE = "WORK_PROFILE";
public static final String NOTIFIER_FREQUENCY = "NOTIFIER_FREQUENCY";
}
public final class StatusCodes {
@ -122,6 +123,7 @@ public final class AndroidConstants {
public static final String LICENSE_KEY = "androidEula";
public static final String LANGUAGE_US = "en_US";
public static final String CONTENT_TYPE_TEXT = "text";
public static final String NOTIFIER_FREQUENCY = "notifierFrequency";
}
public final class ApplicationProperties {

@ -21,7 +21,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -23,13 +23,13 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.mgt.mobile.android.ui</artifactId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<name>WSO2 Carbon - Mobile Android UI</name>
<packaging>pom</packaging>

@ -23,7 +23,7 @@
<parent>
<artifactId>android-plugin</artifactId>
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
<version>4.1.7-SNAPSHOT</version>
<version>4.1.12-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -0,0 +1,41 @@
/*
* Copyright (c) 2018, 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.mdm.services.android.bean;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
@ApiModel(value = "NotifierFrequency",
description = "This class represents notification frequency configuration.")
public class NotifierFrequency extends AndroidOperation implements Serializable {
@ApiModelProperty(name = "value", value = "Notification polling frequency", required = true)
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}

@ -21,13 +21,20 @@ package org.wso2.carbon.mdm.services.android.services.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
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.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.mdm.services.android.bean.AndroidPlatformConfiguration;
import org.wso2.carbon.mdm.services.android.bean.ErrorResponse;
import org.wso2.carbon.mdm.services.android.bean.NotifierFrequency;
import org.wso2.carbon.mdm.services.android.exception.UnexpectedServerErrorException;
import org.wso2.carbon.mdm.services.android.services.DeviceTypeConfigurationService;
import org.wso2.carbon.mdm.services.android.util.AndroidAPIUtils;
@ -115,6 +122,29 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
AndroidAPIUtils.getDeviceManagementService().addLicense(DeviceManagementConstants.
MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID, license);
licenseEntry = entry;
} else if (AndroidConstants.TenantConfigProperties.NOTIFIER_FREQUENCY.equals(entry.getName())) {
List<Device> deviceList = AndroidAPIUtils.
getDeviceManagementService().
getAllDevices(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID);
List<DeviceIdentifier> deviceIdList = new ArrayList<>();
for (Device device : deviceList) {
deviceIdList.add(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
}
if (entry.getValue() != null) {
NotifierFrequency notifierFrequency = new NotifierFrequency();
notifierFrequency.setValue(Integer.parseInt(entry.getValue().toString()));
ProfileOperation operation = new ProfileOperation();
operation.setCode(AndroidConstants.OperationCodes.NOTIFIER_FREQUENCY);
operation.setPayLoad(notifierFrequency.toJSON());
operation.setType(Operation.Type.CONFIG);
operation.setEnabled(true);
AndroidAPIUtils.getDeviceManagementService().addOperation(
DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID,
operation, deviceIdList);
} else {
return Response.status(Response.Status.BAD_REQUEST)
.entity("No value specified for notifierFrequency.").build();
}
}
}
@ -129,8 +159,24 @@ public class DeviceTypeConfigurationServiceImpl implements DeviceTypeConfigurati
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
} catch (NumberFormatException e) {
msg = "Error occurred while reading notification frequency.";
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
} catch (OperationManagementException e) {
msg = "Error occurred while modifying configuration settings of Android platform.";
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
} catch (InvalidDeviceException e) {
msg = "Error occurred with the device.";
log.error(msg, e);
throw new UnexpectedServerErrorException(
new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build());
}
return Response.status(Response.Status.OK).entity("Android platform configuration has been updated successfully.").build();
return Response.status(Response.Status.OK)
.entity("Android platform configuration has been updated successfully.").build();
}

@ -70,13 +70,14 @@ public class EventReceiverServiceImpl implements EventReceiverService {
if (log.isDebugEnabled()) {
log.debug("Invoking Android device event logging.");
}
Device device;
try {
if (!DeviceManagerUtil.isPublishLocationResponseEnabled()) {
return Response.status(Response.Status.ACCEPTED).entity("Event is publishing has not enabled.").build();
}
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(eventBeanWrapper.getDeviceIdentifier(),
AndroidConstants.DEVICE_TYPE_ANDROID);
Device device = AndroidAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier);
device = AndroidAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier);
if (device != null && EnrolmentInfo.Status.ACTIVE != device.getEnrolmentInfo().getStatus()){
return Response.status(Response.Status.ACCEPTED).entity("Device is not in Active state.").build();
} else if (device == null){
@ -93,7 +94,8 @@ public class EventReceiverServiceImpl implements EventReceiverService {
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
Message message = new Message();
Object[] metaData = {eventBeanWrapper.getDeviceIdentifier(), AndroidConstants.DEVICE_TYPE_ANDROID};
Object[] metaData = {eventBeanWrapper.getDeviceIdentifier(), device.getEnrolmentInfo().getOwner(),
AndroidConstants.DEVICE_TYPE_ANDROID};
String eventPayload = eventBeanWrapper.getPayload();
JsonObject jsonObject = gson.fromJson(eventPayload, JsonObject.class);
Object[] payload = {

@ -104,6 +104,7 @@ public final class AndroidConstants {
public static final String LOGCAT = "LOGCAT";
public static final String APP_RESTRICTION = "APP-RESTRICTION";
public static final String WORK_PROFILE = "WORK_PROFILE";
public static final String NOTIFIER_FREQUENCY = "NOTIFIER_FREQUENCY";
}
public final class StatusCodes {
@ -122,6 +123,7 @@ public final class AndroidConstants {
public static final String LICENSE_KEY = "androidEula";
public static final String LANGUAGE_US = "en_US";
public static final String CONTENT_TYPE_TEXT = "text";
public static final String NOTIFIER_FREQUENCY = "notifierFrequency";
}
public final class ApplicationProperties {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save