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

revert-70aa11f8
ayyoob 8 years ago
commit 3b7d4d8966

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Annotations</name>
<description>WSO2 Carbon - API Management Custom Annotation Module</description>

@ -21,12 +21,12 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - API Application Management API</name>

@ -22,12 +22,12 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Application Management</name>

@ -21,13 +21,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.handlers</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Security Handler Component</name>
<description>WSO2 Carbon - API Management Security Handler Module</description>

@ -44,6 +44,8 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Contains util methods for synapse gateway authentication handler
@ -62,21 +64,47 @@ public class Utils {
public static IOTServerConfiguration initConfig() {
try {
String IOTServerAPIConfigurationPath =
CarbonUtils.getCarbonConfigDirPath() + File.separator + IOT_APIS_CONFIG_FILE;
String IOTServerAPIConfigurationPath = CarbonUtils.getCarbonConfigDirPath() + File.separator
+ IOT_APIS_CONFIG_FILE;
File file = new File(IOTServerAPIConfigurationPath);
Document doc = Utils.convertToDocument(file);
JAXBContext fileContext = JAXBContext.newInstance(IOTServerConfiguration.class);
Unmarshaller unmarshaller = fileContext.createUnmarshaller();
return (IOTServerConfiguration) unmarshaller.unmarshal(doc);
IOTServerConfiguration iotServerConfiguration = (IOTServerConfiguration) unmarshaller.unmarshal(
doc);
iotServerConfiguration.setHostname(replaceProperties(iotServerConfiguration.getHostname()));
iotServerConfiguration.setVerificationEndpoint(
replaceProperties(iotServerConfiguration.getVerificationEndpoint()));
iotServerConfiguration.setDynamicClientRegistrationEndpoint(
replaceProperties(iotServerConfiguration.getDynamicClientRegistrationEndpoint()));
iotServerConfiguration.setOauthTokenEndpoint(
replaceProperties(iotServerConfiguration.getOauthTokenEndpoint()));
return iotServerConfiguration;
} catch (JAXBException | APIMCertificateMGTException e) {
log.error("Error occurred while initializing Data Source config", e);
return null;
}
}
/**
* This method gets the values from system variables and sets to xml.
*/
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;
}
/**
* This class build the iot-api-config.xml file.
* @param file

@ -13,13 +13,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.client</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Integration Client</name>
<description>WSO2 Carbon - API Management Integration Client</description>

@ -13,13 +13,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.generated.client</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Integration Generated Client</name>
<description>WSO2 Carbon - API Management Integration Client</description>

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.webapp.publisher</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Webapp Publisher</name>
<description>WSO2 Carbon - API Management Webapp Publisher</description>

@ -22,13 +22,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apimgt-extensions</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - API Management Extensions Component</name>
<url>http://wso2.org</url>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -21,13 +21,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Certificate Management Core</name>
<description>WSO2 Carbon - Certificate Management Core</description>

@ -22,14 +22,14 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - Certificate Management Component</name>
<url>http://wso2.org</url>

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

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

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

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

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

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

@ -22,7 +22,7 @@
<parent>
<artifactId>carbon-devicemgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -3,7 +3,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -66,10 +66,6 @@
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.databridge.agent</artifactId>

@ -41,7 +41,7 @@ public class EventsPublisherServiceImpl implements EventsPublisherService {
* @param metaDataArray - meta data that needs to pushed
* @param correlationDataArray - correlation data that needs to be pushed
* @param payloadDataArray - payload data that needs to be pushed
* @return
* @return if success returns true
* @throws DataPublisherConfigurationException
*/
@Override
@ -74,7 +74,4 @@ public class EventsPublisherServiceImpl implements EventsPublisherService {
PrivilegedCarbonContext.endTenantFlow();
}
}
}

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -296,6 +296,16 @@
<artifactId>org.wso2.carbon.application.mgt.stub</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.datasource.commons</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>

@ -0,0 +1,472 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.jaxrs.service.api;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import io.swagger.annotations.Info;
import io.swagger.annotations.ResponseHeader;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.geo.service.Alert;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.Valid;
import javax.validation.constraints.Size;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "geo_services"),
@ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/geo-services"),
})
}
),
tags = {
@Tag(name = "device_management", description = "")
}
)
@Scopes(
scopes = {
@Scope(
name = "View Analytics",
description = "",
key = "perm:geo-service:analytics",
permissions = {"/device-mgt/devices/owning-device/analytics"}
)
}
)
@Path("/geo-services")
@Api(value = "Geo Service",
description = "This carries all the resources related to the geo service functionalities.")
public interface GeoService {
/**
* Retrieve Analytics for the device type
*/
@GET
@Path("stats/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve Analytics for the device type",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response getGeoDeviceStats(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "device-type",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("deviceType")
@Size(max = 45)
String deviceType,
@ApiParam(
name = "from",
value = "Get stats from what time",
required = true)
@QueryParam("from") long from,
@ApiParam(
name = "to",
value = "Get stats up to what time",
required = true)
@QueryParam("to") long to);
/**
* Create Geo alerts
*/
@POST
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Create Geo alerts for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response createGeoAlerts(
@ApiParam(
name = "alert",
value = "The alert object",
required = true)
@Valid Alert alert,
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "device-type",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("deviceType")
@Size(max = 45)
String deviceType,
@ApiParam(
name = "alertType",
value = "The alert type, such as Within, Speed, Stationary",
required = true)
@PathParam("alertType") String alertType);
/**
* Update Geo alerts
*/
@PUT
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Update Geo alerts for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response updateGeoAlerts(
@ApiParam(
name = "alert",
value = "The alert object",
required = true)
@Valid Alert alert,
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "device-type",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("deviceType")
@Size(max = 45)
String deviceType,
@ApiParam(
name = "alertType",
value = "The alert type, such as Within, Speed, Stationary",
required = true)
@PathParam("alertType") String alertType);
/**
* Retrieve Geo alerts
*/
@GET
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve Geo alerts for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests.")
}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response getGeoAlerts(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "device-type",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("deviceType")
@Size(max = 45)
String deviceType,
@ApiParam(
name = "alertType",
value = "The alert type, such as Within, Speed, Stationary",
required = true)
@PathParam("alertType") String alertType);
/**
* Retrieve Geo alerts history
*/
@GET
@Path("alerts/history/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "GET",
value = "Retrieve Geo alerts history for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests.")
}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response getGeoAlertsHistory(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "device-type",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("deviceType")
@Size(max = 45)
String deviceType,
@ApiParam(
name = "from",
value = "Get stats from what time",
required = true)
@QueryParam("from") long from,
@ApiParam(
name = "to",
value = "Get stats up to what time",
required = true)
@QueryParam("to") long to);
@DELETE
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@ApiOperation(
consumes = "application/json",
produces = "application/json",
httpMethod = "DELETE",
value = "Create Geo alerts for the device",
notes = "",
response = Response.class,
tags = "Geo Service Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK.",
response = Response.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid Device Identifiers found.",
response = Response.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized request."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error on retrieving stats",
response = Response.class)
})
Response removeGeoAlerts(
@ApiParam(
name = "deviceId",
value = "The registered device Id.",
required = true)
@PathParam("deviceId") String deviceId,
@ApiParam(
name = "deviceType",
value = "The device type, such as ios, android or windows.",
required = true)
@PathParam("deviceType") String deviceType,
@ApiParam(
name = "alertType",
value = "The alert type, such as Within, Speed, Stationary",
required = true)
@PathParam("alertType") String alertType,
@ApiParam(
name = "queryName",
value = "The query name.",
required = true)
@QueryParam("queryName") String queryName);
}

@ -0,0 +1,368 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.analytics.api.AnalyticsDataAPIUtil;
import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse;
import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry;
import org.wso2.carbon.analytics.dataservice.commons.SortByField;
import org.wso2.carbon.analytics.dataservice.commons.SortType;
import org.wso2.carbon.analytics.datasource.commons.Record;
import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException;
import org.wso2.carbon.device.mgt.common.geo.service.Alert;
import org.wso2.carbon.device.mgt.common.geo.service.Event;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFence;
import org.wso2.carbon.device.mgt.common.geo.service.GeoServiceException;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants;
import org.wso2.carbon.device.mgt.jaxrs.service.api.GeoService;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtUtil;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The api for
*/
public class GeoServiceImpl implements GeoService {
private static Log log = LogFactory.getLog(GeoServiceImpl.class);
@Path("stats/{deviceType}/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoDeviceStats(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@QueryParam("from") long from, @QueryParam("to") long to) {
String tableName = "IOT_PER_DEVICE_STREAM_GEO_FUSEDSPATIALEVENT";
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = "id:" + deviceId + " AND type:" + deviceType;
if (from != 0 || to != 0) {
query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]";
}
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("timeStamp", SortType.ASC);
sortByFields.add(sortByField);
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername());
try {
String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser);
int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain);
AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI();
List<SearchResultEntry> searchResults = analyticsDataAPI.search(tenantId, tableName, query,
0,
100,
sortByFields);
List<Event> events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList<String>(),
searchResults);
return Response.ok().entity(events).build();
} catch (AnalyticsException | UserStoreException e) {
log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e);
throw DeviceMgtUtil.buildBadRequestException(
Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT);
}
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
}
}
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@POST
@Consumes("application/json")
@Produces("application/json")
public Response createGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@PathParam("alertType") String alertType) {
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId);
identifier.setType(deviceType);
org.wso2.carbon.device.mgt.common.geo.service.GeoService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.createGeoAlert(alert, identifier, alertType);
return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoServiceException e) {
String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@PUT
@Consumes("application/json")
@Produces("application/json")
public Response updateGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@PathParam("alertType") String alertType) {
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId);
identifier.setType(deviceType);
org.wso2.carbon.device.mgt.common.geo.service.GeoService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.updateGeoAlert(alert, identifier, alertType);
return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoServiceException e) {
String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@DELETE
@Consumes("application/json")
@Produces("application/json")
public Response removeGeoAlerts(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@PathParam("alertType") String alertType,
@QueryParam("queryName") String queryName) {
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId);
identifier.setType(deviceType);
org.wso2.carbon.device.mgt.common.geo.service.GeoService geoService = DeviceMgtAPIUtils.getGeoService();
geoService.removeGeoAlert(alertType, identifier, queryName);
return Response.ok().build();
} catch (DeviceAccessAuthorizationException | GeoServiceException e) {
String error = "Error occurred while removing the geo alert for " + deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Path("alerts/{alertType}/{deviceType}/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoAlerts(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@PathParam("alertType") String alertType) {
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername()
);
DeviceIdentifier identifier = new DeviceIdentifier();
identifier.setId(deviceId);
identifier.setType(deviceType);
org.wso2.carbon.device.mgt.common.geo.service.GeoService geoService = DeviceMgtAPIUtils.getGeoService();
if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) {
List<GeoFence> alerts = geoService.getWithinAlerts(identifier);
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) {
List<GeoFence> alerts = geoService.getExitAlerts(identifier);
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) {
String result = geoService.getSpeedAlerts(identifier);
return Response.ok().entity(result).build();
} else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) {
String result = geoService.getProximityAlerts(identifier);
return Response.ok().entity(result).build();
} else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) {
List<GeoFence> alerts = geoService.getStationaryAlerts(identifier);
return Response.ok().entity(alerts).build();
} else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) {
List<GeoFence> alerts = geoService.getTrafficAlerts(identifier);
return Response.ok().entity(alerts).build();
}
return null;
} catch (DeviceAccessAuthorizationException | GeoServiceException e) {
String error = "Error occurred while getting the geo alerts for " + deviceType + " with id: " + deviceId;
log.error(error, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build();
}
}
@Path("alerts/history/{deviceType}/{deviceId}")
@GET
@Consumes("application/json")
@Produces("application/json")
public Response getGeoAlertsHistory(@PathParam("deviceId") String deviceId,
@PathParam("deviceType") String deviceType,
@QueryParam("from") long from, @QueryParam("to") long to) {
String tableName = "IOT_PER_DEVICE_STREAM_GEO_ALERTNOTIFICATIONS";
String fromDate = String.valueOf(from);
String toDate = String.valueOf(to);
String query = "id:" + deviceId + " AND type:" + deviceType;
if (from != 0 || to != 0) {
query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]";
}
try {
if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized(
new DeviceIdentifier(deviceId, deviceType),
DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) {
return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build();
}
List<SortByField> sortByFields = new ArrayList<>();
SortByField sortByField = new SortByField("timeStamp", SortType.ASC);
sortByFields.add(sortByField);
// this is the user who initiates the request
String authorizedUser = MultitenantUtils.getTenantAwareUsername(
CarbonContext.getThreadLocalCarbonContext().getUsername());
try {
String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser);
int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain);
AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI();
List<SearchResultEntry> searchResults = analyticsDataAPI.search(tenantId, tableName, query,
0,
100,
sortByFields);
List<Event> events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList<String>(),
searchResults);
return Response.ok().entity(events).build();
} catch (AnalyticsException | UserStoreException e) {
log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e);
throw DeviceMgtUtil.buildBadRequestException(
Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT);
}
} catch (DeviceAccessAuthorizationException e) {
log.error(e.getErrorMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build();
}
}
private List<Event> getEventBeans(AnalyticsDataAPI analyticsDataAPI, int tenantId, String tableName,
List<String> columns,
List<SearchResultEntry> searchResults) throws AnalyticsException {
List<String> ids = getIds(searchResults);
List<String> requiredColumns = (columns == null || columns.isEmpty()) ? null : columns;
AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, requiredColumns, ids);
List<Record> records = AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response);
Map<String, Event> eventBeanMap = getEventBeanKeyedWithIds(records);
return getSortedEventBeans(eventBeanMap, searchResults);
}
private List<Event> getSortedEventBeans(Map<String, Event> eventBeanMap,
List<SearchResultEntry> searchResults) {
List<Event> sortedRecords = new ArrayList<>();
for (SearchResultEntry entry : searchResults) {
sortedRecords.add(eventBeanMap.get(entry.getId()));
}
return sortedRecords;
}
private Map<String, Event> getEventBeanKeyedWithIds(List<Record> records) {
Map<String, Event> eventBeanMap = new HashMap<>();
for (Record record : records) {
Event event = getEventBean(record);
eventBeanMap.put(event.getId(), event);
}
return eventBeanMap;
}
private List<String> getIds(List<SearchResultEntry> searchResults) {
List<String> ids = new ArrayList<>();
if (searchResults != null) {
for (SearchResultEntry resultEntry : searchResults) {
ids.add(resultEntry.getId());
}
}
return ids;
}
private static Event getEventBean(Record record) {
Event eventBean = new Event();
eventBean.setId(record.getId());
eventBean.setTableName(record.getTableName());
eventBean.setTimestamp(record.getTimestamp());
eventBean.setValues(record.getValues());
return eventBean;
}
}

@ -30,6 +30,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.analytics.stream.persistence.stub.EventStreamPersistenceAdminServiceStub;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils;
@ -43,6 +44,7 @@ import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorization
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.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.geo.service.GeoService;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService;
import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService;
@ -425,6 +427,27 @@ public class DeviceMgtAPIUtils {
return gadgetDataService;
}
public static GeoService getGeoService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
GeoService geoService = (GeoService) ctx.getOSGiService(GeoService.class, null);
if (geoService == null) {
throw new IllegalStateException("Geo Service has not been initialized.");
}
return geoService;
}
public static AnalyticsDataAPI getAnalyticsDataAPI() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
AnalyticsDataAPI analyticsDataAPI =
(AnalyticsDataAPI) ctx.getOSGiService(AnalyticsDataAPI.class, null);
if (analyticsDataAPI == null) {
String msg = "Analytics api service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return analyticsDataAPI;
}
public static int getTenantId(String tenantDomain) throws DeviceManagementException {
RealmService realmService =
(RealmService) PrivilegedCarbonContext.getThreadLocalCarbonContext().getOSGiService(RealmService.class, null);

@ -37,6 +37,7 @@
<ref bean="userManagementService"/>
<ref bean="userManagementAdminService"/>
<ref bean="groupManagementService"/>
<ref bean="geoService"/>
<ref bean="groupManagementAdminService"/>
<ref bean="applicationManagementAdminService"/>
<ref bean="deviceTypeManagementAdminService"/>
@ -79,6 +80,7 @@
<bean id="roleManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.RoleManagementServiceImpl"/>
<bean id="userManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.UserManagementServiceImpl"/>
<bean id="groupManagementService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.GroupManagementServiceImpl"/>
<bean id="geoService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.GeoServiceImpl"/>
<bean id="deviceManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceManagementAdminServiceImpl"/>
<bean id="applicationManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.ApplicationManagementAdminServiceImpl"/>
<bean id="groupManagementAdminService" class="org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.GroupManagementAdminServiceImpl"/>

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -50,6 +50,7 @@
<Import-Package>
javax.xml.bind.annotation; version="${javax.xml.bind.imp.pkg.version}",
com.fasterxml.jackson.annotation;version="${jackson-annotations.version}",
org.wso2.carbon.analytics.datasource.commons;version="${carbon.analytics.version.range}",
io.swagger.annotations; version="${swagger.annotations.version}"; resolution:=optional
</Import-Package>
</instructions>
@ -68,6 +69,14 @@
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.api</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.datasource.commons</artifactId>
</dependency>
</dependencies>
</project>

@ -61,6 +61,7 @@ public final class DeviceManagementConstants {
private LicenseProperties() {
throw new AssertionError();
}
public static final String PROVIDER = "overview_provider";
public static final String NAME = "overview_name";
public static final String LANGUAGE = "overview_language";
@ -76,6 +77,7 @@ public final class DeviceManagementConstants {
private NotificationProperties() {
throw new AssertionError();
}
public static final String NOTIFICATION_CONFIG_FILE = "notification-messages.xml";
}
@ -83,6 +85,7 @@ public final class DeviceManagementConstants {
private DataBaseTypes() {
throw new AssertionError();
}
public static final String DB_TYPE_MYSQL = "MySQL";
public static final String DB_TYPE_ORACLE = "Oracle";
public static final String DB_TYPE_MSSQL = "Microsoft SQL Server";
@ -91,4 +94,32 @@ public final class DeviceManagementConstants {
public static final String DB_TYPE_POSTGRESQL = "PostgreSQL";
}
public static final class GeoServices {
private GeoServices() {
throw new AssertionError();
}
public static final String ALERT_TYPE_SPEED = "Speed";
public static final String ALERT_TYPE_WITHIN = "Within";
public static final String ALERT_TYPE_EXIT = "Exit";
public static final String ALERT_TYPE_PROXIMITY = "Proximity";
public static final String ALERT_TYPE_STATIONARY = "Stationery";
public static final String ALERT_TYPE_TRAFFIC = "Traffic";
public static final String REGISTRY_PATH_FOR_ALERTS = "/_system/governance/geo/alerts/";
public static final String PROXIMITY_DISTANCE = "proximityDistance";
public static final String PROXIMITY_TIME = "proximityTime";
public static final String STATIONARY_NAME = "stationeryName";
public static final String STATIONARY_TIME = "stationeryTime";
public static final String FLUCTUATION_RADIUS = "fluctuationRadius";
public static final String QUERY_NAME = "queryName";
public static final String AREA_NAME = "areaName";
public static final String GEO_FENCE_GEO_JSON = "geoFenceGeoJSON";
public static final String SPEED_ALERT_VALUE = "speedAlertValue";
public static final String DAS_PORT = "${iot.analytics.https.port}";
public static final String DAS_HOST_NAME = "${iot.analytics.host}";
public static final String DEFAULT_HTTP_PROTOCOL = "https";
public static final String DAS_URL = DEFAULT_HTTP_PROTOCOL + "://" + DAS_HOST_NAME + ":" + DAS_PORT;
}
}

@ -0,0 +1,180 @@
/*
* 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.
*
*/
package org.wso2.carbon.device.mgt.common.geo.service;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The Class Alert Bean.
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "alert")
public class Alert {
/**
* The parse data.
*/
@XmlElement(required = true, name = "parseData")
private String parseData;
/**
* The execution plan name.
*/
@XmlElement(required = true, name = "executionPlan")
private String executionPlan;
/**
* The custom name.
*/
@XmlElement(required = false, nillable = true, name = "customName")
private String customName;
/**
* The query name.
*/
@XmlElementWrapper(required = true, name = "queryName")
private String queryName;
/**
* The CEP action.
*/
@XmlElementWrapper(required = true, name = "cepAction")
private String cepAction;
/**
* The device id.
*/
@XmlElementWrapper(required = true, name = "deviceId")
private String deviceId;
/**
* The stationery time.
*/
@XmlElementWrapper(required = false, nillable = true, name = "stationeryTime")
private String stationeryTime;
/**
* The fluctuation radius.
*/
@XmlElementWrapper(required = false, nillable = true, name = "fluctuationRadius")
private String fluctuationRadius;
/**
* The proximity distance.
*/
@XmlElementWrapper(required = false, nillable = true, name = "proximityDistance")
private String proximityDistance;
/**
* The proximity time.
*/
@XmlElementWrapper(required = false, nillable = true, name = "proximityTime")
private String proximityTime;
public String getParseData() {
return parseData;
}
public void setParseData(String parseData) {
this.parseData = parseData;
}
public String getExecutionPlan() {
return executionPlan;
}
public void setExecutionPlan(String executionPlan) {
this.executionPlan = executionPlan;
}
public String getCustomName() {
return customName;
}
public void setCustomName(String customName) {
this.customName = customName;
}
public String getQueryName() {
return queryName;
}
public void setQueryName(String queryName) {
this.queryName = queryName;
}
public String getCepAction() {
return cepAction;
}
public void setCepAction(String cepAction) {
this.cepAction = cepAction;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getStationeryTime() {
return stationeryTime;
}
public void setStationeryTime(String stationeryTime) {
this.stationeryTime = stationeryTime;
}
public String getFluctuationRadius() {
return fluctuationRadius;
}
public void setFluctuationRadius(String fluctuationRadius) {
this.fluctuationRadius = fluctuationRadius;
}
public String getProximityDistance() {
return proximityDistance;
}
public void setProximityDistance(String proximityDistance) {
this.proximityDistance = proximityDistance;
}
public String getProximityTime() {
return proximityTime;
}
public void setProximityTime(String proximityTime) {
this.proximityTime = proximityTime;
}
@Override
public String toString() {
return String.format(
"{\"queryName\" : %s,\"customName\" : %s,\"cepAction\" : %s,\"deviceId\" : %s }",
queryName, customName, cepAction, deviceId);
}
}

@ -0,0 +1,135 @@
/*
* 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.
*
*/
package org.wso2.carbon.device.mgt.common.geo.service;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* The Class RecordBean.
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "event")
public class Event {
/** The id. */
@XmlElement(required = false, name = "id")
private String id;
/** The table name. */
@XmlElement(required = false, name = "tableName")
private String tableName;
/** The timestamp. */
@XmlElement(required = false, nillable = true, name = "timestamp")
private long timestamp;
/** The values. */
@XmlElementWrapper(required = true, name = "values")
private Map<String, Object> values;
/**
* Sets the table name.
* @param tableName the new table name
*/
public void setTableName(String tableName) {
this.tableName = tableName;
}
/**
* Sets the values.
* @param values the values
*/
public void setValues(Map<String, Object> values) {
this.values = values;
}
/**
* Sets the timestamp.
* @param timestamp the new timestamp
*/
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
/**
* Sets the id.
* @param id the new id
*/
public void setId(String id) {
this.id = id;
}
/**
* Gets the id.
* @return the id
*/
public String getId() {
return id;
}
/**
* Gets the table name.
* @return the table name
*/
public String getTableName() {
return tableName;
}
/**
* Gets the values.
* @return the values
*/
public Map<String, Object> getValues() {
return values;
}
/**
* Gets the value.
* @param name
* the name
* @return the value
*/
public Object getValue(String name) {
return this.values.get(name);
}
/**
* Gets the timestamp.
* @return the timestamp
*/
public long getTimestamp() {
return timestamp;
}
@Override
public String toString(){
List<String> valueList = new ArrayList<>();
for (Map.Entry<String, Object> entry : values.entrySet()) {
valueList.add(entry.getKey() + ":" + entry.getValue());
}
return valueList.toString();
}
}

@ -0,0 +1,114 @@
/*
* 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.
*
*/
package org.wso2.carbon.device.mgt.common.geo.service;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The Class GeoFence.
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "fence")
public class GeoFence {
/** The geoJson. */
@XmlElement(required = false, name = "geoJson")
private String geoJson;
/** The queryName. */
@XmlElement(required = false, name = "queryName")
private String queryName;
/** The areaName. */
@XmlElement(required = false, name = "areaName")
private String areaName;
/** The createdTime. */
@XmlElement(required = false, nillable = true, name = "createdTime")
private long createdTime;
/** The stationaryTime. */
@XmlElement(required = false, name = "stationaryTime")
private String stationaryTime;
/** The fluctuationRadius. */
@XmlElement(required = false, name = "fluctuationRadius")
private String fluctuationRadius;
public String getGeoJson() {
return geoJson;
}
public void setGeoJson(String geoJson) {
this.geoJson = geoJson;
}
public String getQueryName() {
return queryName;
}
public void setQueryName(String queryName) {
this.queryName = queryName;
}
public String getAreaName() {
return areaName;
}
public void setAreaName(String areaName) {
this.areaName = areaName;
}
public long getCreatedTime() {
return createdTime;
}
public void setCreatedTime(long createdTime) {
this.createdTime = createdTime;
}
public void setStationaryTime(String stationaryTime) {
this.stationaryTime = stationaryTime;
}
public String getStationaryTime() {
return stationaryTime;
}
public void setFluctuationRadius(String fluctuationRadius) {
this.fluctuationRadius = fluctuationRadius;
}
public String getFluctuationRadius() {
return fluctuationRadius;
}
@Override
public String toString() {
return "{\"geoJson\": " + geoJson +
",\"queryName\": " + queryName +
",\"areaName\":" + areaName +
",\"createdTime\":" + createdTime +
"}";
}
}

@ -0,0 +1,51 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.common.geo.service;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import java.util.List;
/**
* This represents the Geo service functionality which should be implemented by
* required GeoServiceManagers.
*/
public interface GeoService {
List<GeoFence> getWithinAlerts(DeviceIdentifier identifier) throws GeoServiceException;
List<GeoFence> getExitAlerts(DeviceIdentifier identifier) throws GeoServiceException;
boolean createGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType)
throws GeoServiceException;
boolean updateGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType)
throws GeoServiceException;
boolean removeGeoAlert(String alertType, DeviceIdentifier identifier, String queryName)
throws GeoServiceException;
String getSpeedAlerts(DeviceIdentifier identifier) throws GeoServiceException;
String getProximityAlerts(DeviceIdentifier identifier) throws GeoServiceException;
List<GeoFence> getStationaryAlerts(DeviceIdentifier identifier) throws GeoServiceException;
List<GeoFence> getTrafficAlerts(DeviceIdentifier identifier) throws GeoServiceException;
}

@ -0,0 +1,60 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.common.geo.service;
/**
* Custom exception class of Geo Service related operations.
*/
public class GeoServiceException extends Exception {
private static final long serialVersionUID = -7151990041029070298L;
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public GeoServiceException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public GeoServiceException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public GeoServiceException(String msg) {
super(msg);
setErrorMessage(msg);
}
public GeoServiceException() {
super();
}
public GeoServiceException(Throwable cause) {
super(cause);
}
}

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>3.0.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -66,6 +66,7 @@
org.wso2.carbon.core,
org.wso2.carbon.utils.*,
org.wso2.carbon.device.mgt.common.*,
org.wso2.carbon.device.mgt.analytics.data.publisher.service,
org.wso2.carbon.user.api,
org.wso2.carbon.user.core.*,
org.wso2.carbon.registry.core.service,
@ -81,12 +82,15 @@
org.wso2.carbon.ntask.common,
org.apache.catalina,
org.apache.catalina.core,
org.apache.commons.collections,
org.apache.commons.collections;version="${commons-collections.version.range}",
org.wso2.carbon.email.sender.*,
io.swagger.annotations.*;resolution:=optional,
org.wso2.carbon,
org.wso2.carbon.base,
org.scannotation.*
org.scannotation.*,
org.wso2.carbon.event.processor.stub,
org.wso2.carbon.identity.jwt.client.extension.service,
org.apache.commons.codec.binary
</Import-Package>
<Export-Package>
!org.wso2.carbon.device.mgt.core.internal,
@ -133,6 +137,17 @@
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.analytics.data.publisher</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.logging</artifactId>
@ -262,6 +277,20 @@
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.event-processing</groupId>
<artifactId>org.wso2.carbon.event.processor.stub</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec.wso2</groupId>
<artifactId>commons-codec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>

@ -265,16 +265,22 @@ public class ApplicationManagerProviderServiceImpl implements ApplicationManagem
@Override
public List<Application> getApplicationListForDevice(
DeviceIdentifier deviceId) throws ApplicationManagementException {
Device device = null;
try {
Device device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider().getDevice(deviceId,
device = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider().getDevice(deviceId,
false);
if (device == null) {
if (log.isDebugEnabled()) {
log.debug("No device is found upon the device identifier '" + deviceId.getId() +
"' and type '" + deviceId.getType() + "'. Therefore returning null");
}
return null;
} catch (DeviceManagementException e) {
throw new ApplicationManagementException("Error occurred while fetching the device of '" +
deviceId.getType() + "' carrying the identifier'" + deviceId.getId(), e);
}
if (device == null) {
if (log.isDebugEnabled()) {
log.debug("No device is found upon the device identifier '" + deviceId.getId() +
"' and type '" + deviceId.getType() + "'. Therefore returning null");
}
return null;
}
try {
DeviceManagementDAOFactory.openConnection();
return applicationDAO.getInstalledApplications(device.getId());
} catch (DeviceManagementDAOException e) {
@ -282,10 +288,7 @@ public class ApplicationManagerProviderServiceImpl implements ApplicationManagem
deviceId.getType() + "' device carrying the identifier'" + deviceId.getId(), e);
} catch (SQLException e) {
throw new ApplicationManagementException("Error occurred while opening a connection to the data source", e);
} catch (DeviceManagementException e) {
throw new ApplicationManagementException("Error occurred while fetching the device of '" +
deviceId.getType() + "' carrying the identifier'" + deviceId.getId(), e);
} finally {
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}

@ -17,6 +17,7 @@
*/
package org.wso2.carbon.device.mgt.core.config;
import org.wso2.carbon.device.mgt.core.config.geo.location.GeoLocationConfiguration;
import org.wso2.carbon.device.mgt.core.config.cache.DeviceCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations;
import org.wso2.carbon.device.mgt.core.config.pagination.PaginationConfiguration;
@ -45,7 +46,7 @@ public final class DeviceManagementConfig {
private PullNotificationConfiguration pullNotificationConfiguration;
private DeviceStatusTaskConfig deviceStatusTaskConfig;
private DeviceCacheConfiguration deviceCacheConfiguration;
private GeoLocationConfiguration geoLocationConfiguration;
@XmlElement(name = "ManagementRepository", required = true)
public DeviceManagementConfigRepository getDeviceManagementConfigRepository() {
@ -128,5 +129,14 @@ public final class DeviceManagementConfig {
public void setDeviceCacheConfiguration(DeviceCacheConfiguration deviceCacheConfiguration) {
this.deviceCacheConfiguration = deviceCacheConfiguration;
}
@XmlElement(name = "GeoLocationConfiguration", required = true)
public GeoLocationConfiguration getGeoLocationConfiguration() {
return geoLocationConfiguration;
}
public void setGeoLocationConfiguration(GeoLocationConfiguration geoLocationConfiguration) {
this.geoLocationConfiguration = geoLocationConfiguration;
}
}

@ -0,0 +1,40 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.core.config.geo.location;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This class represents the information related to Geo Location configuration.
*/
@XmlRootElement(name = "GeoLocationConfiguration")
public class GeoLocationConfiguration {
private boolean publishLocationOperationResponse;
public boolean getPublishLocationOperationResponse() {
return publishLocationOperationResponse;
}
@XmlElement(name = "PublishLocationOperationResponse", required = true)
public void setPublishLocationOperationResponse(boolean publishLocationOperationResponse) {
this.publishLocationOperationResponse = publishLocationOperationResponse;
}
}

@ -20,11 +20,16 @@ package org.wso2.carbon.device.mgt.core.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.IllegalTransactionStateException;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.UnsupportedDatabaseEngineException;
import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig;
import org.wso2.carbon.device.mgt.core.config.datasource.JNDILookupDefinition;
import org.wso2.carbon.device.mgt.core.dao.impl.GroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.impl.group.GenericGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.impl.group.OracleGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.impl.group.PostgreSQLGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.impl.group.SQLServerGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.util.GroupManagementDAOUtil;
import javax.sql.DataSource;
@ -40,6 +45,7 @@ public class GroupManagementDAOFactory {
private static final Log log = LogFactory.getLog(GroupManagementDAOFactory.class);
private static DataSource dataSource;
private static String databaseEngine;
private static ThreadLocal<Connection> currentConnection = new ThreadLocal<>();
/**
@ -48,25 +54,40 @@ public class GroupManagementDAOFactory {
* @return instance of GroupDAO implementation
*/
public static GroupDAO getGroupDAO() {
return new GroupDAOImpl();
if (databaseEngine != null) {
switch (databaseEngine) {
case DeviceManagementConstants.DataBaseTypes.DB_TYPE_ORACLE:
return new OracleGroupDAOImpl();
case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MSSQL:
return new SQLServerGroupDAOImpl();
case DeviceManagementConstants.DataBaseTypes.DB_TYPE_POSTGRESQL:
return new PostgreSQLGroupDAOImpl();
case DeviceManagementConstants.DataBaseTypes.DB_TYPE_H2:
case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MYSQL:
return new GenericGroupDAOImpl();
default:
throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine);
}
}
throw new IllegalStateException("Database engine has not initialized properly.");
}
/**
* Initialize factory with datasource configs
*
* @param config data source configuration
*/
public static void init(DataSourceConfig config) {
dataSource = resolveDataSource(config);
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
}
/**
* Initialize factory with existing datasource
*
* @param dtSource an existing datasource
*/
public static void init(DataSource dtSource) {
dataSource = dtSource;
try {
databaseEngine = dataSource.getConnection().getMetaData().getDatabaseProductName();
} catch (SQLException e) {
log.error("Error occurred while retrieving config.datasource connection", e);
}
}
/**
@ -129,8 +150,8 @@ public class GroupManagementDAOFactory {
Connection conn = currentConnection.get();
if (conn == null) {
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
"This might have ideally been caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
"This might have ideally been caused by not properly initiating " +
"the transaction via 'beginTransaction'/'openConnection' methods");
}
try {
conn.commit();
@ -146,8 +167,8 @@ public class GroupManagementDAOFactory {
Connection conn = currentConnection.get();
if (conn == null) {
throw new IllegalTransactionStateException("No connection is associated with the current transaction. " +
"This might have ideally been caused by not properly initiating the transaction via " +
"'beginTransaction'/'openConnection' methods");
"This might have ideally been caused by not properly initiating " +
"the transaction via 'beginTransaction'/'openConnection' methods");
}
try {
conn.rollback();

@ -18,13 +18,11 @@
package org.wso2.carbon.device.mgt.core.dao.impl;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.core.dao.GroupDAO;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.dao.util.GroupManagementDAOUtil;
import java.sql.Connection;
@ -37,7 +35,7 @@ import java.util.List;
/**
* This class represents implementation of GroupDAO
*/
public class GroupDAOImpl implements GroupDAO {
public abstract class AbstractGroupDAOImpl implements GroupDAO {
@Override
public int addGroup(DeviceGroup deviceGroup, int tenantId) throws GroupManagementDAOException {
@ -47,7 +45,7 @@ public class GroupDAOImpl implements GroupDAO {
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "INSERT INTO DM_GROUP(DESCRIPTION, GROUP_NAME, OWNER, TENANT_ID) VALUES (?, ?, ?, ?)";
stmt = conn.prepareStatement(sql, new String[]{"ID"});
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt.setString(1, deviceGroup.getDescription());
stmt.setString(2, deviceGroup.getName());
stmt.setString(3, deviceGroup.getOwner());
@ -179,126 +177,6 @@ public class GroupDAOImpl implements GroupDAO {
return deviceGroupBuilders;
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, int tenantId)
throws GroupManagementDAOException {
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
if (hasLimit) {
sql += " LIMIT ?, ?";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,
int tenantId) throws GroupManagementDAOException {
int deviceGroupIdsCount = deviceGroupIds.size();
if (deviceGroupIdsCount == 0) {
return new ArrayList<>();
}
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
}
sql += ")";
if (hasLimit) {
sql += " LIMIT ?, ?";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<DeviceGroup> getGroups(int tenantId) throws GroupManagementDAOException {
PreparedStatement stmt = null;
@ -495,49 +373,6 @@ public class GroupDAOImpl implements GroupDAO {
}
}
@Override
public List<Device> getDevices(int groupId, int startIndex, int rowCount, int tenantId)
throws GroupManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
List<Device> devices = null;
try {
conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
"FROM " +
"(SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID FROM" +
" DM_DEVICE d, (" +
"SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 " +
"WHERE d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?) gd, DM_DEVICE_TYPE t " +
"WHERE gd.DEVICE_TYPE_ID = t.ID) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? LIMIT ? , ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
stmt.setInt(2, tenantId);
stmt.setInt(3, tenantId);
//noinspection JpaQueryApiInspection
stmt.setInt(4, startIndex);
//noinspection JpaQueryApiInspection
stmt.setInt(5, rowCount);
rs = stmt.executeQuery();
devices = new ArrayList<>();
while (rs.next()) {
Device device = DeviceManagementDAOUtil.loadDevice(rs);
devices.add(device);
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while retrieving information of all " +
"registered devices", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return devices;
}
@Override
public List<String> getRoles(int groupId, int tenantId) throws GroupManagementDAOException {
PreparedStatement stmt = null;

@ -0,0 +1,204 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.core.dao.impl.group;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.impl.AbstractGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.dao.util.GroupManagementDAOUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* This class represents implementation of GroupDAO
*/
public class GenericGroupDAOImpl extends AbstractGroupDAOImpl {
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, int tenantId)
throws GroupManagementDAOException {
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
if (hasLimit) {
sql += " LIMIT ?, ?";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,
int tenantId) throws GroupManagementDAOException {
int deviceGroupIdsCount = deviceGroupIds.size();
if (deviceGroupIdsCount == 0) {
return new ArrayList<>();
}
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
}
sql += ")";
if (hasLimit) {
sql += " LIMIT ?, ?";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<Device> getDevices(int groupId, int startIndex, int rowCount, int tenantId)
throws GroupManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
List<Device> devices = null;
try {
conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
"FROM " +
"(SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID FROM" +
" DM_DEVICE d, (" +
"SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 " +
"WHERE d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?) gd, DM_DEVICE_TYPE t " +
"WHERE gd.DEVICE_TYPE_ID = t.ID) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? LIMIT ? , ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
stmt.setInt(2, tenantId);
stmt.setInt(3, tenantId);
//noinspection JpaQueryApiInspection
stmt.setInt(4, startIndex);
//noinspection JpaQueryApiInspection
stmt.setInt(5, rowCount);
rs = stmt.executeQuery();
devices = new ArrayList<>();
while (rs.next()) {
Device device = DeviceManagementDAOUtil.loadDevice(rs);
devices.add(device);
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while retrieving information of all " +
"registered devices", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return devices;
}
}

@ -0,0 +1,204 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.core.dao.impl.group;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.impl.AbstractGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.dao.util.GroupManagementDAOUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* This class represents implementation of GroupDAO
*/
public class OracleGroupDAOImpl extends AbstractGroupDAOImpl {
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, int tenantId)
throws GroupManagementDAOException {
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
if (hasLimit) {
sql += " OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,
int tenantId) throws GroupManagementDAOException {
int deviceGroupIdsCount = deviceGroupIds.size();
if (deviceGroupIdsCount == 0) {
return new ArrayList<>();
}
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
}
sql += ")";
if (hasLimit) {
sql += " OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<Device> getDevices(int groupId, int startIndex, int rowCount, int tenantId)
throws GroupManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
List<Device> devices = null;
try {
conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
"FROM " +
"(SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID FROM" +
" DM_DEVICE d, (" +
"SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 " +
"WHERE d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?) gd, DM_DEVICE_TYPE t " +
"WHERE gd.DEVICE_TYPE_ID = t.ID) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
stmt.setInt(2, tenantId);
stmt.setInt(3, tenantId);
//noinspection JpaQueryApiInspection
stmt.setInt(4, startIndex);
//noinspection JpaQueryApiInspection
stmt.setInt(5, rowCount);
rs = stmt.executeQuery();
devices = new ArrayList<>();
while (rs.next()) {
Device device = DeviceManagementDAOUtil.loadDevice(rs);
devices.add(device);
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while retrieving information of all " +
"registered devices", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return devices;
}
}

@ -0,0 +1,204 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.core.dao.impl.group;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.impl.AbstractGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.dao.util.GroupManagementDAOUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* This class represents implementation of GroupDAO
*/
public class PostgreSQLGroupDAOImpl extends AbstractGroupDAOImpl {
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, int tenantId)
throws GroupManagementDAOException {
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
if (hasLimit) {
sql += " LIMIT ? OFFSET ?";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getRowCount());
stmt.setInt(paramIndex, request.getStartIndex());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,
int tenantId) throws GroupManagementDAOException {
int deviceGroupIdsCount = deviceGroupIds.size();
if (deviceGroupIdsCount == 0) {
return new ArrayList<>();
}
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
}
sql += ")";
if (hasLimit) {
sql += " LIMIT ? OFFSET ?";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getRowCount());
stmt.setInt(paramIndex, request.getStartIndex());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<Device> getDevices(int groupId, int startIndex, int rowCount, int tenantId)
throws GroupManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
List<Device> devices = null;
try {
conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
"FROM " +
"(SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID FROM" +
" DM_DEVICE d, (" +
"SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 " +
"WHERE d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?) gd, DM_DEVICE_TYPE t " +
"WHERE gd.DEVICE_TYPE_ID = t.ID) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? LIMIT ? OFFSET ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
stmt.setInt(2, tenantId);
stmt.setInt(3, tenantId);
//noinspection JpaQueryApiInspection
stmt.setInt(4, rowCount);
//noinspection JpaQueryApiInspection
stmt.setInt(5, startIndex);
rs = stmt.executeQuery();
devices = new ArrayList<>();
while (rs.next()) {
Device device = DeviceManagementDAOUtil.loadDevice(rs);
devices.add(device);
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while retrieving information of all " +
"registered devices", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return devices;
}
}

@ -0,0 +1,204 @@
/*
* 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.
*/
package org.wso2.carbon.device.mgt.core.dao.impl.group;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.GroupPaginationRequest;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.impl.AbstractGroupDAOImpl;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.dao.util.GroupManagementDAOUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* This class represents implementation of GroupDAO
*/
public class SQLServerGroupDAOImpl extends AbstractGroupDAOImpl {
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, int tenantId)
throws GroupManagementDAOException {
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
if (hasLimit) {
sql += " OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<DeviceGroup> getGroups(GroupPaginationRequest request, List<Integer> deviceGroupIds,
int tenantId) throws GroupManagementDAOException {
int deviceGroupIdsCount = deviceGroupIds.size();
if (deviceGroupIdsCount == 0) {
return new ArrayList<>();
}
PreparedStatement stmt = null;
ResultSet resultSet = null;
List<DeviceGroup> deviceGroupList = null;
String groupName = request.getGroupName();
boolean hasGroupName = false;
String owner = request.getOwner();
boolean hasOwner = false;
boolean hasLimit = request.getRowCount() != 0;
try {
Connection conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT ID, DESCRIPTION, GROUP_NAME, OWNER FROM DM_GROUP WHERE TENANT_ID = ?";
if (groupName != null && !groupName.isEmpty()) {
sql += " AND GROUP_NAME LIKE ?";
hasGroupName = true;
}
if (owner != null && !owner.isEmpty()) {
sql += " AND OWNER LIKE ?";
hasOwner = true;
}
sql += " AND ID IN (";
for (int i = 0; i < deviceGroupIdsCount; i++) {
sql += (deviceGroupIdsCount - 1 != i) ? "?," : "?";
}
sql += ")";
if (hasLimit) {
sql += " OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
}
int paramIndex = 1;
stmt = conn.prepareStatement(sql);
stmt.setInt(paramIndex++, tenantId);
if (hasGroupName) {
stmt.setString(paramIndex++, groupName + "%");
}
if (hasOwner) {
stmt.setString(paramIndex++, owner + "%");
}
for (Integer deviceGroupId : deviceGroupIds) {
stmt.setInt(paramIndex++, deviceGroupId);
}
if (hasLimit) {
stmt.setInt(paramIndex++, request.getStartIndex());
stmt.setInt(paramIndex, request.getRowCount());
}
resultSet = stmt.executeQuery();
deviceGroupList = new ArrayList<>();
while (resultSet.next()) {
deviceGroupList.add(GroupManagementDAOUtil.loadGroup(resultSet));
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while listing all groups in tenant: " + tenantId, e);
} finally {
GroupManagementDAOUtil.cleanupResources(stmt, resultSet);
}
return deviceGroupList;
}
@Override
public List<Device> getDevices(int groupId, int startIndex, int rowCount, int tenantId)
throws GroupManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
List<Device> devices = null;
try {
conn = GroupManagementDAOFactory.getConnection();
String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " +
"(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " +
"FROM " +
"(SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID FROM" +
" DM_DEVICE d, (" +
"SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 " +
"WHERE d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?) gd, DM_DEVICE_TYPE t " +
"WHERE gd.DEVICE_TYPE_ID = t.ID) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, groupId);
stmt.setInt(2, tenantId);
stmt.setInt(3, tenantId);
//noinspection JpaQueryApiInspection
stmt.setInt(4, startIndex);
//noinspection JpaQueryApiInspection
stmt.setInt(5, rowCount);
rs = stmt.executeQuery();
devices = new ArrayList<>();
while (rs.next()) {
Device device = DeviceManagementDAOUtil.loadDevice(rs);
devices.add(device);
}
} catch (SQLException e) {
throw new GroupManagementDAOException("Error occurred while retrieving information of all " +
"registered devices", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return devices;
}
}

@ -22,7 +22,11 @@ package org.wso2.carbon.device.mgt.core.device.details.mgt.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo;
import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation;
import org.wso2.carbon.device.mgt.core.dao.DeviceDAO;
@ -33,6 +37,7 @@ import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManag
import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsDAO;
import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsMgtDAOException;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import java.sql.SQLException;
import java.util.ArrayList;
@ -45,6 +50,7 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager {
private DeviceDetailsDAO deviceDetailsDAO;
private DeviceDAO deviceDAO;
private static final Log log = LogFactory.getLog(DeviceInformationManagerImpl.class);
private static final String EVENT_STREAM_DEFINITION = "org.wso2.iot.LocationStream";
public DeviceInformationManagerImpl() {
this.deviceDAO = DeviceManagementDAOFactory.getDeviceDAO();
@ -160,6 +166,17 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager {
deviceDAO.updateDevice(device, CarbonContext.getThreadLocalCarbonContext().getTenantId());
deviceDetailsDAO.deleteDeviceLocation(deviceLocation.getDeviceId());
deviceDetailsDAO.addDeviceLocation(deviceLocation);
if (DeviceManagerUtil.isPublishLocationOperationResEnabled()) {
Object metaData[] = {device.getDeviceIdentifier(), device.getType()};
Object payload[] = new Object[]{
deviceLocation.getUpdatedTime().getTime(),
deviceLocation.getLatitude(),
deviceLocation.getLongitude()
};
DeviceManagerUtil.getEventPublisherService().publishEvent(
EVENT_STREAM_DEFINITION, "1.0.0", metaData, new Object[0], payload
);
}
DeviceManagementDAOFactory.commitTransaction();
} catch (TransactionManagementException e) {
throw new DeviceDetailsMgtException("Transactional error occurred while adding the device location " +
@ -174,6 +191,9 @@ public class DeviceInformationManagerImpl implements DeviceInformationManager {
DeviceManagementDAOFactory.rollbackTransaction();
throw new DeviceDetailsMgtException("Error occurred while updating the last updated timestamp of " +
"the device", e);
} catch (DataPublisherConfigurationException e) {
DeviceManagementDAOFactory.rollbackTransaction();
throw new DeviceDetailsMgtException("Error occurred while publishing the device location information.", e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}

@ -0,0 +1,728 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.geo.service;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.Stub;
import org.apache.axis2.java.security.SSLProtocolSocketFactory;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.Utils;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices;
import org.wso2.carbon.device.mgt.common.geo.service.Alert;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFence;
import org.wso2.carbon.device.mgt.common.geo.service.GeoService;
import org.wso2.carbon.device.mgt.common.geo.service.GeoServiceException;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.event.processor.stub.EventProcessorAdminServiceStub;
import org.wso2.carbon.identity.jwt.client.extension.JWTClient;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException;
import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService;
import org.wso2.carbon.registry.api.Registry;
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices.DAS_PORT;
import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices.DEFAULT_HTTP_PROTOCOL;
/**
* This class will read events, set alerts, read alerts related to geo-fencing and it will
* use Registry as the persistence storage.
*/
public class GeoServcieManagerImpl implements GeoService {
private static Log log = LogFactory.getLog(GeoServcieManagerImpl.class);
/**
* required soap header for authorization
*/
private static final String AUTHORIZATION_HEADER = "Authorization";
/**
* required soap header value for mutualSSL
*/
private static final String AUTHORIZATION_HEADER_VALUE = "Bearer";
/**
* Default keystore type of the client
*/
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";
@Override
public List<GeoFence> getWithinAlerts(DeviceIdentifier identifier) throws GeoServiceException {
Registry registry = getGovernanceRegistry();
String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_WITHIN + "/" + identifier.getId() + "/";
Resource resource;
try {
resource = registry.get(registryPath);
} catch (RegistryException e) {
log.error("Error while reading the registry path: " + registryPath);
return null;
}
try {
List<GeoFence> fences = new ArrayList<>();
if (resource != null) {
Object contentObj = resource.getContent();
if (contentObj instanceof String[]) {
String[] content = (String[]) contentObj;
for (String res : content) {
Resource childRes = registry.get(res);
Properties props = childRes.getProperties();
GeoFence geoFence = new GeoFence();
InputStream inputStream = childRes.getContentStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
geoFence.setGeoJson(writer.toString());
List queryNameObj = (List) props.get(GeoServices.QUERY_NAME);
geoFence.setQueryName(queryNameObj != null ? queryNameObj.get(0).toString() : null);
List areaNameObj = (List) props.get(GeoServices.AREA_NAME);
geoFence.setAreaName(areaNameObj != null ? areaNameObj.get(0).toString() : null);
geoFence.setCreatedTime(childRes.getCreatedTime().getTime());
fences.add(geoFence);
}
}
}
return fences;
} catch (RegistryException | IOException e) {
throw new GeoServiceException(
"Error occurred while getting the geo alerts for " + identifier.getType() + " with id: " +
identifier.getId(), e);
}
}
@Override
public List<GeoFence> getExitAlerts(DeviceIdentifier identifier) throws GeoServiceException {
Registry registry = getGovernanceRegistry();
String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_EXIT + "/" + identifier.getId() + "/";
Resource resource;
try {
resource = registry.get(registryPath);
} catch (RegistryException e) {
log.error("Error while reading the registry path: " + registryPath);
return null;
}
try {
List<GeoFence> fences = new ArrayList<>();
if (resource != null) {
Object contentObj = resource.getContent();
if (contentObj instanceof String[]) {
String[] content = (String[]) contentObj;
for (String res : content) {
Resource childRes = registry.get(res);
Properties props = childRes.getProperties();
GeoFence geoFence = new GeoFence();
InputStream inputStream = childRes.getContentStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
geoFence.setGeoJson(writer.toString());
List queryNameObj = (List) props.get(GeoServices.QUERY_NAME);
geoFence.setQueryName(queryNameObj != null ? queryNameObj.get(0).toString() : null);
List areaNameObj = (List) props.get(GeoServices.AREA_NAME);
geoFence.setAreaName(areaNameObj != null ? areaNameObj.get(0).toString() : null);
geoFence.setCreatedTime(childRes.getCreatedTime().getTime());
fences.add(geoFence);
}
}
}
return fences;
} catch (RegistryException | IOException e) {
throw new GeoServiceException(
"Error occurred while getting the geo alerts for " + identifier.getType() + " with id: " +
identifier.getId(), e);
}
}
@Override
public boolean createGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType)
throws GeoServiceException {
return saveGeoAlert(alert, identifier, alertType, false);
}
@Override
public boolean updateGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType)
throws GeoServiceException {
return saveGeoAlert(alert, identifier, alertType, true);
}
public boolean saveGeoAlert(Alert alert, DeviceIdentifier identifier, String alertType, boolean isUpdate)
throws GeoServiceException {
Type type = new TypeToken<Map<String, String>>() {
}.getType();
Gson gson = new Gson();
Map<String, String> parseMap = gson.fromJson(alert.getParseData(), type);
Map<String, String> options = new HashMap<>();
Object content = null;
if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) {
options.put(GeoServices.QUERY_NAME, alert.getQueryName());
options.put(GeoServices.AREA_NAME, alert.getCustomName());
content = parseMap.get(GeoServices.GEO_FENCE_GEO_JSON);
} else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) {
options.put(GeoServices.QUERY_NAME, alert.getQueryName());
options.put(GeoServices.AREA_NAME, alert.getCustomName());
content = parseMap.get(GeoServices.GEO_FENCE_GEO_JSON);
} else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) {
content = parseMap.get(GeoServices.SPEED_ALERT_VALUE);
} else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) {
options.put(GeoServices.PROXIMITY_DISTANCE, alert.getProximityDistance());
options.put(GeoServices.PROXIMITY_TIME, alert.getProximityTime());
content = alert.getParseData();
} else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) {
options.put(GeoServices.QUERY_NAME, alert.getQueryName());
options.put(GeoServices.AREA_NAME, alert.getCustomName());
options.put(GeoServices.STATIONARY_TIME, alert.getStationeryTime());
options.put(GeoServices.FLUCTUATION_RADIUS, alert.getFluctuationRadius());
content = alert.getParseData();
} else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) {
content = parseMap.get(GeoServices.GEO_FENCE_GEO_JSON);
} else {
throw new GeoServiceException(
"Unrecognized execution plan type: " + alertType + " while creating geo alert");
}
//persist alert in registry
updateRegistry(getRegistryPath(alertType, identifier, alert.getQueryName()), identifier, content,
options);
//deploy alert into event processor
EventProcessorAdminServiceStub eventprocessorStub = null;
String action = (isUpdate ? "updating" : "creating");
try {
eventprocessorStub = getEventProcessorAdminServiceStub();
String parsedTemplate = parseTemplate(alertType, parseMap);
String validationResponse = eventprocessorStub.validateExecutionPlan(parsedTemplate);
if (validationResponse.equals("success")) {
if (isUpdate) {
String executionPlanName = getExecutionPlanName(alertType, alert.getQueryName(),
identifier.getId());
eventprocessorStub.editActiveExecutionPlan(parsedTemplate, executionPlanName);
} else {
eventprocessorStub.deployExecutionPlan(parsedTemplate);
}
} else {
if (validationResponse.startsWith(
"'within' is neither a function extension nor an aggregated attribute extension"
)) {
log.error("GPL Siddhi Geo Extension is not configured. Please execute maven script " +
"`siddhi-geo-extention-deployer.xml` in $IOT_HOME/analytics/scripts");
} else {
log.error("Execution plan validation failed: " + validationResponse);
}
throw new GeoServiceException(
"Error occurred while " + action + " geo " + alertType + " alert for " +
identifier.getType() + " with id: " + identifier.getId());
}
return true;
} catch (AxisFault axisFault) {
throw new GeoServiceException(
"Event processor admin service initialization failed while " + action + " geo alert '" +
alertType + "' for " + identifier.getType() + " " +
"device with id: " + identifier.getId(), axisFault
);
} catch (IOException e) {
throw new GeoServiceException(
"Event processor admin service failed while " + action + " geo alert '" +
alertType + "' for " + identifier.getType() + " " +
"device with id: " + identifier.getId(), e);
} catch (JWTClientException e) {
throw new GeoServiceException(
"JWT token creation failed while " + action + " geo alert '" + alertType + "' for " +
identifier.getType() + " device with id:" + identifier.getId(), e);
} finally {
cleanup(eventprocessorStub);
}
}
private String getRegistryPath(String alertType, DeviceIdentifier identifier, String queryName)
throws GeoServiceException {
String path = "";
if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_WITHIN +
"/" + identifier.getId() + "/" + queryName;
} else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_EXIT +
"/" + identifier.getId() + "/" + queryName;
} else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_SPEED +
"/" + identifier.getId();
} else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_PROXIMITY +
"/" + identifier.getId() + "/" + queryName;
} else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_STATIONARY +
"/" + identifier.getId() + "/" + queryName;
} else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) {
path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_TRAFFIC +
"/" + identifier.getId() + "/" + queryName;
} else {
throw new GeoServiceException(
"Unrecognized execution plan type: " + alertType);
}
return path;
}
private String getExecutionPlanName(String alertType, String queryName, String deviceId) {
if ("Traffic".equals(alertType)) {
return "Geo-ExecutionPlan-Traffic_" + queryName + "_alert";
} else {
return "Geo-ExecutionPlan-" + alertType + "_" + queryName + "---_" + deviceId + "_alert";
}
}
@Override
public boolean removeGeoAlert(String alertType, DeviceIdentifier identifier, String queryName)
throws GeoServiceException {
removeFromRegistry(alertType, identifier, queryName);
String executionPlanName = getExecutionPlanName(alertType, queryName, identifier.getId());
EventProcessorAdminServiceStub eventprocessorStub = null;
try {
eventprocessorStub = getEventProcessorAdminServiceStub();
eventprocessorStub.undeployActiveExecutionPlan(executionPlanName);
return true;
} catch (IOException e) {
throw new GeoServiceException(
"Event processor admin service stub invocation failed while removing geo alert '" +
alertType +
"': " + executionPlanName + " for " +
identifier.getType() + " device with id:" + identifier.getId(), e
);
} catch (JWTClientException e) {
throw new GeoServiceException(
"JWT token creation failed while removing geo alert '" + alertType + "': " +
executionPlanName + " for " +
identifier.getType() + " device with id:" + identifier.getId(), e
);
} finally {
cleanup(eventprocessorStub);
}
}
private void removeFromRegistry(String alertType, DeviceIdentifier identifier, String queryName)
throws GeoServiceException {
String path = "unknown";
try {
path = getRegistryPath(alertType, identifier, queryName);
getGovernanceRegistry().delete(path);
} catch (RegistryException e) {
throw new GeoServiceException(
"Error occurred while removing " + alertType + " alert for " + identifier.getType() +
" device with id:" + identifier.getId() + " from the path: " + path);
}
}
private EventProcessorAdminServiceStub getEventProcessorAdminServiceStub() throws JWTClientException {
//send alert to event-processing
String eventProcessorAdminServiceWSUrl = Utils.replaceSystemProperty(GeoServices.DAS_URL) +
"/services/EventProcessorAdminService";
//Getting the tenant Domain
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
String tenantAdminUser = username + "@" + tenantDomain;
try {
//Create the SSL context with the loaded TrustStore/keystore.
SSLContext sslContext = initSSLConnection(tenantAdminUser);
JWTClient jwtClient = getJWTClientManagerService().getJWTClient();
String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64(
jwtClient.getJwtToken(tenantAdminUser).getBytes()));
EventProcessorAdminServiceStub eventprocessorStub = new EventProcessorAdminServiceStub(
eventProcessorAdminServiceWSUrl);
Options eventProcessorOption = eventprocessorStub._getServiceClient().getOptions();
if (eventProcessorOption == null) {
eventProcessorOption = new Options();
}
List<Header> list = new ArrayList<>();
Header httpHeader = new Header();
httpHeader.setName(AUTHORIZATION_HEADER);
httpHeader.setValue(authValue);
list.add(httpHeader);//"https"
eventProcessorOption.setProperty(HTTPConstants.HTTP_HEADERS, list);
eventProcessorOption.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER
, new Protocol(DEFAULT_HTTP_PROTOCOL
, (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext)
, Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT))));
eventprocessorStub._getServiceClient().setOptions(eventProcessorOption);
return eventprocessorStub;
} catch (CertificateException | NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException |
KeyManagementException | IOException e) {
throw new JWTClientException("JWT token creation failed for the Event Processor Stub", e);
}
}
@Override
public String getSpeedAlerts(DeviceIdentifier identifier) throws GeoServiceException {
try {
Registry registry = getGovernanceRegistry();
Resource resource = registry.get(GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_SPEED + "/" + identifier.getId());
if (resource == null) {
return "{'content': false}";
}
InputStream inputStream = resource.getContentStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
return "{'speedLimit':" + writer.toString() + "}";
} catch (RegistryException | IOException e) {
return "{'content': false}";
}
}
@Override
public String getProximityAlerts(DeviceIdentifier identifier) throws GeoServiceException {
try {
Registry registry = getGovernanceRegistry();
Resource resource = registry.get(GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_PROXIMITY
+ "/" + identifier.getId());
if (resource != null) {
Properties props = resource.getProperties();
List proxDisObj = (List) props.get(GeoServices.PROXIMITY_DISTANCE);
List proxTimeObj = (List) props.get(GeoServices.PROXIMITY_TIME);
return String.format("{proximityDistance:\"%s\", proximityTime:\"%s\"}",
proxDisObj != null ? proxDisObj.get(0).toString() : "",
proxTimeObj != null ? proxTimeObj.get(0).toString() : "");
} else {
return "{'content': false}";
}
} catch (RegistryException e) {
return "{'content': false}";
}
}
@Override
public List<GeoFence> getStationaryAlerts(DeviceIdentifier identifier) throws GeoServiceException {
Registry registry = getGovernanceRegistry();
String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_STATIONARY + "/" + identifier.getId() + "/";
Resource resource;
try {
resource = registry.get(registryPath);
} catch (RegistryException e) {
log.error("Error while reading the registry path: " + registryPath);
return null;
}
try {
List<GeoFence> fences = new ArrayList<>();
if (resource != null) {
Object contentObj = resource.getContent();
if (contentObj instanceof String[]) {
String[] content = (String[]) contentObj;
for (String res : content) {
Resource childRes = registry.get(res);
Properties props = childRes.getProperties();
GeoFence geoFence = new GeoFence();
InputStream inputStream = childRes.getContentStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
geoFence.setGeoJson(writer.toString());
List queryNameObj = (List) props.get(GeoServices.QUERY_NAME);
geoFence.setQueryName(queryNameObj != null ? queryNameObj.get(0).toString() : null);
List areaNameObj = (List) props.get(GeoServices.AREA_NAME);
geoFence.setAreaName(areaNameObj != null ? areaNameObj.get(0).toString() : null);
List sTimeObj = (List) props.get(GeoServices.STATIONARY_TIME);
geoFence.setStationaryTime(sTimeObj != null ? sTimeObj.get(0).toString() : null);
List fluctRadiusObj = (List) props.get(GeoServices.FLUCTUATION_RADIUS);
geoFence.setFluctuationRadius(fluctRadiusObj != null ? fluctRadiusObj.get(0).toString() : null);
geoFence.setCreatedTime(childRes.getCreatedTime().getTime());
fences.add(geoFence);
}
}
}
return fences;
} catch (RegistryException | IOException e) {
throw new GeoServiceException(
"Error occurred while getting the geo alerts for " + identifier.getType() + " with id: " +
identifier.getId(), e);
}
}
@Override
public List<GeoFence> getTrafficAlerts(DeviceIdentifier identifier) throws GeoServiceException {
Registry registry = getGovernanceRegistry();
String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
GeoServices.ALERT_TYPE_STATIONARY + "/" + identifier.getId() + "/";
Resource resource;
try {
resource = registry.get(registryPath);
} catch (RegistryException e) {
log.error("Error while reading the registry path: " + registryPath);
return null;
}
try {
List<GeoFence> fences = new ArrayList<>();
if (resource != null) {
Object contentObj = resource.getContent();
if (contentObj instanceof String[]) {
String[] content = (String[]) contentObj;
for (String res : content) {
Resource childRes = registry.get(res);
Properties props = childRes.getProperties();
GeoFence geoFence = new GeoFence();
InputStream inputStream = childRes.getContentStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, "UTF-8");
geoFence.setGeoJson(writer.toString());
List queryNameObj = (List) props.get(GeoServices.QUERY_NAME);
geoFence.setQueryName(queryNameObj != null ? queryNameObj.get(0).toString() : null);
List sNameObj = (List) props.get(GeoServices.STATIONARY_NAME);
geoFence.setAreaName(sNameObj != null ? sNameObj.get(0).toString() : null);
geoFence.setCreatedTime(childRes.getCreatedTime().getTime());
fences.add(geoFence);
}
}
}
return fences;
} catch (RegistryException | IOException e) {
throw new GeoServiceException(
"Error occurred while getting the geo alerts for " + identifier.getType() + " with id: " +
identifier.getId(), e);
}
}
private Registry getGovernanceRegistry() throws GeoServiceException {
try {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
return DeviceManagementDataHolder.getInstance().getRegistryService()
.getGovernanceSystemRegistry(
tenantId);
} catch (RegistryException e) {
throw new GeoServiceException(
"Error in retrieving governance registry instance: " +
e.getMessage(), e);
}
}
private String parseTemplate(String alertType, Map<String, String> parseMap) throws GeoServiceException {
String templatePath = "alerts/Geo-ExecutionPlan-" + alertType + "_alert.siddhiql";
InputStream resource = getClass().getClassLoader().getResourceAsStream(templatePath);
if (resource == null) {
throw new GeoServiceException("Could not find template in path : " + templatePath);
}
try {
//Read template
String template = IOUtils.toString(resource, StandardCharsets.UTF_8.toString());
//Replace variables
for (Map.Entry<String, String> parseEntry : parseMap.entrySet()) {
String find = "\\$" + parseEntry.getKey();
template = template.replaceAll(find, parseEntry.getValue());
}
return template;
} catch (IOException e) {
throw new GeoServiceException(
"Error occurred while populating the template for the Within Alert", e);
}
}
private void updateRegistry(String path, DeviceIdentifier identifier, Object content, Map<String, String> options)
throws GeoServiceException {
try {
Registry registry = getGovernanceRegistry();
Resource newResource = registry.newResource();
newResource.setContent(content);
newResource.setMediaType("application/json");
for (Map.Entry<String, String> option : options.entrySet()) {
newResource.addProperty(option.getKey(), option.getValue());
}
registry.put(path, newResource);
} catch (RegistryException e) {
throw new GeoServiceException(
"Error occurred while setting the Within Alert for " + identifier.getType() + " with id: " +
identifier.getId(), e);
}
}
/**
* Loads the keystore.
*
* @param keyStorePath - the path of the keystore
* @param keyStorePassword - the keystore password
*/
private KeyStore loadKeyStore(String keyStorePath, char[] keyStorePassword)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
InputStream fis = null;
try {
KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
fis = new FileInputStream(keyStorePath);
keyStore.load(fis, keyStorePassword);
return keyStore;
} finally {
if (fis != null) {
fis.close();
}
}
}
/**
* Loads the trustore
*
* @param trustStorePath - the trustore path in the filesystem.
* @param tsPassword - the truststore password
*/
private KeyStore loadTrustStore(String trustStorePath, char[] tsPassword)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
InputStream fis = null;
try {
KeyStore trustStore = KeyStore.getInstance(TRUST_STORE_TYPE);
fis = new FileInputStream(trustStorePath);
trustStore.load(fis, tsPassword);
return trustStore;
} finally {
if (fis != null) {
fis.close();
}
}
}
/**
* Initializes the SSL Context
*/
private SSLContext initSSLConnection(String tenantAdminUser)
throws NoSuchAlgorithmException, UnrecoverableKeyException,
KeyStoreException, KeyManagementException, IOException, CertificateException {
String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password");
String trustStorePassword = ServerConfiguration.getInstance().getFirstProperty(
"Security.TrustStore.Password");
String keyStoreLocation = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Location");
String trustStoreLocation = ServerConfiguration.getInstance().getFirstProperty(
"Security.TrustStore.Location");
//Call to load the keystore.
KeyStore keyStore = loadKeyStore(keyStoreLocation, keyStorePassword.toCharArray());
//Call to load the TrustStore.
KeyStore trustStore = loadTrustStore(trustStoreLocation, trustStorePassword.toCharArray());
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;
}
private void cleanup(Stub stub) {
if (stub != null) {
try {
stub.cleanup();
} catch (AxisFault axisFault) {
//do nothing
}
}
}
public static JWTClientManagerService getJWTClientManagerService() {
JWTClientManagerService jwtClientManagerService;
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
jwtClientManagerService = (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null);
if (jwtClientManagerService == null) {
String msg = "jwtClientManagerServicehas not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return jwtClientManagerService;
}
}

@ -25,6 +25,7 @@ import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService;
import org.wso2.carbon.device.mgt.common.geo.service.GeoService;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
@ -43,6 +44,7 @@ import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig;
import org.wso2.carbon.device.mgt.core.config.tenant.PlatformConfigurationManagementServiceImpl;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.geo.service.GeoServcieManagerImpl;
import org.wso2.carbon.device.mgt.core.notification.mgt.NotificationManagementServiceImpl;
import org.wso2.carbon.device.mgt.core.notification.mgt.dao.NotificationManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerImpl;
@ -270,6 +272,10 @@ public class DeviceManagementServiceComponent {
bundleContext.registerService(DeviceAccessAuthorizationService.class.getName(),
deviceAccessAuthorizationService, null);
/* Registering Geo Service */
GeoService geoService = new GeoServcieManagerImpl();
bundleContext.registerService(GeoService.class.getName(), geoService, null);
/* Registering App Management service */
try {
AppManagementConfigurationManager.getInstance().initConfig();

@ -152,7 +152,8 @@ public class OperationMappingDAOImpl implements OperationMappingDAO {
"DM_DEVICE D ON E.DEVICE_ID = D.ID WHERE " +
"OP.STATUS IN ('"+ Operation.Status.PENDING.name() + "','" + Operation.Status.REPEATED.name() + "') " +
"AND OP.CREATED_TIMESTAMP BETWEEN ? AND ? AND E.STATUS IN ('" + EnrolmentInfo.Status.ACTIVE.name() +
"','" + EnrolmentInfo.Status.UNREACHABLE.name() + "') AND D.DEVICE_TYPE_ID = ? GROUP BY ENROLMENT_ID";
"','" + EnrolmentInfo.Status.UNREACHABLE.name() + "') AND D.DEVICE_TYPE_ID = ? GROUP BY ENROLMENT_ID," +
" D.DEVICE_IDENTIFICATION, E.STATUS, E.TENANT_ID";
stmt = conn.prepareStatement(sql);
stmt.setLong(1, maxDuration);
stmt.setLong(2, minDuration);

@ -284,7 +284,8 @@ public class SQLServerOperationDAOImpl extends GenericOperationDAOImpl {
stmt = conn.prepareStatement(sql);
stmt.setString(1, opStatus.toString());
stmt.setString(2, pushNotificationStatus.toString());
stmt.setInt(3, limit);
stmt.setInt(3, 0);
stmt.setInt(4, limit);
rs = stmt.executeQuery();
while (rs.next()) {
int tenantID = rs.getInt("TENANT_ID");

@ -337,23 +337,25 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
return false;
}
try {
int tenantId = this.getTenantId();
Device device = this.getDevice(deviceId, false);
if (device == null) {
if (log.isDebugEnabled()) {
log.debug("Device not found for id '" + deviceId.getId() + "'");
}
return false;
int tenantId = this.getTenantId();
Device device = this.getDevice(deviceId, false);
if (device == null) {
if (log.isDebugEnabled()) {
log.debug("Device not found for id '" + deviceId.getId() + "'");
}
return false;
}
if (device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.REMOVED)) {
if (log.isDebugEnabled()) {
log.debug("Device has already disenrolled : " + deviceId.getId() + "'");
}
return false;
if (device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.REMOVED)) {
if (log.isDebugEnabled()) {
log.debug("Device has already disenrolled : " + deviceId.getId() + "'");
}
return true;
}
try {
device.getEnrolmentInfo().setDateOfLastUpdate(new Date().getTime());
device.getEnrolmentInfo().setStatus(EnrolmentInfo.Status.REMOVED);
DeviceManagementDAOFactory.beginTransaction();

@ -92,13 +92,19 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
operations = this.getValidOperationNames(); //list operations for each device type
devices = deviceManagementProviderService.getAllDevices(deviceType, false);//list devices for each type
if (!devices.isEmpty()) {
for (String str : operations) {
CommandOperation operation = new CommandOperation();
operation.setEnabled(true);
operation.setType(Operation.Type.COMMAND);
operation.setCode(str);
deviceManagementProviderService.addOperation(deviceType, operation,
DeviceManagerUtil.getValidDeviceIdentifiers(devices));
if (operations != null) {
for (String str : operations) {
CommandOperation operation = new CommandOperation();
operation.setEnabled(true);
operation.setType(Operation.Type.COMMAND);
operation.setCode(str);
deviceManagementProviderService.addOperation(deviceType, operation,
DeviceManagerUtil.getValidDeviceIdentifiers(devices));
}
} else {
if (log.isDebugEnabled()) {
log.debug("No operations are available.");
}
}
} else {
if (log.isDebugEnabled()) {

@ -53,7 +53,6 @@ public class DeviceTaskManagerServiceImpl implements DeviceTaskManagerService {
log.info("Task adding for " + deviceType);
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
taskService.registerTaskType(TASK_TYPE);

@ -21,6 +21,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
@ -411,6 +413,17 @@ public final class DeviceManagerUtil {
return limit;
}
public static boolean isPublishLocationOperationResEnabled() throws DeviceManagementException {
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig();
if (deviceManagementConfig != null) {
return deviceManagementConfig.getGeoLocationConfiguration().getPublishLocationOperationResponse();
} else {
throw new DeviceManagementException("Device-Mgt configuration has not initialized. Please check the " +
"cdm-config.xml file.");
}
}
public static DeviceIDHolder validateDeviceIdentifiers(List<DeviceIdentifier> deviceIDs) {
List<String> errorDeviceIdList = new ArrayList<String>();
@ -463,6 +476,18 @@ public final class DeviceManagerUtil {
return Caching.getCacheManagerFactory().getCacheManager(DeviceManagementConstants.DM_CACHE_MANAGER);
}
public static EventsPublisherService getEventPublisherService() {
PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
EventsPublisherService eventsPublisherService =
(EventsPublisherService) ctx.getOSGiService(EventsPublisherService.class, null);
if (eventsPublisherService == null) {
String msg = "Event Publisher service has not initialized.";
log.error(msg);
throw new IllegalStateException(msg);
}
return eventsPublisherService;
}
public static void initializeDeviceCache() {
DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
int deviceCacheExpiry = config.getDeviceCacheConfiguration().getExpiryTime();

@ -0,0 +1,20 @@
/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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);
@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);
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==false and id == "$deviceId"]#geodashboard:subscribe()
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, "This device is outside $areaName area!!!" as information
insert into dataOut;
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=false and id == "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information
insert into dataOut;

@ -0,0 +1,140 @@
/* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-Proximity_alert')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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 );
@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 );
@IndexBy('id')
define table ProximityTable(id string, timeStamp long);
@IndexBy('id')
define table AlertsTable(id string , proximityWith string, eventId string);
from dataIn#geodashboard:subscribe()
select id, latitude, longitude, timeStamp, type, speed, heading, eventId
insert into initialStream;
from initialStream[type == 'STOP']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream;
from initialStream[type != 'STOP']
select *
insert into objectInitialStream;
from objectInitialStream#geo:proximity(id,longitude,latitude, $proximityDistance)
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith
insert into proxymityStream;
from proxymityStream[AlertsTable.id == proxymityStream.id in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable
insert into innerStreamOne;
from proxymityStream[not(AlertsTable.id == proxymityStream.id in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable
insert into innerStreamOne;
from proxymityStream[AlertsTable.id == proxymityStream.proximityWith in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable
insert into innerStreamSeven;
from proxymityStream[not(AlertsTable.id == proxymityStream.proximityWith in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable
insert into innerStreamSeven;
from innerStreamOne[inCloseProximity == true AND not(inAlertTable)]
select id,str:concat(",",proximityWith) as proximityWith , eventId
insert into AlertsTable;
from innerStreamSeven[inCloseProximity == true AND not(inAlertTable)]
select proximityWith as id,str:concat(",",id) as proximityWith , eventId
insert into AlertsTable;
from innerStreamOne[innerStreamOne.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamOne.id == AlertsTable.id
select innerStreamOne.id as id, str:concat(",", innerStreamOne.proximityWith, AlertsTable.proximityWith) as proximityWith, innerStreamOne.eventId as eventId
insert into updateStream;
from innerStreamSeven[innerStreamSeven.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamSeven.proximityWith == AlertsTable.id
select innerStreamSeven.proximityWith as id, str:concat(",", innerStreamSeven.id, AlertsTable.proximityWith) as proximityWith, innerStreamSeven.eventId as eventId
insert into updateStream;
from innerStreamOne[innerStreamOne.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamOne.id == AlertsTable.id
select innerStreamOne.id as id, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamOne.proximityWith), "") as proximityWith, innerStreamOne.eventId as eventId
insert into updateStream;
from innerStreamSeven[innerStreamSeven.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamSeven.proximityWith == AlertsTable.id
select innerStreamSeven.proximityWith as id, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamSeven.id), "") as proximityWith, innerStreamSeven.eventId as eventId
insert into updateStream;
from updateStream
select *
update AlertsTable
on id== AlertsTable.id;
from updateStream[proximityWith == ""]
delete AlertsTable
on id== AlertsTable.id;
from objectInitialStream[AlertsTable.id == objectInitialStream.id in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId, true as inAlertTable
insert into publishStream;
from objectInitialStream[not(AlertsTable.id == objectInitialStream.id in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId, false as inAlertTable
insert into publishStream;
from publishStream[inAlertTable == true]#window.length(0) join AlertsTable
on publishStream.id== AlertsTable.id
select publishStream.id as id, publishStream.latitude as latitude, publishStream.longitude as longitude, publishStream.timeStamp as timeStamp, publishStream.type as type, publishStream.speed as speed, publishStream.heading as heading, publishStream.eventId as eventId, AlertsTable.proximityWith as proximityInfo
insert into innerStreamTwo;
from publishStream[inAlertTable == false]
delete ProximityTable on ProximityTable.id==id;
from publishStream[inAlertTable == false]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream;
from innerStreamTwo[ProximityTable.id == innerStreamTwo.id in ProximityTable]
insert into innerStreamThree;
from innerStreamThree#window.length(0) join ProximityTable
on innerStreamThree.id == ProximityTable.id
select innerStreamThree.id , innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId, ProximityTable.timeStamp as storedTime, innerStreamThree.proximityInfo as proximityInfo
insert into innerStreamFour;
from innerStreamFour[(timeStamp - storedTime) >= $proximityTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,proximityInfo,"true" as isProximity
insert into dataOutStream;
from innerStreamFour[(timeStamp - storedTime) < $proximityTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , proximityInfo ,"false" as isProximity
insert into dataOutStream;
from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)]
select innerStreamTwo.id, innerStreamTwo.timeStamp
insert into ProximityTable;
from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream;
from dataOutStream[isProximity == 'true']
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,"WARNING" as state,str:concat("Proximity with "," ",proximityInfo) as information
insert into dataOut;
from dataOutStream[isProximity == 'false']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"NORMAL" as state,"" as information
insert into dataOut;

@ -0,0 +1,20 @@
/* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-Speed---$deviceId_alert')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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);
@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);
from dataIn[speed >= $speedAlertValue and id == "$deviceId"]#geodashboard:subscribe()
select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "ALERTED" as state, "This device movement is not normal!!" as information
insert into dataOut;
from dataIn[speed < $speedAlertValue and id == "$deviceId"]
select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "NORMAL" as state, "This device movement is normal" as information
insert into dataOut;

@ -0,0 +1,89 @@
/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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);
@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);
@IndexBy('id')
define table StationeryTable(id string, timeStamp long);
@IndexBy('id')
define table AlertsTable(id string, stationary bool);
from dataIn#geodashboard:subscribe()
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin
insert into innerStreamOne;
from innerStreamOne[isWithin == false]
delete StationeryTable on StationeryTable.id==id;
from innerStreamOne[isWithin == false]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream;
from innerStreamOne[isWithin == true]#geo:stationary(id,longitude,latitude, $fluctuationRadius)
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,stationary
insert into innerStreamTwo;
from innerStreamTwo[innerStreamTwo.stationary == true]
select innerStreamTwo.id, innerStreamTwo.stationary
insert into AlertsTable;
from innerStreamTwo[innerStreamTwo.stationary == false]
delete AlertsTable on AlertsTable.id==id;
from innerStreamTwo[innerStreamTwo.stationary == false]
delete StationeryTable on StationeryTable.id==id;
from innerStreamOne[isWithin == true AND not(AlertsTable.id == innerStreamOne.id in AlertsTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream;
from innerStreamOne[isWithin == true AND AlertsTable.id == innerStreamOne.id in AlertsTable]
insert into innerStreamThree;
from innerStreamThree#window.length(0) join AlertsTable
on innerStreamThree.id == AlertsTable.id
select innerStreamThree.id , innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId
insert into innerStreamFour;
from innerStreamFour[not(StationeryTable.id == innerStreamFour.id in StationeryTable)]
select innerStreamFour.id, innerStreamFour.timeStamp
insert into StationeryTable;
from innerStreamOne[isWithin == true AND not(StationeryTable.id == innerStreamOne.id in StationeryTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream;
from innerStreamOne[isWithin == true AND StationeryTable.id == innerStreamOne.id in StationeryTable]
insert into innerStreamFive;
from innerStreamFive#window.length(0) join StationeryTable
on innerStreamFive.id == StationeryTable.id
select innerStreamFive.id , innerStreamFive.latitude, innerStreamFive.longitude,innerStreamFive.timeStamp, innerStreamFive.type, innerStreamFive.speed, innerStreamFive.heading ,innerStreamFive.eventId, StationeryTable.timeStamp as storedTime
insert into innerStreamSix;
from innerStreamSix[(timeStamp - storedTime) >= $stationeryTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"true" as isStationary
insert into dataOutStream;
from innerStreamSix[(timeStamp - storedTime) < $stationeryTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"false" as isStationary
insert into dataOutStream;
from dataOutStream[isStationary == 'true']
select id ,latitude, longitude,timeStamp, type, speed, heading ,eventId ,"ALERTED" as state, "This device is in $stationeryName area!!!" as information
insert into dataOut;
from dataOutStream[isStationary == 'false']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"NORMAL" as state,"" as information
insert into dataOut;

@ -0,0 +1,17 @@
/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* define streams/tables and write queries here ... */
@Import('rawGeoStream:1.0.0')
define stream dataIn (id string, timeStamp long, geometry string, state string, information string);
@Export('AlertsNotifications:1.0.0')
define stream dataOut (id string, state string, information string, timeStamp long, latitude double, longitude double);
from dataIn[geo:intersects(geometry, "$geoFenceGeoJSON")==true and geodashboard:needToNotify(id, str:concat(information, state), "sendFirst") == true and id == $deviceId]
select id, state, str:concat("Traffic alert in $areaName. State: ", state, " ", information) as information, timeStamp, 0.0 as latitude, 0.0 as longitude
insert into dataOut

@ -0,0 +1,20 @@
/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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);
@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);
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==true and id == "$deviceId"]#geodashboard:subscribe()
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, "This device is in $areaName restricted area!!!" as information
insert into dataOut;
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=true and id == "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information
insert into dataOut;

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

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

@ -147,7 +147,8 @@
"perm:device-types:events",
"perm:device-types:events:view",
"perm:admin:device-type",
"perm:device:enroll"
"perm:device:enroll",
"perm:geo-service:analytics"
],
"isOAuthEnabled": true,
"backendRestEndpoints": {

@ -39,17 +39,17 @@ deviceModule = function () {
privateMethods.callBackend = function (url, method) {
if (constants["HTTP_GET"] == method) {
return serviceInvokers.XMLHttp.get(url,
function (backendResponse) {
var response = {};
response.content = backendResponse.responseText;
if (backendResponse.status == 200) {
response.status = "success";
} else if (backendResponse.status == 400 || backendResponse.status == 401 ||
backendResponse.status == 404 || backendResponse.status == 500) {
response.status = "error";
}
return response;
}
function (backendResponse) {
var response = {};
response.content = backendResponse.responseText;
if (backendResponse.status == 200) {
response.status = "success";
} else if (backendResponse.status == 400 || backendResponse.status == 401 ||
backendResponse.status == 404 || backendResponse.status == 500) {
response.status = "error";
}
return response;
}
);
} else {
log.error("Runtime error : This method only support HTTP GET requests.");
@ -70,35 +70,22 @@ deviceModule = function () {
throw constants["ERRORS"]["USER_NOT_FOUND"];
}
var userName = carbonUser.username + "@" + carbonUser.domain;
var locationDataSet = [];
switch (deviceType) {
case 'android':
locationDataSet = batchProvider.getData(userName, deviceId, deviceType);
break;
case 'android_sense':
locationDataSet = batchProvider.getData(userName, deviceId, deviceType);
break;
var locationHistory = [];
try {
var fromDate = new Date();
fromDate.setHours(fromDate.getHours() - 2);
var toDate = new Date();
var serviceUrl = devicemgtProps["httpsURL"] + '/api/device-mgt/v1.0/geo-services/stats/' + deviceType + '/' + deviceId;
serviceInvokers.XMLHttp.get(serviceUrl,
function (backendResponse) {
if (backendResponse.status === 200 && backendResponse.responseText) {
locationHistory = JSON.parse(backendResponse.responseText);
}
});
} catch (e) {
log.error(e.message, e);
}
var locationData = [];
var locationTimeData = [];
if (locationDataSet != null) {
for (var i = 0; i < locationDataSet.length; i++) {
var gpsReading = {};
var gpsReadingTimes = {};
gpsReading.lat = locationDataSet[i].latitude;
gpsReading.lng = locationDataSet[i].longitude;
if (deviceType == "android") {
gpsReadingTimes.time = locationDataSet[i].timeStamp;
} else {
gpsReadingTimes.time = locationDataSet[i].meta_timestamp;
}
locationData.push(gpsReading);
locationTimeData.push(gpsReadingTimes);
}
}
var locationInfo = {};
try {
var url = devicemgtProps["httpsURL"] + "/api/device-mgt/v1.0/devices/" + deviceType + "/" + deviceId + "/location";
@ -111,14 +98,12 @@ deviceModule = function () {
locationInfo.latitude = device.latitude;
locationInfo.longitude = device.longitude;
locationInfo.updatedOn = device.updatedTime;
}
});
} catch (e) {
log.error(e.message, e);
}
var utility = require('/app/modules/utility.js')["utility"];
try {
utility.startTenantFlow(carbonUser);
@ -193,27 +178,45 @@ deviceModule = function () {
}
}
}
if (device["deviceInfo"]) {
filteredDeviceData["latestDeviceInfo"] = device["deviceInfo"];
} else {
filteredDeviceData["latestDeviceInfo"] = {};
filteredDeviceData["latestDeviceInfo"]["location"] = {};
}
//location related verification and modifications
// adding the location histry for the movement path.
var locationHistory = {};
locationHistory.locations = locationData;
locationHistory.times = locationTimeData;
filteredDeviceData["locationHistory"] = locationHistory;
//checking for the latest location information.
if (filteredDeviceData.latestDeviceInfo.location && locationInfo) {
var infoDate = new Date(filteredDeviceData.latestDeviceInfo.location.updatedTime);
var locationDate = new Date(locationInfo.updatedOn);
if (infoDate < locationDate) {
filteredDeviceData.latestDeviceInfo.location.longitude = locationInfo.longitude;
filteredDeviceData.latestDeviceInfo.location.latitude = locationInfo.latitude;
}
//location related verification and modifications
// adding the location histry for the movement path.
filteredDeviceData["locationHistory"] = locationHistory;
//checking for the latest location information based on historical data.
if (locationHistory) {
var infoDate;
var locationDate;
var historicalLatestLoc = locationHistory[locationHistory.length - 1];
if (historicalLatestLoc && filteredDeviceData.latestDeviceInfo && filteredDeviceData.latestDeviceInfo.location) {
infoDate = new Date(filteredDeviceData.latestDeviceInfo.location.updatedTime);
locationDate = new Date(historicalLatestLoc.values.timeStamp);
}
if (infoDate < locationDate || filteredDeviceData.latestDeviceInfo.length === 0) {
filteredDeviceData.latestDeviceInfo.location = {};
filteredDeviceData.latestDeviceInfo.location.longitude = historicalLatestLoc.values.longitude;
filteredDeviceData.latestDeviceInfo.location.latitude = historicalLatestLoc.values.latitude;
filteredDeviceData.latestDeviceInfo.location.updatedTime = historicalLatestLoc.values.timeStamp;
}
}
//checking for the latest location information.
if (filteredDeviceData.latestDeviceInfo.location && locationInfo) {
var infoDate = new Date(filteredDeviceData.latestDeviceInfo.location.updatedTime);
var locationDate = new Date(locationInfo.updatedOn);
if (infoDate < locationDate) {
filteredDeviceData.latestDeviceInfo.location.longitude = locationInfo.longitude;
filteredDeviceData.latestDeviceInfo.location.latitude = locationInfo.latitude;
filteredDeviceData.latestDeviceInfo.location.updatedTime = locationInfo.updatedOn;
}
}
response["content"] = filteredDeviceData;
response["status"] = "success";
@ -246,10 +249,10 @@ deviceModule = function () {
var url;
if (uiPermissions.LIST_DEVICES) {
url = devicemgtProps["httpsURL"] +
devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/devices?offset=0&limit=1";
devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/devices?offset=0&limit=1";
} else if (uiPermissions.LIST_OWN_DEVICES) {
url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
"/devices?offset=0&limit=1&user=" + carbonUser.username;
"/devices?offset=0&limit=1&user=" + carbonUser.username;
} else {
log.error("Access denied for user: " + carbonUser.username);
return -1;
@ -339,7 +342,7 @@ deviceModule = function () {
publicMethods.getDevices = function (userName) {
var url = devicemgtProps["httpsURL"] +
devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/devices";
devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/devices";
return serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
var devices = JSON.parse(responsePayload.responseText).devices;

@ -19,6 +19,8 @@
{{#zone "content"}}
{{#if deviceFound}}
{{#if isAuthorized}}
<span id="logged-in-user" class="hidden" data-username="{{@user.username}}" data-domain="{{@user.domain}}"
data-tenant-id="{{@user.tenantId}}" data-iscloud="{{isCloud}}"></span>
{{#defineZone "device-details-header"}}
<h1 class="page-sub-title device-id device-select" data-deviceid="{{device.deviceIdentifier}}"
data-type="{{device.type}}">

@ -34,6 +34,7 @@ function onRequest(context) {
var viewModel = {};
if (filteredDeviceData["type"]) {
viewModel["deviceType"] = filteredDeviceData["type"];
viewModel["type"] = filteredDeviceData["type"];
viewModel.isNotWindows = true;
if (viewModel["deviceType"] == "windows") {
viewModel.isNotWindows = false;

@ -0,0 +1,715 @@
{{!
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.
}}
{{#zone "topCss"}}
{{css "css/app.css" combine=false}}
{{css "css/map.css" combine=false}}
{{css "css/leaflet.css" combine=false}}
{{css "css/L.Control.Locate.css" combine=false}}
{{css "css/MarkerCluster.Default.css" combine=false}}
{{css "css/leaflet_fullscreen/leaflet.fullscreen.css" combine=false}}
{{css "css/leaflet/leaflet.draw.css" combine=false}}
{{css "css/d3/c3.css" combine=false}}
{{css "css/bootstrap-datepicker.min.css" combine=false}}
<style>
.datepicker-inline {
margin:0 auto;
}
</style>
{{/zone}}
{{#zone "content"}}
<div id="alerts-common"></div>
{{/zone}}
<span id="geo-charts" data-ws-endpoint="{{wsEndpoint}}" data-ws-token="{{wsToken}}" data-geo-public-uri="{{@unit.publicUri}}"
data-device-location="{{lastLocation}}"></span>
<div class="map-wrapper">
{{#unless @unit.params.hideSearch}}
<div class="navbar-collapse collapse" style="display:inline-block;">
<ul class="nav navbar-nav-right">
<li>
<form id="mapSearch" class="navbar-form" role="search"
onsubmit="focusOnSpatialObject($(this).find('#searchbox').val());return false;">
<div class="form-group has-feedback">
<input autofocus="true" id="searchbox" type="text" placeholder="Search"
class="form-control typeahead">
<span id="searchicon" class="fa fa-search form-control-feedback"></span>
</div>
<input style="visibility: hidden; position: fixed;" type="submit"/>
</form>
</li>
</ul>
</div>
{{/unless}}
<div id="" style="height: 93vh;">
<!-- Sidebar -->
<div id="map"></div>
</div>
<div id="predictionResults" style="background: darkgray;display: none;border-radius: 13px;height: 94%;padding: 0"
class="col-md-2 pull-right">
<div class="panel-heading text-center">
<h4> Prediction Results For: <span id="predictionResultsID" class="text-info"></span>
<i id="objectInfoCloseButton" class="fa fa-times pull-right"
onclick="$('#predictionResults').animate({width: ['toggle','swing']},200);toggeled = false;spatialObject = currentSpatialObjects[selectedSpatialObject];spatialObject.removePath();spatialObject.marker.closePopup();selectedSpatialObject = null;">
</i>
</h4>
</div>
<br>
<div class="panel panel-default" style="overflow: auto;box-shadow: 0 0 8px 0 #635749">
<div class="panel-heading text-center"><h4>Prediction</h4>
</div>
<br>
<div class="panel-body">
<div style="max-height: 100%;margin: 0;border: none;margin-left: -25px" id="prediction_chart_div"></div>
</div>
</div>
</div>
<div id="loading">
<div class="loading-indicator">
<div class="progress progress-striped active">
<div class="progress-bar progress-bar-info" style="width: 100%"></div>
</div>
</div>
</div>
<div class="modal" id="aboutModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Welcome to the BootLeaf template!</h4>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="aboutTabs">
<li class="active"><a href="#about" data-toggle="tab"><i class="fa fa-question-circle"></i>&nbsp;About
the project</a></li>
<li><a href="#contact" data-toggle="tab"><i class="fa fa-envelope"></i>&nbsp;Contact us</a></li>
<li><a href="#disclaimer" data-toggle="tab"><i class="fa fa-exclamation-circle"></i>&nbsp;Disclaimer</a>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-globe"></i>&nbsp;Metadata
<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#boroughs-tab" data-toggle="tab">Boroughs</a></li>
<li><a href="#subway-lines-tab" data-toggle="tab">Subway Lines</a></li>
<li><a href="#theaters-tab" data-toggle="tab">Theaters</a></li>
<li><a href="#museums-tab" data-toggle="tab">Museums</a></li>
</ul>
</li>
</ul>
<div class="tab-content" id="aboutTabsContent" style="padding-top: 10px;">
<div class="tab-pane fade active in" id="about">
<p>A simple, responsive template for building web mapping applications with <a
href="http://getbootstrap.com/">Bootstrap 3</a>, <a href="http://leafletjs.com/"
target="_blank">Leaflet</a>, and <a
href="http://twitter.github.io/typeahead.js/" target="_blank">typeahead.js</a>. Open
source, MIT licensed, and available on <a href="https://github.com/bmcbride/bootleaf"
target="_blank">GitHub</a>.</p>
<div class="panel panel-primary">
<div class="panel-heading">Features</div>
<ul class="list-group">
<li class="list-group-item">Fullscreen mobile-friendly map template with responsive
navbar and modal placeholders
</li>
<li class="list-group-item">jQuery loading of external GeoJSON files</li>
<li class="list-group-item">Logical multiple layer marker clustering via the <a
href="https://github.com/Leaflet/Leaflet.markercluster" target="_blank">leaflet
marker cluster plugin</a></li>
<li class="list-group-item">Elegant client-side multi-layer feature search with
autocomplete using <a href="http://twitter.github.io/typeahead.js/" target="_blank">typeahead.js</a>
</li>
<li class="list-group-item">Responsive sidebar feature list with sorting and filtering
via <a href="http://listjs.com/" target="_blank">list.js</a></li>
<li class="list-group-item">Marker icons included in grouped layer control via the <a
href="https://github.com/ismyrnow/Leaflet.groupedlayercontrol" target="_blank">grouped
layer control plugin</a></li>
</ul>
</div>
</div>
<div id="disclaimer" class="tab-pane fade text-danger">
<p>The data provided on this site is for informational and planning purposes only.</p>
<p>Absolutely no accuracy or completeness guarantee is implied or intended. All information on
this map is subject to such variations and corrections as might result from a complete title
search and/or accurate field survey.</p>
</div>
<div class="tab-pane fade" id="contact">
<form id="contact-form">
<div class="well well-sm">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label for="first-name">First Name:</label>
<input type="text" class="form-control" id="first-name">
</div>
<div class="form-group">
<label for="last-email">Last Name:</label>
<input type="text" class="form-control" id="last-email">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="text" class="form-control" id="email">
</div>
</div>
<div class="col-md-8">
<label for="message">Message:</label>
<textarea class="form-control" rows="8" id="message"></textarea>
</div>
<div class="col-md-12">
<p>
<button type="submit" class="btn btn-primary pull-right"
data-dismiss="modal">Submit
</button>
</p>
</div>
</div>
</div>
</form>
</div>
<div class="tab-pane fade" id="boroughs-tab">
<p>Borough data courtesy of <a
href="http://www.nyc.gov/html/dcp/html/bytes/meta_dis_nyboroughwi.shtml"
target="_blank">New York City Department of City Planning</a></p>
</div>
<div class="tab-pane fade" id="subway-lines-tab">
<p><a href="http://spatialityblog.com/2010/07/08/mta-gis-data-update/#datalinks"
target="_blank">MTA Subway data</a> courtesy of the <a
href="http://www.urbanresearch.org/about/cur-components/cuny-mapping-service"
target="_blank">CUNY Mapping Service at the Center for Urban Research</a></p>
</div>
<div class="tab-pane fade" id="theaters-tab">
<p>Theater data courtesy of <a
href="https://data.cityofnewyork.us/Recreation/Theaters/kdu2-865w" target="_blank">NYC
Department of Information & Telecommunications (DoITT)</a></p>
</div>
<div class="tab-pane fade" id="museums-tab">
<p>Museum data courtesy of <a
href="https://data.cityofnewyork.us/Recreation/Museums-and-Galleries/sat5-adpb"
target="_blank">NYC Department of Information & Telecommunications (DoITT)</a></p>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal" id="attributionModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 id = "title" class="modal-title">
WSO2 Geo Dashboard
</h4>
</div>
<div class="modal-body">
<div id="attribution"></div>
</div>
</div>
</div>
</div>
<div class="modal" id="addTileServer" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content" style="width:50%; margin:0 auto;">
<div class="modal-header"
style="cursor: move;background: #f9f9f9;-webkit-box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);-moz-box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
&lt;!&ndash; TODO: Trigger bootstrap tooltip $('#aboutTileUrl').tooltip(); to enable tooltip &ndash;&gt;
Add tiler server URL <sup id="aboutTileUrl" style="cursor: pointer;" data-toggle="tooltip"
title="What is a tile URL?"><i class="fa fa-question" style="color: #39F;"
data-toggle="collapse"
data-target="#collapseOne"></i></sup>
</h4>
</div>
<div class="modal-body">
<div id="urlInput">
<div style="height: 0px;" id="collapseOne" class="panel-collapse collapse">
<div class="panel-body">
<p>A string of the following form:</p>
<pre><code class="javascript"><span class="string">'http://{s}.somedomain.com/blabla/{z}/{x}/{y}.png'</span></code></pre>
<p><code class="javascript">{s}</code> means one of the available subdomains (used
sequentially to help with browser parallel requests per domain limitation; subdomain
values are specified in options; <code class="javascript">a</code>, <code
class="javascript">b</code> or <code class="javascript">c</code> by default, can
be omitted), <code class="javascript">{z}</code> — zoom level, <code class="javascript">{x}</code>
and <code class="javascript">{y}</code> — tile coordinates.</p>
<p>You can use custom keys in the template, which will be <a
href="#util-template">evaluated</a> from TileLayer options, like this:</p>
<pre><code class="javascript">L.tileLayer(<span class="string">'http://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png'</span>,
{foo: <span class="string">'bar'</span>});</code></pre>
</div>
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon"><i class="fa fa-italic"></i></span>
<input autofocus="enable" id="tileName" type="text" class="form-control"
placeholder="Tile URL name">
</div>
<br>
<div class="input-group input-group-sm">
<span class="input-group-addon"><i class="fa fa-globe"></i></span>
<input id="tileUrl" class="form-control" type="text"
placeholder="http://{s}.somedomain.com/blabla/{z}/{x}/{y}.png">
<span class="input-group-btn">
<button class="btn btn-info" type="button" onclick="addTileUrl()"><i class="fa fa-plus"></i>
</button>
</span>
</div>
<br/>
<div class="panel panel-default" style="width: 80%;">
<div>
<h4 class="panel-title" style="font-size: 12px;line-height: 1.5;">
<button style="text-align: left;" class="btn btn-default btn-xs btn-block collapsed"
onclick="$('.fa-chevron-right').toggleClass('fa-rotate-90')"
data-toggle="collapse" data-parent="#accordion" href="#tileUrlOptions">
<i class="fa fa-chevron-right"></i> Options
</button>
</h4>
</div>
<div style="height: 0px;" id="tileUrlOptions" class="panel-collapse collapse">
<div class="panel-body">
<div class="input-group input-group-sm col-sm-9">
<small class="text-primary">
<label class="col-sm-2 control-label" for="sub_domains">Sub-domains</label>
</small>
<input id="sub_domains" type="text" class="form-control"
placeholder="Enter sub-domains in CSV format">
</div>
<br/>
<div class="input-group input-group-sm col-sm-9">
<small class="text-primary">
<label class="col-sm-9 control-label" for="maxzoom">Max zoom level</label>
</small>
<input id="maxzoom" type="text" class="form-control"
placeholder="Number between(around) 1~19">
</div>
<br/>
<div class="input-group input-group-sm col-sm-9">
<small class="text-primary">
<label class="col-sm-2 control-label" for="data_attribution">Attribution</label>
</small>
<input id="data_attribution" type="text" class="form-control"
placeholder="Enter attribution">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal" id="addWmsUrl" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content" style="width:50%; margin:0 auto;">
<div class="modal-header"
style="cursor: move;background: #f9f9f9;-webkit-box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);-moz-box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
<sup id="aboutWms" style="cursor: pointer;" data-toggle="tooltip"
title="What WMS end-point"><i class="fa fa-question"
style="color: #39F;"
data-toggle="collapse"
data-target="#wmsOverview"></i></sup>
</h4>
</div>
<div class="modal-body">
<div>
<div style="height: 0px;" id="wmsOverview" class="panel-collapse collapse">
<div class="panel-body">
The OpenGIS® Web Map Service Interface Standard (WMS) provides a simple HTTP interface for
requesting geo-registered map images from one or more distributed geospatial databases.
A WMS request defines the geographic layer(s) and area of interest to be processed.
The response to the request is one or more geo-registered map images (returned as JPEG, PNG,
etc) that can be displayed in a browser application.
The interface also supports the ability to specify whether the returned images should be
transparent so that layers from multiple servers can be combined or not.
</div>
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon"><i class="fa fa-italic"></i></span>
<input autofocus="enable" id="serviceName" type="text" class="form-control"
placeholder="Service provider name">
</div>
<br>
<div class="input-group input-group-sm">
<span class="input-group-addon"><i class="fa fa-align-justify"></i></span>
<input autofocus="enable" id="layers" type="text" class="form-control"
placeholder="Service layers as comma seperated values">
</div>
<br>
<div class="input-group input-group-sm">
<span class="input-group-addon">V.</span>
<input autofocus="enable" id="wmsVersion" type="text" class="form-control"
placeholder="WMS version (i.e: 1.1.1 or 1.3.0)">
</div>
<br>
<div class="input-group input-group-sm">
<span class="input-group-addon"><i class="fa fa-globe"></i></span>
<input id="serviceEndPoint" class="form-control" type="text"
placeholder="http(s)://sedac.ciesin.columbia.edu/geoserver/wms">
<span class="input-group-btn">
<button class="btn btn-info" type="button" onclick="addWmsEndPoint()"><i
class="fa fa-plus"></i>
</button>
</span>
</div>
<br/>
<div class="panel panel-default" style="width: 80%;">
<div>
<h4 class="panel-title" style="font-size: 12px;line-height: 1.5;">
<button style="text-align: left;" class="btn btn-default btn-xs btn-block collapsed"
onclick="$('.fa-chevron-right').toggleClass('fa-rotate-90')"
data-toggle="collapse" data-parent="#accordion" href="#wmsOptions">
<i class="fa fa-chevron-right"></i> Options
</button>
</h4>
</div>
<div style="height: 0px;" id="wmsOptions" class="panel-collapse collapse">
<div class="panel-body">
<div class="input-group input-group-sm col-sm-11">
<small class="text-primary">
<label class="col-sm-6 control-label" for="outputFormat">Output format</label>
</small>
<input id="outputFormat" type="text" class="form-control"
placeholder="Output format (i.e: image/png, image/jpeg, image/svg)">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal" id="commonModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
<div class="modal" id="editWithinGeoJSON" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
</h4>
<div class="col-lg-5 col-md-6 col-centered">
<h4>
Adding GeoJson
<br>
</h4>
</div>
</div>
<div class="modal-body">
<div class="col-lg-8 col-md-8 col-centered">
<div>
<label for="importGeoJsonFile">Import GeoJson</label>
<input id="importGeoJsonFile" type="file">
<hr />
<label for="enterGeoJson">Enter GeoJson</label>
<textarea id="enterGeoJson" class="form-control" rows="10"></textarea>
</div>
<div class="pull-right">
<button id="updateGeoJson" class="btn btn-primary" onclick="importGeoJson()">Import</button>
<button type="button" class="btn btn-default" onclick="closeAll()">Cancel</button>
<br />
<br />
</div>
</div>
</div>
</div>
</div>
</div>
<div style="display: none">
<div id="markerPopup" class="popover top">
<div class="arrow"></div>
<h3 class="popover-title">ID <span id="objectId"></span></h3>
<div class="popover-content">
<h6>Information</h6>
<p id="information" class="bg-primary" style="margin: 0px;padding: 0px;"></p>
<h6>Speed<span class="label label-primary pull-right"><span id="speed"></span> km/h</span></h6>
<h6>Heading<span id="heading" class="label label-primary pull-right"></span></h6>
<button type="button" class="btn btn-info btn-xs" onClick="toggleSpeedGraph();return false;">Speed Graph</button>
<button type="button" class="btn btn-info btn-xs" onClick="focusOnRecentHistorySpatialObject();return false;">Recent History</button>
<button type="button" class="btn btn-info btn-xs" onClick="popupDateRange();">Full History</button>
</div>
</div>
<div id="dateRangePopup">
<div>
<label> From: <input id="timeFrom" type="text"> </label>
<label> To: <input id="timeTo" type="text"> </label>
<button type="button" class="btn btn-info btn-xs" onClick="focusOnHistorySpatialObject(document.getElementById('objectId').innerHTML, document.getElementById('timeFrom').value, document.getElementById('timeTo').value);return false;">Full History</button>
</div>
</div>
<div id="markerPopupStop" class="popover top">
<div class="arrow"></div>
<h3 class="popover-title">ID <span id="objectId"></span></h3>
<div class="popover-content">
<h6>Information</h6>
<p id="information" class="bg-primary" style="margin: 0px;padding: 0px;"></p>
</div>
</div>
<div id="areaPopup" class="popover top">
<div class="arrow"></div>
<h3 class="popover-title">ID <span id="objectId"></span></h3>
<div class="popover-content">
<h6>Severity</h6>
<p id="severity" class="bg-primary" style="margin: 0px;padding: 0px;"></p>
</div>
<div class="popover-content">
<h6>Information</h6>
<p id="information" class="bg-primary" style="margin: 0px;padding: 0px;"></p>
</div>
</div>
<div id="setWithinAlert">
<form role="form" style="width: auto;">
<div class="form-group">
<label class="text-primary" for="areaName">Fence name</label>
<input class="form-control" id="areaName" placeholder="Fence name" type="text">
<span class="help-block">Name of the selected area(i.e colombo)</span>
</div>
<div>
<div class="btn-group btn-group-sm btn-group-justified">
<div class="btn-group">
<button id="addWithinAlert" onclick="setWithinAlert($(this).attr('leaflet_id'))" type="button"
class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left"
title="Save selected area for alerts">Save
</button>
</div>
<div class="btn-group">
<button id="editGeoJson"
onclick="$('#editWithinGeoJSON #updateGeoJson').attr('leaflet_id',$(this).attr('leaflet_id'));$('#editWithinGeoJSON textarea').text(JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'));$('#editWithinGeoJSON').modal('toggle')"
type="button" class="btn btn-default btn-xs">Edit
</button>
</div>
<div class="btn-group">
<a id="exportGeoJson" download="geoJson.json" href="#"
onclick="exportToGeoJSON(this, JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'))"
class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="left"
title="Export selected area as a geoJson file">Export</a>
</div>
</div>
</div>
</form>
</div>
<div id="setExitAlert">
<form role="form" style="width: auto;">
<div class="form-group">
<label class="text-primary" for="areaName">Fence name</label>
<input class="form-control" id="areaName" placeholder="Fence name" type="text">
<span class="help-block">Name of the selected area(i.e colombo)</span>
</div>
<div>
<div class="btn-group btn-group-sm btn-group-justified">
<div class="btn-group">
<button id="addExitAlert" onclick="setExitAlert($(this).attr('leaflet_id'))" type="button"
class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left"
title="Save selected area for alerts">Save
</button>
</div>
<div class="btn-group">
<button id="editGeoJson"
onclick="$('#editExitGeoJSON #updateGeoJson').attr('leaflet_id',$(this).attr('leaflet_id'));$('#editExitGeoJSON textarea').text(JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'));$('#editExitGeoJSON').modal('toggle')"
type="button" class="btn btn-default btn-xs">Edit
</button>
</div>
<div class="btn-group">
<a id="exportGeoJson" download="geoJson.json" href="#"
onclick="exportToGeoJSON(this, JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'))"
class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="left"
title="Export selected area as a geoJson file">Export</a>
</div>
</div>
</div>
</form>
</div>
<div id="templateLoader"></div>
<div id="setStationeryAlert">
<form role="form" style="width: auto;">
<div class="form-group">
<label class="text-primary" for="areaName">Fence name</label>
<input class="form-control" id="areaName" placeholder="Stationery name" type="text">
<span class="help-block">Name of the selected area(i.e colombo)</span>
<label class="text-primary" for="fRadius">Fluctuation radius</label>
<input class="form-control" id="fRadius" onblur="reformatRadius(this.form.fRadius.value);" placeholder="m" type="text">
<label class="text-primary" for="time">Time</label>
<input class="form-control" id="time" placeholder="Seconds" type="text">
</div>
<div>
<div class="btn-group btn-group-sm btn-group-justified">
<div class="btn-group">
<button id="addStationeryAlert" onclick="setStationeryAlert($(this).attr('leaflet_id'))" type="button"
class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left"
title="Save selected area for alerts">Save
</button>
</div>
<div class="btn-group">
<button id="editGeoJson"
onclick="$('#editWithinGeoJSON #updateGeoJson').attr('leaflet_id',$(this).attr('leaflet_id'));$('#editWithinGeoJSON textarea').text(JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'));$('#editWithinGeoJSON').modal('toggle')"
type="button" class="btn btn-default btn-xs">Edit
</button>
</div>
<div class="btn-group">
<a id="exportGeoJson" download="geoJson.json" href="#"
onclick="exportToGeoJSON(this, JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'))"
class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="left"
title="Export selected area as a geoJson file">Export</a>
</div>
</div>
</div>
</form>
</div>
<div id="setTrafficAlert">
<form role="form" style="width: auto;">
<div class="form-group">
<label class="text-primary" for="areaName">Fence name</label>
<input class="form-control" id="areaName" placeholder="Area Name" type="text">
<span class="help-block">Name of the selected area(i.e colombo)</span>
</div>
<div>
<div class="btn-group btn-group-sm btn-group-justified">
<div class="btn-group">
<button id="addTrafficAlert" onclick="setTrafficAlert($(this).attr('leaflet_id'))" type="button"
class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left"
title="Save selected area for alerts">Save
</button>
</div>
<div class="btn-group">
<button id="editGeoJson"
onclick="$('#editTrafficGeoJSON #updateGeoJson').attr('leaflet_id',$(this).attr('leaflet_id'));$('#editTrafficGeoJSON textarea').text(JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'));$('#editTrafficGeoJSON').modal('toggle')"
type="button" class="btn btn-default btn-xs">Edit
</button>
</div>
<div class="btn-group">
<a id="exportGeoJson" download="geoJson.json" href="#"
onclick="exportToGeoJSON(this, JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'))"
class="btn btn-default btn-xs" data-toggle="tooltip" data-placement="left"
title="Export selected area as a geoJson file">Export</a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
{{#zone "bottomJs" }}
{{js "js/leaflet/leaflet.js" }}
{{js "js/leaflet/leaflet.markercluster.js" }}
{{js "js/leaflet/L.Control.Locate.js" }}
{{js "js/leaflet/L.Control.Focus.js" }}
{{js "js/leaflet/L.Control.GeoAlerts.js" }}
{{js "js/leaflet/leaflet.groupedlayercontrol.js" }}
{{js "js/leaflet/Leaflet.fullscreen.min.js" }}
{{js "js/leaflet/Marker.Rotate.js" }}
{{js "js/leaflet/leaflet.draw.js" }}
{{js "js/jquery/jquery-ui.min.js" }}
<!-- Leaflet plugins libries -->
{{js "js/firstTemp.js" }}
{{js "js/typeahead.bundle.min.js" }}
<!-- C3 charting library using D3 core -->
{{js "js/d3/d3.min.js" }}
{{js "js/d3/c3.min.js" }}
{{js "js/application_options.js" }}
{{js "js/secondTemp.js" }}
{{js "js/geo_remote.js" }}
{{js "js/show_alert_in_map.js" }}
{{js "js/app.js" }}
{{js "js/websocket.js" }}
{{js "js/geo_fencing.js" }}
<script type="text/javascript">
$(document).ready(function () {
var geoLocationLink = $(".initGeoLocationLink");
if (geoLocationLink) {
geoLocationLink.on('click', function () {
initializeGeoLocation()
});
{{#if showGeoFencingTools}}
var locationItems = geoLocationLink.closest('li');
var geoToolsMenu = $("<ul/>", {class: 'collapse list-group geo-tools active'}).appendTo(locationItems);
geoPublicUri = $("#geo-charts").data("geo-public-uri");
var realtTime = createGeoToolListItem('javascript:enableRealTime()',
'Return to Real Time View', 'fw fw-undo', geoToolsMenu);
realtTime.css("display", "none");
realtTime.attr("id", "realTimeShow");
createGeoToolListItem(geoPublicUri + '/assets/html_templates/modal/speed_alert.html',
'Set Speed Alert', 'glyphicon glyphicon-dashboard', geoToolsMenu);
createGeoToolListItem(geoPublicUri + '/assets/html_templates/modal/stationery_alert.html',
'Add Stationary Alert', 'glyphicon glyphicon-link', geoToolsMenu);
createGeoToolListItem(geoPublicUri + '/assets/html_templates/modal/within_alert.html',
'Add Geo Fence Enter Alert', 'glyphicon glyphicon-log-in', geoToolsMenu);
createGeoToolListItem(geoPublicUri + '/assets/html_templates/modal/exit_alert.html',
'Add Geo Fence Exit Alert', 'glyphicon glyphicon-log-out', geoToolsMenu);
{{/if}}
}
});
</script>
{{/zone}}

@ -0,0 +1,57 @@
/*
* 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.
*/
function onRequest(context) {
var log = new Log("geo-dashboard.js");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var viewModel = {};
var carbonServer = require("carbon").server;
var device = context.unit.params.device;
var constants = require("/app/modules/constants.js");
var wsEndpoint = devicemgtProps["wssURL"].replace("https", "wss") + "/secured-websocket/t/";
var spatialWSEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
var alertsWSEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
var jwtService = carbonServer.osgiService(
'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
var jwtClient = jwtService.getJWTClient();
var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"]);
var token = "";
if (encodedClientKeys) {
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
var resp = tokenUtil.decode(encodedClientKeys).split(":");
var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username, "default", {});
if (tokenPair) {
token = tokenPair.accessToken;
}
}
viewModel.device = device;
viewModel.wsToken = token;
viewModel.wsEndpoint = wsEndpoint;
if (device.latestDeviceInfo) {
viewModel.lastLocation = stringify(device.latestDeviceInfo.location);
} else if (device.location) {
viewModel.lastLocation = stringify(device.location);
} else {
viewModel.lastLocation = stringify({});
}
viewModel.showGeoFencingTools = true;
return viewModel;
}

@ -0,0 +1,47 @@
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
<div class="col-lg-5 col-md-6 col-centered">
<h4>
Set 'Exit Fence' alerts
<br>
</h4>
</div>
</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-8 col-md-8 col-centered">
<div class="">
<table class="table table-hover" id="exit-alert">
<thead>
<tr>
<th>Fence Name</th>
<th>Query Name</th>
<th>Created On</th>
<th></th>
</tr>
</thead>
<tbody>
<div class="alert alert-info fence-not-exist" role="alert">
<strong>Oh snap!</strong> Can't find any geo-fence areas,please draw a new area or try again.
</div>
</tbody>
</table>
</div>
<div class="pull-right">
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default"
onclick="openTools('Exit')">Draw area
</button>
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default"
onclick="$('#editExitinGeoJSON').modal('toggle')">Enter area
</button>
<br/>
<br/>
</div>
</div>
</div>
</div>
</div>
<script src="/devicemgt/public/cdmf.unit.geo-dashboard/js/geo_exit_fence.js"></script>

@ -0,0 +1,95 @@
<!--~ 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.-->
<!DOCTYPE html>
<html>
<head lang="en">
<link href="/portal/store/carbon.super/fs/gadget/geo-dashboard/css/leaflet/L.Grid.css" rel="stylesheet" type="text/css"/>
<link href="/portal/store/carbon.super/fs/gadget/geo-dashboard/css/main.css" rel="stylesheet" type="text/css"/>
<script src="/portal/store/carbon.super/fs/gadget/geo-dashboard/js/leaflet/L.Grid.js"></script>
<script src="/portal/store/carbon.super/fs/gadget/geo-dashboard/js/leaflet/L.MeasuringTool.js"></script>
<style>
.leaflet-grid-label .lng {
margin-left: 8px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
.measuring-line-for-look {
stroke-dasharray: 3, 20;
}
.measuring-label-tooltip .leaflet-popup-content-wrapper {
border-radius: 4px 4px 4px 4px;
opacity: 0.7;
padding: 1px;
text-align: center;
}
.measuring-label-tooltip .leaflet-popup-content {
margin: 0 5px;
/*width: 0;*/
}
.measuring-label-tooltip .leaflet-popup-tip-container {
display: none;
}
</style>
</head>
<body>
<div class="modal-header"
style="cursor: move;background: #f9f9f9;-webkit-box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);-moz-box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
<!-- TODO: Trigger bootstrap tooltip $('#aboutTileUrl').tooltip(); to enable tooltip -->
Define proximity
</h4>
</div>
<div class="modal-body">
<div id="proximityMap" style="height: 50%; margin: 0 auto;"></div>
<div class="row">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<form class="form-inline" role="form">
<div class="input-group input-group-sm">
<input type="text" id="proximityDistance" class="form-control" placeholder="Distance" >
<span class="input-group-addon">m</span>
</div>
<div class="input-group input-group-sm">
<input autofocus="enable" id="proximityTime" type="number" class="form-control"
placeholder="Close time in S" >
<span class="input-group-addon">Seconds</span>
</div>
</form>
</div>
</div>
<div style="margin-bottom: -15px" class="btn-group btn-group-justified">
<div class="btn-group">
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default"
onclick="setProximityAlert()">Set Proximity
</button>
</div>
<div class="btn-group">
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default"
onclick="closeAll()">Cancel
</button>
</div>
</div>
</div>
</div>
<script src="/portal/store/carbon.super/fs/gadget/geo-dashboard/js/geo_proximity.js"></script>
</body>
</html>

@ -0,0 +1,49 @@
<!--~ 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.-->
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<div class="col-lg-5 col-md-6 col-centered">
<h4>
Setup global speed limit
<br>
</h4>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-5 col-md-6 col-centered">
<div class="input-group input-group-sm">
<input autofocus="enable" id="speedAlertValue" type="number" class="form-control" placeholder="Speed alert value " autocomplete="off">
<span class="input-group-addon">km/h</span>
</div>
<br>
<button type="button" class="btn btn-default pull-right btn-sm" onclick="closeAll()">Cancel</button>
<button type="button" class="btn btn-info pull-right btn-sm" onclick="setSpeedAlert()" style="margin-right: 10px;">Set speed alert</button>
<br><br>
</div>
</div>
</div>
<script src="/devicemgt/public/cdmf.unit.geo-dashboard/js/geo_speed.js"></script>
</body>
</html>

@ -0,0 +1,80 @@
<!--~ 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.-->
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.fa-trash-o:hover {
color: red;
}
</style>
<script>
</script>
</head>
<body>
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<div class="col-lg-5 col-md-6 col-centered">
<h4>
Set 'Stationery' alerts
<br>
</h4>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-8 col-md-8 col-centered">
<div class="">
<table class="table table-hover" id="stationary-alert-table">
<thead>
<tr>
<th>Stationery Name</th>
<th>Stationery Time</th>
<th>Fluctuation Radius</th>
<th>Query Name</th>
<th>Created On</th>
<th></th>
</tr>
</thead>
<tbody>
<div class="alert alert-info fence-not-exist" role="alert">
<strong>Oh snap!</strong> Can't find any geo-fence areas,please draw a new area or try again.
</div>
</tbody>
</table>
</div>
<br/>
<br/>
<div class="pull-right">
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default"
onclick="openTools('Stationery')">Draw area
</button>
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default"
onclick="$('#editWithinGeoJSON').modal('toggle')">Enter area
</button>
</div>
<br/>
<br/>
</div>
</div>
<script src="/devicemgt/public/cdmf.unit.geo-dashboard/js/geo_stationary.js"></script>
</body>
</html>

@ -0,0 +1,104 @@
<!--~ 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.-->
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.fa-trash-o:hover{color:red;}
</style>
<script>
$(".removeGeoFence").tooltip();
$('.viewGeoFenceRow td:not(:last-child)').click(function () {
viewFence(this.parentElement,'Traffic');
});
</script>
</head>
<body>
<div class="modal-header" style="cursor: move;background: #f9f9f9;-webkit-box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);-moz-box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);box-shadow: inset 0px 0px 14px 1px rgba(0,0,0,0.2);">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
<!-- TODO: Trigger bootstrap tooltip $('#aboutTileUrl').tooltip(); to enable tooltip -->
Set <i>traffic</i> alerts
</h4>
</div>
<div class="modal-body">
<div class="row">
<p class="text-info text-center">View current fences</p>
<div class="">
<table class="table table-hover">
<thead>
<tr >
<th>Query Name</th>
<th>Traffic Congestion Area Name</th>
<th></th>
</tr>
</thead>
<tbody>
<%
var alerts = get('traffic');
if(alerts){
for each(var alert in alerts){
%>
<tr class="viewGeoFenceRow" style="cursor: pointer" data-areaName='<%= alert.areaName %>' data-queryName='<%= alert.queryName %>' data-geoJson='<%= alert.geoJson %>'>
<td><%= alert.queryName %></td>
<td><%= alert.areaName %></td>
<td onClick="removeGeoFence(this.parentElement,'Traffic')" class="removeGeoFence" data-toggle="tooltip" title="Remove fence" ><i class="fa fa-trash-o"></i></td>
</tr>
<%
}
}
else{
%>
<div class="alert alert-danger" role="alert">
<strong>Oh snap!</strong> Can't find any geo-fence areas,please draw a new area or try again.
</div>
<%
}
%>
</tbody>
</table>
</div>
<p class="text-info text-center">Select Interested Area</p>
<div style="margin-bottom: -15px" class="btn-group btn-group-justified">
<div class="btn-group">
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default" onclick="openTools('Traffic')">Draw area</button>
</div>
<div class="btn-group">
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default" onclick="$('#editWithinGeoJSON').modal('toggle')" >Enter area</button>
</div>
<!--<div class="btn-group">-->
<!--<button style="background-color: #f4f4f4;" type="button" class="btn btn-default" onclick="closeAll()">Cancel</button>-->
<!--</div>-->
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,47 @@
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">
<div class="col-lg-5 col-md-6 col-centered">
<h4>
Set 'Within' alerts
<br>
</h4>
</div>
</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-8 col-md-8 col-centered">
<div class="">
<table class="table table-hover" id="within-alert">
<thead>
<tr>
<th>Fence Name</th>
<th>Query Name</th>
<th>Created On</th>
<th></th>
</tr>
</thead>
<tbody>
<div class="alert alert-info fence-not-exist" role="alert">
<strong>Oh snap!</strong> Can't find any geo-fence areas,please draw a new area or try again.
</div>
</tbody>
</table>
</div>
<div class="pull-right">
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default"
onclick="openTools('WithIn')">Draw area
</button>
<button style="background-color: #f4f4f4;" type="button" class="btn btn-default"
onclick="$('#editWithinGeoJSON').modal('toggle')">Enter area
</button>
<br/>
<br/>
</div>
</div>
</div>
</div>
</div>
<script src="/devicemgt/public/cdmf.unit.geo-dashboard/js/geo_within.js"></script>

@ -0,0 +1,52 @@
<!--~ 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.-->
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="viewExitAlert" >
<h3 class="popover-title" id="viewAreaName"></h3>
<div class="popover-content">
<form role="form" style="width: auto" id="exitAlertForm">
<button type="button" id="exportGeoJson" download="geoJson.json" onclick="exportToGeoJSON(this,JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'))" class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left" title="Export selected area as a geoJson file">Export</button>
<button type="button" id="hideViewFence" class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left" title="Hide this fence" onclick="map.removeLayer(map._layers[$(this).attr('leaflet_id')])" >Hide</button>
</form>
</div>
</div>
<div id="viewWithinAlert" >
<h3 class="popover-title" id="viewAreaName"></h3>
<div class="popover-content">
<form role="form" style="width: auto" class="" id="withinAlertForm">
<button type="button" id="exportGeoJson" download="geoJson.json" onclick="exportToGeoJSON(this,JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'))" class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left" title="Export selected area as a geoJson file">Export</button>
<button type="button" id="hideViewFence" class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left" title="Hide this fence" onclick="map.removeLayer(map._layers[$(this).attr('leaflet_id')])" >Hide</button>
</form>
</div>
</div>
<div id="viewStationeryAlert" >
<h3 class="popover-title" id="viewAreaName"></h3>
<div class="popover-content">
<form role="form" style="width: auto" id="stationaryAlertForm">
<h6>Stationery time(Seconds)<span id="viewAreaTime" class="label label-primary pull-right">N/A</span></h6>
<button type="button" id="exportGeoJson" download="geoJson.json" onclick="exportToGeoJSON(this,JSON.stringify(map._layers[$(this).attr('leaflet_id')].toGeoJSON(),null, '\t'))" class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left" title="Export selected area as a geoJson file">Export</button>
<button type="button" id="hideViewFence" class="btn btn-info btn-xs" data-toggle="tooltip" data-placement="left" title="Hide this fence" onclick="map.removeLayer(map._layers[$(this).attr('leaflet_id')])" >Hide</button>
</form>
</div>
</div>
</body>
</html>

@ -0,0 +1,20 @@
/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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);
@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);
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==false and id == "$deviceId"]#geodashboard:subscribe()
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, "This device is in $areaName restricted area!!!" as information
insert into dataOut;
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=false and id == "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information
insert into dataOut;

@ -0,0 +1,140 @@
/* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-Proximity_alert')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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 );
@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 );
@IndexBy('id')
define table ProximityTable(id string, timeStamp long);
@IndexBy('id')
define table AlertsTable(id string , proximityWith string, eventId string);
from dataIn#geodashboard:subscribe()
select id, latitude, longitude, timeStamp, type, speed, heading, eventId
insert into initialStream;
from initialStream[type == 'STOP']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream;
from initialStream[type != 'STOP']
select *
insert into objectInitialStream;
from objectInitialStream#geo:proximity(id,longitude,latitude, $proximityDistance)
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith
insert into proxymityStream;
from proxymityStream[AlertsTable.id == proxymityStream.id in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable
insert into innerStreamOne;
from proxymityStream[not(AlertsTable.id == proxymityStream.id in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable
insert into innerStreamOne;
from proxymityStream[AlertsTable.id == proxymityStream.proximityWith in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable
insert into innerStreamSeven;
from proxymityStream[not(AlertsTable.id == proxymityStream.proximityWith in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable
insert into innerStreamSeven;
from innerStreamOne[inCloseProximity == true AND not(inAlertTable)]
select id,str:concat(",",proximityWith) as proximityWith , eventId
insert into AlertsTable;
from innerStreamSeven[inCloseProximity == true AND not(inAlertTable)]
select proximityWith as id,str:concat(",",id) as proximityWith , eventId
insert into AlertsTable;
from innerStreamOne[innerStreamOne.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamOne.id == AlertsTable.id
select innerStreamOne.id as id, str:concat(",", innerStreamOne.proximityWith, AlertsTable.proximityWith) as proximityWith, innerStreamOne.eventId as eventId
insert into updateStream;
from innerStreamSeven[innerStreamSeven.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamSeven.proximityWith == AlertsTable.id
select innerStreamSeven.proximityWith as id, str:concat(",", innerStreamSeven.id, AlertsTable.proximityWith) as proximityWith, innerStreamSeven.eventId as eventId
insert into updateStream;
from innerStreamOne[innerStreamOne.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamOne.id == AlertsTable.id
select innerStreamOne.id as id, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamOne.proximityWith), "") as proximityWith, innerStreamOne.eventId as eventId
insert into updateStream;
from innerStreamSeven[innerStreamSeven.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable
on innerStreamSeven.proximityWith == AlertsTable.id
select innerStreamSeven.proximityWith as id, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamSeven.id), "") as proximityWith, innerStreamSeven.eventId as eventId
insert into updateStream;
from updateStream
select *
update AlertsTable
on id== AlertsTable.id;
from updateStream[proximityWith == ""]
delete AlertsTable
on id== AlertsTable.id;
from objectInitialStream[AlertsTable.id == objectInitialStream.id in AlertsTable]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId, true as inAlertTable
insert into publishStream;
from objectInitialStream[not(AlertsTable.id == objectInitialStream.id in AlertsTable)]
select id, latitude, longitude, timeStamp, type, speed, heading, eventId, false as inAlertTable
insert into publishStream;
from publishStream[inAlertTable == true]#window.length(0) join AlertsTable
on publishStream.id== AlertsTable.id
select publishStream.id as id, publishStream.latitude as latitude, publishStream.longitude as longitude, publishStream.timeStamp as timeStamp, publishStream.type as type, publishStream.speed as speed, publishStream.heading as heading, publishStream.eventId as eventId, AlertsTable.proximityWith as proximityInfo
insert into innerStreamTwo;
from publishStream[inAlertTable == false]
delete ProximityTable on ProximityTable.id==id;
from publishStream[inAlertTable == false]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream;
from innerStreamTwo[ProximityTable.id == innerStreamTwo.id in ProximityTable]
insert into innerStreamThree;
from innerStreamThree#window.length(0) join ProximityTable
on innerStreamThree.id == ProximityTable.id
select innerStreamThree.id , innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId, ProximityTable.timeStamp as storedTime, innerStreamThree.proximityInfo as proximityInfo
insert into innerStreamFour;
from innerStreamFour[(timeStamp - storedTime) >= $proximityTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,proximityInfo,"true" as isProximity
insert into dataOutStream;
from innerStreamFour[(timeStamp - storedTime) < $proximityTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , proximityInfo ,"false" as isProximity
insert into dataOutStream;
from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)]
select innerStreamTwo.id, innerStreamTwo.timeStamp
insert into ProximityTable;
from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity
insert into dataOutStream;
from dataOutStream[isProximity == 'true']
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,"WARNING" as state,str:concat("Proximity with "," ",proximityInfo) as information
insert into dataOut;
from dataOutStream[isProximity == 'false']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"NORMAL" as state,"" as information
insert into dataOut;

@ -0,0 +1,20 @@
/* Enter a unique ExecutionPlan */
@Plan:name('Geo-ExecutionPlan-Speed---$deviceId_alert')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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);
@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);
from dataIn[speed >= $speedAlertValue and id == "$deviceId"]#geodashboard:subscribe()
select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "ALERTED" as state, "This device movement is not normal!!" as information
insert into dataOut;
from dataIn[speed < $speedAlertValue and id == "$deviceId"]
select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "NORMAL" as state, "This device movement is normal" as information
insert into dataOut;

@ -0,0 +1,89 @@
/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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);
@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);
@IndexBy('id')
define table StationeryTable(id string, timeStamp long);
@IndexBy('id')
define table AlertsTable(id string, stationary bool);
from dataIn#geodashboard:subscribe()
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin
insert into innerStreamOne;
from innerStreamOne[isWithin == false]
delete StationeryTable on StationeryTable.id==id;
from innerStreamOne[isWithin == false]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream;
from innerStreamOne[isWithin == true]#geo:stationary(id,longitude,latitude, $fluctuationRadius)
select id, latitude, longitude, timeStamp, type, speed, heading, eventId,stationary
insert into innerStreamTwo;
from innerStreamTwo[innerStreamTwo.stationary == true]
select innerStreamTwo.id, innerStreamTwo.stationary
insert into AlertsTable;
from innerStreamTwo[innerStreamTwo.stationary == false]
delete AlertsTable on AlertsTable.id==id;
from innerStreamTwo[innerStreamTwo.stationary == false]
delete StationeryTable on StationeryTable.id==id;
from innerStreamOne[isWithin == true AND not(AlertsTable.id == innerStreamOne.id in AlertsTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream;
from innerStreamOne[isWithin == true AND AlertsTable.id == innerStreamOne.id in AlertsTable]
insert into innerStreamThree;
from innerStreamThree#window.length(0) join AlertsTable
on innerStreamThree.id == AlertsTable.id
select innerStreamThree.id , innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId
insert into innerStreamFour;
from innerStreamFour[not(StationeryTable.id == innerStreamFour.id in StationeryTable)]
select innerStreamFour.id, innerStreamFour.timeStamp
insert into StationeryTable;
from innerStreamOne[isWithin == true AND not(StationeryTable.id == innerStreamOne.id in StationeryTable)]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary
insert into dataOutStream;
from innerStreamOne[isWithin == true AND StationeryTable.id == innerStreamOne.id in StationeryTable]
insert into innerStreamFive;
from innerStreamFive#window.length(0) join StationeryTable
on innerStreamFive.id == StationeryTable.id
select innerStreamFive.id , innerStreamFive.latitude, innerStreamFive.longitude,innerStreamFive.timeStamp, innerStreamFive.type, innerStreamFive.speed, innerStreamFive.heading ,innerStreamFive.eventId, StationeryTable.timeStamp as storedTime
insert into innerStreamSix;
from innerStreamSix[(timeStamp - storedTime) >= $stationeryTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"true" as isStationary
insert into dataOutStream;
from innerStreamSix[(timeStamp - storedTime) < $stationeryTime]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"false" as isStationary
insert into dataOutStream;
from dataOutStream[isStationary == 'true']
select id ,latitude, longitude,timeStamp, type, speed, heading ,eventId ,"ALERTED" as state, "This device is in $stationeryName area!!!" as information
insert into dataOut;
from dataOutStream[isStationary == 'false']
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"NORMAL" as state,"" as information
insert into dataOut;

@ -0,0 +1,17 @@
/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* define streams/tables and write queries here ... */
@Import('rawGeoStream:1.0.0')
define stream dataIn (id string, timeStamp long, geometry string, state string, information string);
@Export('AlertsNotifications:1.0.0')
define stream dataOut (id string, state string, information string, timeStamp long, latitude double, longitude double);
from dataIn[geo:intersects(geometry, "$geoFenceGeoJSON")==true and geodashboard:needToNotify(id, str:concat(information, state), "sendFirst") == true and id == $deviceId]
select id, state, str:concat("Traffic alert in $areaName. State: ", state, " ", information) as information, timeStamp, 0.0 as latitude, 0.0 as longitude
insert into dataOut

@ -0,0 +1,20 @@
/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')
/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')
/* 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);
@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);
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==true and id == "$deviceId"]#geodashboard:subscribe()
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, "This device is in $areaName restricted area!!!" as information
insert into dataOut;
from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=true and id == "$deviceId"]
select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information
insert into dataOut;

@ -0,0 +1,31 @@
/* Compatible with Leaflet 0.7 */
@import url('font/locate-fa.woff');
@import url('css/locate-fa.css');
@import url('css/animation.css');
.leaflet-touch .leaflet-bar-part-single {
-webkit-border-radius: 7px 7px 7px 7px;
border-radius: 7px 7px 7px 7px;
border-bottom: none;
}
.leaflet-control-locate a {
font-size: 1.4em;
margin-left: 1px;
color: #444;
}
.leaflet-control-locate.active a {
color: #2074B6;
}
.leaflet-control-locate.active.following a {
color: #FC8428;
}
.leaflet-touch .leaflet-control-locate {
box-shadow: none;
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}

@ -0,0 +1,14 @@
/* Conditional stylesheet for IE. */
@import url('css/locate-fa-ie7.css');
.leaflet-control-locate {
border: 3px solid #999;
}
.leaflet-control-locate a {
background-color: #eee;
}
.leaflet-control-locate a:hover {
background-color: #fff;
}

@ -0,0 +1,60 @@
.marker-cluster-small {
background-color: rgba(181, 226, 140, 0.6);
}
.marker-cluster-small div {
background-color: rgba(110, 204, 57, 0.6);
}
.marker-cluster-medium {
background-color: rgba(241, 211, 87, 0.6);
}
.marker-cluster-medium div {
background-color: rgba(240, 194, 12, 0.6);
}
.marker-cluster-large {
background-color: rgba(253, 156, 115, 0.6);
}
.marker-cluster-large div {
background-color: rgba(241, 128, 23, 0.6);
}
/* IE 6-8 fallback colors */
.leaflet-oldie .marker-cluster-small {
background-color: rgb(181, 226, 140);
}
.leaflet-oldie .marker-cluster-small div {
background-color: rgb(110, 204, 57);
}
.leaflet-oldie .marker-cluster-medium {
background-color: rgb(241, 211, 87);
}
.leaflet-oldie .marker-cluster-medium div {
background-color: rgb(240, 194, 12);
}
.leaflet-oldie .marker-cluster-large {
background-color: rgb(253, 156, 115);
}
.leaflet-oldie .marker-cluster-large div {
background-color: rgb(241, 128, 23);
}
.marker-cluster {
background-clip: padding-box;
border-radius: 20px;
}
.marker-cluster div {
width: 30px;
height: 30px;
margin-left: 5px;
margin-top: 5px;
text-align: center;
border-radius: 15px;
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
}
.marker-cluster span {
line-height: 30px;
}

@ -0,0 +1,6 @@
.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
-webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in;
-moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in;
-o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in;
transition: transform 0.3s ease-out, opacity 0.3s ease-in;
}

@ -0,0 +1,151 @@
input[type="radio"], input[type="checkbox"] {
margin: 0;
}
.map-wrapper{
background: #37474f;
}
#left_side_pannel> .nav > li > a{
color: #fff;
}
.typeahead {
background-color: #FFFFFF;
}
#map {
width: auto;
height: 100%;
}
#loading {
position: absolute;
width: 220px;
height: 19px;
top: 50%;
left: 50%;
margin: -10px 0 0 -110px;
z-index: 20001;
}
/*.sidebar-wrapper {
width: 100%;
height: 100%;
position: relative;
}
.sidebar-table {
position: absolute;
width: 100%;
top: 124px;
bottom: 0px;
overflow: auto;
}*/
.leaflet-control-layers label {
font-weight: normal;
margin-bottom: 0px;
}
.leaflet-control-layers-group-name {
font-weight: bold;
margin-bottom: .2em;
display: block;
}
.leaflet-control-layers-group {
margin-bottom: .5em;
}
.leaflet-control-layers-group label {
padding-left: .5em;
}
.table {
margin-bottom: 0px;
}
.tt-dropdown-menu {
background-color: #FFFFFF;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 4px 4px 4px 4px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
margin-top: 4px;
padding: 4px 0;
width: 100%;
max-height: 300px;
overflow: auto;
}
.tt-suggestion {
font-size: 14px;
line-height: 20px;
padding: 3px 10px;
}
.tt-suggestion.tt-cursor {
background-color: #0097CF;
color: #FFFFFF;
cursor: pointer;
}
.tt-suggestion p {
margin: 0;
}
.tt-suggestion + .tt-suggestion {
border-top: 1px solid #ccc;
}
.typeahead-header {
margin: 0 5px 5px 5px;
padding: 3px 0;
border-bottom: 2px solid #333;
}
.has-feedback .form-control-feedback {
position: absolute;
top: 0;
right: 0;
display: block;
width: 34px;
height: 34px;
line-height: 34px;
text-align: center;
}
@media (max-width: 992px) {
/*.navbar .navbar-brand {
font-size: 18px;
}*/
}
@media (max-width: 767px){
.url-break {
word-break: break-all;
word-break: break-word;
-webkit-hyphens: auto;
hyphens: auto;
}
#sidebar {
display: none;
}
}
.leaflet-geo-alerts{
border-radius: 4px;
border: none;
background-color: white;
padding: 5px;
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
width: 200px;
font-size: 11px;
}
.leaflet-geo-alerts a{
padding: 5px 10px;
}
/*
!* Print Handling *!
@media print {
.navbar {
display: none !important;
}
.leaflet-control-container {
display: none !important;
}
}
.nav > li > a {
padding: 25px 15px !important;
}
.nav > li > a:hover, .nav > li > a:focus {
background-color: transparent !important;
}
*/

@ -0,0 +1,19 @@
Copyright (C) 2013 Panopta, Andrew Moffat
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,182 @@
/* WIZARD GENERAL */
.wizard {
display:none;
}
.wizard-dialog {}
.wizard-content {}
.wizard-body {
padding: 0;
margin: 0;
}
/* WIZARD HEADER */
.wizard-header {
padding: 9px 15px;
border-bottom: 0;
}
.wizard-header h3 {
margin: 0;
line-height: 35px;
display: inline;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-family: inherit;
font-weight: bold;
text-rendering: optimizelegibility;
color: rgb(51, 51, 51);
}
.wizard-subtitle {
font-weight:bold;
color:#AFAFAF;
padding-left:20px;
}
/* WIZARD NAVIGATION */
.wizard-steps {
width: 28%;
background-color: #f5f5f5;
border-bottom-left-radius: 6px;
position: relative;
}
.wizard-nav-container {
padding-bottom: 30px;
}
.wizard-nav-list {
margin-bottom: 0;
}
.wizard-nav-link .glyphicon-chevron-right {
float:right;
margin-top:12px;
margin-right:-6px;
opacity:.25;
}
li.wizard-nav-item.active .glyphicon-chevron-right {
opacity:1;
}
li.wizard-nav-item {
line-height:40px;
}
.wizard-nav-list > li > a {
background-color:#f5f5f5;
padding:3px 15px 3px 20px;
cursor:default;
color:#B4B4B4;
}
.wizard-nav-list > li > a:hover {
background-color: transparent;
}
.wizard-nav-list > li.already-visited > a.wizard-nav-link {
color:#08C;
cursor:pointer;
}
.wizard-nav-list > li.active > a.wizard-nav-link {
color:white;
}
.wizard-nav-item .already-visited .active {
background-color:#08C;
}
.wizard-nav-list li.active > a {
background-color:#08C;
}
/* WIZARD CONTENT */
.wizard-body form {
padding: 0;
margin: 0;
}
/* WIZARD PROGRESS BAR */
.wizard-progress-container {
margin-top: 20px;
padding: 15px;
width: 100%;
position: absolute;
bottom: 0;
}
.wizard-card-container {
margin-left: 28%;
}
/* WIZARD CARDS */
.wizard-error,
.wizard-failure,
.wizard-success,
.wizard-loading,
.wizard-card {
border-top: 1px solid #EEE;
display:none;
padding:35px;
padding-top:20px;
overflow-y:auto;
/*
position:relative;
height:300px;
margin-right: 5px;
*/
}
.wizard-card-overlay {
overflow-y: initial;
}
.wizard-card > h3 {
margin-top:0;
margin-bottom:20px;
font-size:21px;
line-height:40px;
font-weight:normal;
}
/* WIZARD FOOTER */
.wizard-footer {
padding:0;
}
.wizard-buttons-container {
padding:20px;
}
.wizard-cancel {
margin-left: 12px;
}
/* Inner Card */
.wizard-input-section {
margin-bottom:20px;
}
.wizard-dialog .popover.error-popover {
background-color:#F2DEDE;
color:#B94A48;
border-color:#953B39;
}
.wizard-dialog .popover.error-popover .arrow::after {
border-right-color:#F2DEDE;
}
.wizard-dialog .popover.error-popover .popover-title {
display:none;
}
.wizard-dialog .popover.error-popover .arrow {
border-right-color:#953B39;
}

@ -0,0 +1,85 @@
/*
Animation example, for spinners
*/
.animate-spin:before {
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
-webkit-animation: spin 2s infinite linear;
animation: spin 2s infinite linear;
display: inline-block;
}
@-moz-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-webkit-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-o-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-ms-keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes spin {
0% {
-moz-transform: rotate(0deg);
-o-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
-o-transform: rotate(359deg);
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}

@ -0,0 +1,4 @@
.icon-location:before { content: '\e802'; } /* '' */
.icon-direction:before { content: '\e800'; } /* '' */
.icon-spinner:before { content: '\e801'; } /* '' */

@ -0,0 +1,4 @@
.icon-location { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
.icon-direction { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
.icon-spinner { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }

@ -0,0 +1,15 @@
[class^="icon-"], [class*=" icon-"] {
font-family: 'locate-fa';
font-style: normal;
font-weight: normal;
/* fix buttons height */
line-height: 1em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
}
.icon-location { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
.icon-direction { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
.icon-spinner { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }

@ -0,0 +1,72 @@
@font-face {
font-family: 'locate-fa';
src: url('../font/locate-fa.eot?9201824');
src: url('../font/locate-fa.eot?9201824#iefix') format('embedded-opentype'),
url('../font/locate-fa.woff?9201824') format('woff'),
url('../font/locate-fa.ttf?9201824') format('truetype'),
url('../font/locate-fa.svg?9201824#locate-fa') format('svg');
font-weight: normal;
font-style: normal;
}
/* use SVG only on mobile devices to avoid display issue on android
issue: https://github.com/domoritz/leaflet-locatecontrol/issues/78
solution: http://stackoverflow.com/a/21050160/1106908
*/
@media only screen and (max-width: 320px),
screen and (max-device-width: 720px) and (orientation: portrait),
screen and (max-device-width: 1280px) and (orientation: landscape)
{
@font-face {
font-family: 'locate-fa';
src: url('../font/locate-fa.eot?9201824');
src: url('../font/locate-fa.svg?9201824#locate-fa') format('svg');
font-weight: normal;
font-style: normal;
}
}
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
/*
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'locate-fa';
src: url('../font/locate-fa.svg?9201824#locate-fa') format('svg');
}
}
*/
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: "locate-fa";
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: .2em;
text-align: center;
/* opacity: .8; */
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* fix buttons height, for twitter bootstrap */
line-height: 1em;
/* Animation center compensation - margins should be symmetric */
/* remove if not needed */
margin-left: .2em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
/* Uncomment for 3D effect */
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
}
.icon-location:before { content: '\e802'; } /* '' */
.icon-direction:before { content: '\e800'; } /* '' */
.icon-spinner:before { content: '\e801'; } /* '' */

@ -0,0 +1,203 @@
/*-- Chart --*/
.c3 svg {
font: 10px sans-serif;
}
.c3 path, .c3 line {
fill: none;
stroke: #000;
}
.c3 text {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.c3-legend-item-tile,
.c3-xgrid-focus,
.c3-ygrid,
.c3-event-rect,
.c3-bars path {
shape-rendering: crispEdges;
}
.c3-chart-arc path {
stroke: #fff;
}
.c3-chart-arc text {
fill: #fff;
font-size: 13px;
}
/*-- Axis --*/
.c3-axis-x .tick {
}
.c3-axis-x-label {
}
.c3-axis-y .tick {
}
.c3-axis-y-label {
}
.c3-axis-y2 .tick {
}
.c3-axis-y2-label {
}
/*-- Grid --*/
.c3-grid line {
stroke: #aaa;
}
.c3-grid text {
fill: #aaa;
}
.c3-xgrid, .c3-ygrid {
stroke-dasharray: 3 3;
}
.c3-xgrid-focus {
}
/*-- Text on Chart --*/
.c3-text {
}
.c3-text.c3-empty {
fill: #808080;
font-size: 2em;
}
/*-- Line --*/
.c3-line {
stroke-width: 1px;
}
/*-- Point --*/
.c3-circle._expanded_ {
stroke-width: 1px;
stroke: white;
}
.c3-selected-circle {
fill: white;
stroke-width: 2px;
}
/*-- Bar --*/
.c3-bar {
stroke-width: 0;
}
.c3-bar._expanded_ {
fill-opacity: 0.75;
}
/*-- Arc --*/
.c3-chart-arcs-title {
font-size: 1.3em;
}
/*-- Focus --*/
.c3-target.c3-focused path.c3-line, .c3-target.c3-focused path.c3-step {
stroke-width: 2px;
}
/*-- Region --*/
.c3-region {
fill: steelblue;
fill-opacity: .1;
}
/*-- Brush --*/
.c3-brush .extent {
fill-opacity: .1;
}
/*-- Select - Drag --*/
.c3-dragarea {
}
/*-- Legend --*/
.c3-legend-item {
font-size: 12px;
}
.c3-legend-background {
opacity: 0.75;
fill: white;
stroke: lightgray;
stroke-width: 1
}
/*-- Tooltip --*/
.c3-tooltip {
border-collapse:collapse;
border-spacing:0;
background-color:#fff;
empty-cells:show;
-webkit-box-shadow: 7px 7px 12px -9px rgb(119,119,119);
-moz-box-shadow: 7px 7px 12px -9px rgb(119,119,119);
box-shadow: 7px 7px 12px -9px rgb(119,119,119);
opacity: 0.9;
}
.c3-tooltip tr {
border:1px solid #CCC;
}
.c3-tooltip th {
background-color: #aaa;
font-size:14px;
padding:2px 5px;
text-align:left;
color:#FFF;
}
.c3-tooltip td {
font-size:13px;
padding: 3px 6px;
background-color:#fff;
border-left:1px dotted #999;
}
.c3-tooltip td > span {
display: inline-block;
width: 10px;
height: 10px;
margin-right: 6px;
}
.c3-tooltip td.value{
text-align: right;
}
.c3-area {
stroke-width: 0;
opacity: 0.2;
}
.c3-chart-arcs .c3-chart-arcs-background {
fill: #e0e0e0;
stroke: none;
}
.c3-chart-arcs .c3-chart-arcs-gauge-unit {
fill: #000;
font-size: 16px;
}
.c3-chart-arcs .c3-chart-arcs-gauge-max {
fill: #777;
}
.c3-chart-arcs .c3-chart-arcs-gauge-min {
fill: #777;
}
.c3-chart-arc .c3-gauge-value {
fill: #000;
font-size: 28px;
}

@ -0,0 +1,10 @@
Font license info
## Font Awesome
Copyright (C) 2012 by Dave Gandy
Author: Dave Gandy
License: SIL ()
Homepage: http://fortawesome.github.com/Font-Awesome/

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

Loading…
Cancel
Save