diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml
index 8de7832bba..9b17a27634 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/pom.xml
@@ -296,6 +296,16 @@
org.wso2.carbon.application.mgt.stub
provided
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+ provided
+
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.datasource.commons
+ provided
+
org.wso2.carbon.devicemgt
org.wso2.carbon.identity.jwt.client.extension
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoService.java
new file mode 100644
index 0000000000..52fa8fbf01
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoService.java
@@ -0,0 +1,404 @@
+/*
+ * 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/{executionPlanType}/{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 = "executionPlanType",
+ value = "The execution plan type, such as Within, Speed, Stationary",
+ required = true)
+ @PathParam("executionPlanType") String executionPlanType);
+
+ /**
+ * Update Geo alerts
+ */
+ @PUT
+ @Path("alerts/{executionPlanType}/{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 = "executionPlanType",
+ value = "The execution plan type, such as Within, Speed, Stationary",
+ required = true)
+ @PathParam("executionPlanType") String executionPlanType);
+
+ /**
+ * Retrieve Geo alerts
+ */
+ @GET
+ @Path("alerts/{executionPlanType}/{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 = "executionPlanType",
+ value = "The execution plan type, such as Within, Speed, Stationary",
+ required = true)
+ @PathParam("executionPlanType") String executionPlanType);
+
+
+ @DELETE
+ @Path("alerts/{executionPlanType}/{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 = "executionPlanType",
+ value = "The execution plan type, such as Within, Speed, Stationary",
+ required = true)
+ @PathParam("executionPlanType") String executionPlanType,
+ @ApiParam(
+ name = "queryName",
+ value = "The query name.",
+ required = true)
+ @QueryParam("queryName") String queryName);
+}
+
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoServiceImpl.java
new file mode 100644
index 0000000000..91ef644bab
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoServiceImpl.java
@@ -0,0 +1,315 @@
+/*
+ * 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 = "ORG_WSO2_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 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 searchResults = analyticsDataAPI.search(tenantId, tableName, query,
+ 0,
+ 100,
+ sortByFields);
+ List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(),
+ 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/{executionPlanType}/{deviceType}/{deviceId}")
+ @POST
+ @Consumes("application/json")
+ @Produces("application/json")
+ public Response createGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId,
+ @PathParam("deviceType") String deviceType,
+ @PathParam("executionPlanType") String executionPlanType) {
+ 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, executionPlanType);
+ 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/{executionPlanType}/{deviceType}/{deviceId}")
+ @PUT
+ @Consumes("application/json")
+ @Produces("application/json")
+ public Response updateGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId,
+ @PathParam("deviceType") String deviceType,
+ @PathParam("executionPlanType") String executionPlanType) {
+ 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, executionPlanType);
+ 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/{executionPlanType}/{deviceType}/{deviceId}")
+ @DELETE
+ @Consumes("application/json")
+ @Produces("application/json")
+ public Response removeGeoAlerts(@PathParam("deviceId") String deviceId,
+ @PathParam("deviceType") String deviceType,
+ @PathParam("executionPlanType") String executionPlanType,
+ @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(executionPlanType, 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/{executionPlanType}/{deviceType}/{deviceId}")
+ @GET
+ @Consumes("application/json")
+ @Produces("application/json")
+ public Response getGeoAlerts(@PathParam("deviceId") String deviceId,
+ @PathParam("deviceType") String deviceType,
+ @PathParam("executionPlanType") String executionPlanType) {
+ 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.EXECUTION_PLAN_TYPE_WITHIN.equals(executionPlanType)) {
+ List alerts = geoService.getWithinAlerts(identifier);
+ return Response.ok().entity(alerts).build();
+ } else if (GeoServices.EXECUTION_PLAN_TYPE_SPEED.equals(executionPlanType)) {
+ String result = geoService.getSpeedAlerts(identifier);
+ return Response.ok().entity(result).build();
+ } else if (GeoServices.EXECUTION_PLAN_TYPE_PROXIMITY.equals(executionPlanType)) {
+ String result = geoService.getProximityAlerts(identifier);
+ return Response.ok().entity(result).build();
+ } else if (GeoServices.EXECUTION_PLAN_TYPE_STATIONARY.equals(executionPlanType)) {
+ List alerts = geoService.getStationaryAlerts(identifier);
+ return Response.ok().entity(alerts).build();
+ } else if (GeoServices.EXECUTION_PLAN_TYPE_TRAFFIC.equals(executionPlanType)) {
+ List 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();
+ }
+ }
+
+ private List getEventBeans(AnalyticsDataAPI analyticsDataAPI, int tenantId, String tableName,
+ List columns,
+ List searchResults) throws AnalyticsException {
+ List ids = getIds(searchResults);
+ List requiredColumns = (columns == null || columns.isEmpty()) ? null : columns;
+ AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, requiredColumns, ids);
+ List records = AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response);
+ Map eventBeanMap = getEventBeanKeyedWithIds(records);
+ return getSortedEventBeans(eventBeanMap, searchResults);
+ }
+
+ private List getSortedEventBeans(Map eventBeanMap,
+ List searchResults) {
+ List sortedRecords = new ArrayList<>();
+ for (SearchResultEntry entry : searchResults) {
+ sortedRecords.add(eventBeanMap.get(entry.getId()));
+ }
+ return sortedRecords;
+ }
+
+ private Map getEventBeanKeyedWithIds(List records) {
+ Map eventBeanMap = new HashMap<>();
+ for (Record record : records) {
+ Event event = getEventBean(record);
+ eventBeanMap.put(event.getId(), event);
+ }
+ return eventBeanMap;
+ }
+
+ private List getIds(List searchResults) {
+ List 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;
+ }
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java
index 888b1c42ee..d1e3ba234c 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java
@@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.jaxrs.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.analytics.api.AnalyticsDataAPI;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.analytics.dashboard.GadgetDataService;
@@ -28,6 +29,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.core.app.mgt.ApplicationManagementProviderService;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
@@ -320,6 +322,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);
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml
index e33d1beb26..6e37d0256b 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml
@@ -36,6 +36,7 @@
+
@@ -76,6 +77,7 @@
+
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.common/pom.xml
index 611fe6c150..15f98b812a 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/pom.xml
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/pom.xml
@@ -50,6 +50,7 @@
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
@@ -68,6 +69,14 @@
org.wso2.orbit.com.fasterxml.jackson.core
jackson-annotations
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.datasource.commons
+
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java
index ba0d3d59ed..a3d50e2d12 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceManagementConstants.java
@@ -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,31 @@ 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 EXECUTION_PLAN_TYPE_SPEED = "Speed";
+ public static final String EXECUTION_PLAN_TYPE_WITHIN = "Within";
+ public static final String EXECUTION_PLAN_TYPE_PROXIMITY = "Proximity";
+ public static final String EXECUTION_PLAN_TYPE_STATIONARY = "Stationery";
+ public static final String EXECUTION_PLAN_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;
+ }
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/Alert.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/Alert.java
new file mode 100644
index 0000000000..f43c319567
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/Alert.java
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/Event.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/Event.java
new file mode 100644
index 0000000000..8c79475a37
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/Event.java
@@ -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 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 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 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 valueList = new ArrayList<>();
+ for (Map.Entry entry : values.entrySet()) {
+ valueList.add(entry.getKey() + ":" + entry.getValue());
+ }
+ return valueList.toString();
+ }
+}
\ No newline at end of file
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoFence.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoFence.java
new file mode 100644
index 0000000000..359264dadb
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoFence.java
@@ -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 +
+ "}";
+ }
+}
\ No newline at end of file
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoService.java
new file mode 100644
index 0000000000..1cc28e95f5
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoService.java
@@ -0,0 +1,49 @@
+/*
+ * 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 getWithinAlerts(DeviceIdentifier identifier) throws GeoServiceException;
+
+ boolean createGeoAlert(Alert alert, DeviceIdentifier identifier, String executionPlanType)
+ throws GeoServiceException;
+
+ boolean updateGeoAlert(Alert alert, DeviceIdentifier identifier, String executionPlanType)
+ throws GeoServiceException;
+
+ boolean removeGeoAlert(String executionPlanType, DeviceIdentifier identifier, String queryName)
+ throws GeoServiceException;
+
+ String getSpeedAlerts(DeviceIdentifier identifier) throws GeoServiceException;
+
+ String getProximityAlerts(DeviceIdentifier identifier) throws GeoServiceException;
+
+ List getStationaryAlerts(DeviceIdentifier identifier) throws GeoServiceException;
+
+ List getTrafficAlerts(DeviceIdentifier identifier) throws GeoServiceException;
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoServiceException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoServiceException.java
new file mode 100644
index 0000000000..91154e03e2
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoServiceException.java
@@ -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);
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml
index a5d2e2afea..bfef6dc4ed 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/pom.xml
@@ -86,7 +86,10 @@
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
!org.wso2.carbon.device.mgt.core.internal,
@@ -262,6 +265,20 @@
org.wso2.carbon.devicemgt
org.wso2.carbon.apimgt.annotations
+
+ org.wso2.carbon.event-processing
+ org.wso2.carbon.event.processor.stub
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.identity.jwt.client.extension
+ provided
+
+
+ commons-codec.wso2
+ commons-codec
+ provided
+
javax.ws.rs
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoServcieManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoServcieManagerImpl.java
new file mode 100644
index 0000000000..8ff4ceb8dd
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoServcieManagerImpl.java
@@ -0,0 +1,668 @@
+/*
+ * 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 getWithinAlerts(DeviceIdentifier identifier) throws GeoServiceException {
+
+ Registry registry = getGovernanceRegistry();
+ String registryPath = GeoServices.REGISTRY_PATH_FOR_ALERTS +
+ GeoServices.EXECUTION_PLAN_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 fences = new ArrayList<>();
+ if (resource != null) {
+ Object contentObj = resource.getContent();
+ if (contentObj instanceof String[]) {
+ String[] content = (String[]) contentObj;
+ Gson gson = new Gson();
+ 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 executionPlanType)
+ throws GeoServiceException {
+ return saveGeoAlert(alert, identifier, executionPlanType, false);
+ }
+
+ @Override
+ public boolean updateGeoAlert(Alert alert, DeviceIdentifier identifier, String executionPlanType)
+ throws GeoServiceException {
+ return saveGeoAlert(alert, identifier, executionPlanType, true);
+ }
+
+ public boolean saveGeoAlert(Alert alert, DeviceIdentifier identifier, String executionPlanType, boolean isUpdate)
+ throws GeoServiceException {
+
+ Type type = new TypeToken
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+ ${carbon.analytics.version}
+
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.datasource.commons
+ ${carbon.analytics.version}
+
+
+ org.wso2.carbon.event-processing
+ org.wso2.carbon.event.processor.stub
+ ${carbon.event-processing.version}
+
org.wso2.orbit.org.bouncycastle
@@ -1827,10 +1842,12 @@
6.1.64
(6.0.0,7.0.0]
-
+
+ 1.3.3
+ [1.3.3, 1.4.0)
5.1.3
[5.1.3,6.0.0)
-
+ 2.1.10
4.6.0