forked from community/device-mgt-core
# Conflicts: # components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractGroupDAOImpl.java # components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/OperationMappingDAOImpl.javarevert-70aa11f8
commit
9398e7ee0b
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
@ -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">×</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> About
|
||||
the project</a></li>
|
||||
<li><a href="#contact" data-toggle="tab"><i class="fa fa-envelope"></i> Contact us</a></li>
|
||||
<li><a href="#disclaimer" data-toggle="tab"><i class="fa fa-exclamation-circle"></i> Disclaimer</a>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-globe"></i> 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">×</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">×</button>
|
||||
<h4 class="modal-title">
|
||||
<!– TODO: Trigger bootstrap tooltip $('#aboutTileUrl').tooltip(); to enable tooltip –>
|
||||
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">×</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">×</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,3 @@
|
||||
{
|
||||
"version": "1.0.0"
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<div class="modal-header">
|
||||
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">×</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">×</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">×</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">×</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">×</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">×</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;
|
||||
}
|
||||
*/
|
File diff suppressed because one or more lines are too long
@ -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;
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -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'; } /* '' */
|
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue