Merge branch 'geofence-api' into 'corrective-policy'

Add geo fence search and geo cache

See merge request entgra/carbon-device-mgt!670
corrective-policy
Inosh Perara 4 years ago
commit f97d9307e7

@ -965,9 +965,18 @@ public interface GeoLocationBasedService {
response = Response.class)
})
Response getGeofence(
@ApiParam(
name = "offset",
value = "The starting pagination index for the complete list of qualified items.")
@QueryParam("offset") int offset,
@DefaultValue("10")
@QueryParam("limit") int limit);
@ApiParam(
name = "limit",
value = "Provide how many device details you require from the starting pagination index/offset.")
@QueryParam("limit") int limit,
@ApiParam(
name = "name",
value = "Geo Fence name")
@QueryParam("name") String name);
@DELETE

@ -29,9 +29,9 @@ 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.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
@ -45,7 +45,6 @@ import org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy.GeoHashLength
import org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy.ZoomGeoHashLengthStrategy;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import org.wso2.carbon.device.mgt.jaxrs.beans.GeofenceList;
import org.wso2.carbon.device.mgt.jaxrs.beans.GeofenceWrapper;
import org.wso2.carbon.device.mgt.jaxrs.service.api.GeoLocationBasedService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
@ -621,7 +620,7 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
public Response getGeofence(@PathParam("fenceId") int fenceId) {
try {
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
GeofenceData geofenceData = geoService.getGeofence(fenceId);
GeofenceData geofenceData = geoService.getGeoFences(fenceId);
if (geofenceData == null) {
String msg = "No valid Geofence found for ID " + fenceId;
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
@ -656,20 +655,21 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
@Consumes("application/json")
@Produces("application/json")
public Response getGeofence(@QueryParam("offset") int offset,
@DefaultValue("10")
@QueryParam("limit") int limit) {
@QueryParam("limit") int limit,
@QueryParam("name") String name) {
try {
PaginationRequest request = new PaginationRequest(offset, limit);
GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService();
List<GeofenceData> geofence = geoService.getGeofence(request);
List<GeofenceWrapper> geofenceList = new ArrayList<>();
for (GeofenceData geofenceData : geofence) {
geofenceList.add(getMappedResponseBean(geofenceData));
if (offset != 0 && limit != 0) {
PaginationRequest request = new PaginationRequest(offset, limit);
if (name != null && !name.isEmpty()) {
request.setProperty(DeviceManagementConstants.GeoServices.FENCE_NAME, name);
}
return getResponse(geoService.getGeoFences(request));
}
if (name != null && !name.isEmpty()) {
return getResponse(geoService.getGeoFences(name));
}
PaginationResult paginationResult = new PaginationResult();
paginationResult.setData(geofenceList);
paginationResult.setRecordsTotal(geofenceList.size());
return Response.status(Response.Status.OK).entity(paginationResult).build();
return getResponse(geoService.getGeoFences());
} catch (GeoLocationBasedServiceException e) {
String msg = "Failed to retrieve geofence data";
log.error(msg, e);
@ -677,6 +677,17 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService {
}
}
private Response getResponse(List<GeofenceData> fencesList) {
List<GeofenceWrapper> geofenceList = new ArrayList<>();
for (GeofenceData geofenceData : fencesList) {
geofenceList.add(getMappedResponseBean(geofenceData));
}
PaginationResult paginationResult = new PaginationResult();
paginationResult.setData(geofenceList);
paginationResult.setRecordsTotal(geofenceList.size());
return Response.status(Response.Status.OK).entity(paginationResult).build();
}
@DELETE
@Override

@ -124,6 +124,7 @@ public final class DeviceManagementConstants {
public static final String DAS_HOST_NAME = "${iot.analytics.host}";
public static final String DEFAULT_HTTP_PROTOCOL = "https";
public static final String DAS_URL = DEFAULT_HTTP_PROTOCOL + "://" + DAS_HOST_NAME + ":" + DAS_PORT;
public static final String FENCE_NAME = "name";
}
public static final class OTPProperties {

@ -86,7 +86,7 @@ public interface GeoLocationProviderService {
* @return Extracted geofence data
* @throws GeoLocationBasedServiceException error occurs while retrieving a geofence
*/
GeofenceData getGeofence(int fenceId) throws GeoLocationBasedServiceException;
GeofenceData getGeoFences(int fenceId) throws GeoLocationBasedServiceException;
/**
* Get paginated geofence list
@ -94,13 +94,28 @@ public interface GeoLocationProviderService {
* @return List of Geofences retrieved
* @throws GeoLocationBasedServiceException error occurs while retrieving geofences
*/
List<GeofenceData> getGeofence(PaginationRequest request) throws GeoLocationBasedServiceException;
List<GeofenceData> getGeoFences(PaginationRequest request) throws GeoLocationBasedServiceException;
/**
* Search geo fences using the fence name
* @param name searching name of the fence
* @return list of fences found for the specific name
* @throws GeoLocationBasedServiceException for errors occur while querying geo fences
*/
List<GeofenceData> getGeoFences(String name) throws GeoLocationBasedServiceException;
/**
* Get all geo fences of the tenant
* @return list of the all geo fences of the tenant
* @throws GeoLocationBasedServiceException for errors occur while querying geo fences
*/
List<GeofenceData> getGeoFences() throws GeoLocationBasedServiceException;
/**
* Delete Geofence with ID
* @param fenceId Id of the fence which should be deleted
* @return true if deletion success. false if not record found for the used Id
* @throws GeoLocationBasedServiceException
* @throws GeoLocationBasedServiceException for errors occur while deleting geo fences
*/
boolean deleteGeofenceData(int fenceId) throws GeoLocationBasedServiceException;
@ -109,7 +124,7 @@ public interface GeoLocationProviderService {
* @param geofenceData Bean with updated geofence data
* @param fenceId Id of the fence which should be updated
* @return true if update success. false if not a record found for the used Id
* @throws GeoLocationBasedServiceException
* @throws GeoLocationBasedServiceException for errors occur while updating geo fences
*/
boolean updateGeofence(GeofenceData geofenceData, int fenceId) throws GeoLocationBasedServiceException;
}

@ -42,6 +42,7 @@ public final class DeviceManagementConstants {
public static final String DM_CACHE_MANAGER = "DM_CACHE_MANAGER";
public static final String DEVICE_CACHE = "DEVICE_CACHE";
public static final String GEOFENCE_CACHE = "GEOFENCE_CACHE";
public static final String ENROLLMENT_NOTIFICATION_API_ENDPOINT = "/api/device-mgt/enrollment-notification";
public static final String URL_SEPERATOR = "/";

@ -0,0 +1,73 @@
/*
* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.cache;
import java.util.Objects;
public class GeoCacheKey {
private int fenceId;
private int tenantId;
private volatile int hashCode;
public GeoCacheKey(int fenceId, int tenantId) {
this.fenceId = fenceId;
this.tenantId = tenantId;
}
public GeoCacheKey() {
}
public int getFenceId() {
return fenceId;
}
public void setFenceId(int fenceId) {
this.fenceId = fenceId;
}
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!GeoCacheKey.class.isAssignableFrom(obj.getClass())) {
return false;
}
final GeoCacheKey other = (GeoCacheKey) obj;
String thisId = this.fenceId + "-" + "_" + this.tenantId;
String otherId = other.fenceId + "-" + "_" + other.tenantId;
return thisId.equals(otherId);
}
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Objects.hash(fenceId, tenantId);
}
return hashCode;
}
}

@ -0,0 +1,54 @@
/*
* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.cache;
import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData;
public interface GeoCacheManager {
/**
* Add geo fences to the cache
* @param geofenceData adding fence object
* @param fenceId id of the fence
* @param tenantId id of the tenant
*/
void addFenceToCache(GeofenceData geofenceData, int fenceId, int tenantId);
/**
* Update geo fences already in cache
* @param geofenceData updating geo fence object
* @param fenceId id of the fence
* @param tenantId id of the tenant
*/
void updateGeoFenceInCache(GeofenceData geofenceData, int fenceId, int tenantId);
/**
* Remove geo fence from cache
* @param fenceId id of the fence
* @param tenantId id of the tenant
*/
void removeFenceFromCache(int fenceId, int tenantId);
/**
* Get geo fence data from the cache
* @param fenceId id of the retrieving fence object
* @param tenantId tenant id of the fence created
* @return GeofenceData object if the cache have the specific object or null if there is no entry
*/
GeofenceData getGeoFenceFromCache(int fenceId, int tenantId);
}

@ -0,0 +1,95 @@
/*
* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.cache.impl;
import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData;
import org.wso2.carbon.device.mgt.core.cache.GeoCacheKey;
import org.wso2.carbon.device.mgt.core.cache.GeoCacheManager;
import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
import javax.cache.Cache;
public class GeoCacheManagerImpl implements GeoCacheManager {
private static GeoCacheManager geoCacheManager;
private GeoCacheManagerImpl() {}
public static GeoCacheManager getInstance() {
if (geoCacheManager == null) {
synchronized (GeoCacheManagerImpl.class) {
if (geoCacheManager == null) {
geoCacheManager = new GeoCacheManagerImpl();
}
}
}
return geoCacheManager;
}
@Override
public void addFenceToCache(GeofenceData geofenceData, int fenceId, int tenantId) {
Cache<GeoCacheKey, GeofenceData> lCache = DeviceManagerUtil.getGeoCache();
if (lCache != null) {
GeoCacheKey cacheKey = getCacheKey(fenceId, tenantId);
if (lCache.containsKey(cacheKey)) {
this.updateGeoFenceInCache(geofenceData, fenceId, tenantId);
} else {
lCache.put(cacheKey, geofenceData);
}
}
}
@Override
public void removeFenceFromCache(int fenceId, int tenantId) {
Cache<GeoCacheKey, GeofenceData> lCache = DeviceManagerUtil.getGeoCache();
if (lCache != null) {
GeoCacheKey cacheKey = getCacheKey(fenceId, tenantId);
if (lCache.containsKey(cacheKey)) {
lCache.remove(cacheKey);
}
}
}
@Override
public void updateGeoFenceInCache(GeofenceData geofenceData, int fenceId, int tenantId) {
Cache<GeoCacheKey, GeofenceData> lCache = DeviceManagerUtil.getGeoCache();
if (lCache != null) {
GeoCacheKey cacheKey = getCacheKey(fenceId, tenantId);
if (lCache.containsKey(cacheKey)) {
lCache.replace(cacheKey, geofenceData);
}
}
}
@Override
public GeofenceData getGeoFenceFromCache(int fenceId, int tenantId) {
GeofenceData geofenceData = null;
Cache<GeoCacheKey, GeofenceData> lCache = DeviceManagerUtil.getGeoCache();
if (lCache != null) {
geofenceData = lCache.get(getCacheKey(fenceId, tenantId));
}
return geofenceData;
}
private GeoCacheKey getCacheKey(int fenceId, int tenantId) {
GeoCacheKey geoCacheKey = new GeoCacheKey();
geoCacheKey.setFenceId(fenceId);
geoCacheKey.setTenantId(tenantId);
return geoCacheKey;
}
}

@ -23,6 +23,7 @@ import org.wso2.carbon.device.mgt.core.config.analytics.OperationAnalyticsConfig
import org.wso2.carbon.device.mgt.core.config.archival.ArchivalConfiguration;
import org.wso2.carbon.device.mgt.core.config.cache.CertificateCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.cache.DeviceCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.cache.GeoFenceCacheConfiguration;
import org.wso2.carbon.device.mgt.core.config.geo.location.GeoLocationConfiguration;
import org.wso2.carbon.device.mgt.core.config.identity.IdentityConfigurations;
import org.wso2.carbon.device.mgt.core.config.keymanager.KeyManagerConfigurations;
@ -54,6 +55,7 @@ public final class DeviceManagementConfig {
private PullNotificationConfiguration pullNotificationConfiguration;
private DeviceStatusTaskConfig deviceStatusTaskConfig;
private DeviceCacheConfiguration deviceCacheConfiguration;
private GeoFenceCacheConfiguration geoFenceCacheConfiguration;
private CertificateCacheConfiguration certificateCacheConfiguration;
private OperationAnalyticsConfiguration operationAnalyticsConfiguration;
private GeoLocationConfiguration geoLocationConfiguration;
@ -154,6 +156,15 @@ public final class DeviceManagementConfig {
this.deviceCacheConfiguration = deviceCacheConfiguration;
}
@XmlElement(name = "GeoFenceCacheConfiguration", required = true)
public GeoFenceCacheConfiguration getGeoFenceCacheConfiguration() {
return geoFenceCacheConfiguration;
}
public void setGeoFenceCacheConfiguration(GeoFenceCacheConfiguration geoFenceCacheConfiguration) {
this.geoFenceCacheConfiguration = geoFenceCacheConfiguration;
}
@XmlElement(name = "CertificateCacheConfiguration", required = true)
public CertificateCacheConfiguration getCertificateCacheConfiguration() {
return certificateCacheConfiguration;

@ -0,0 +1,57 @@
/*
* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.core.config.cache;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "GeoFenceCacheConfiguration")
public class GeoFenceCacheConfiguration {
private boolean isEnabled;
private int expiryTime;
private long capacity;
@XmlElement(name = "Enable", required = true)
public boolean isEnabled() {
return isEnabled;
}
public void setEnabled(boolean enabled) {
isEnabled = enabled;
}
@XmlElement(name = "ExpiryTime", required = true)
public int getExpiryTime() {
return expiryTime;
}
public void setExpiryTime(int expiryTime) {
this.expiryTime = expiryTime;
}
@XmlElement(name = "Capacity", required = true)
public long getCapacity() {
return capacity;
}
public void setCapacity(long capacity) {
this.capacity = capacity;
}
}

@ -34,7 +34,7 @@ public interface GeofenceDAO {
* @return created row count
* @throws DeviceManagementDAOException error occurs while saving the data
*/
int saveGeofence(GeofenceData geofenceData) throws DeviceManagementDAOException;
GeofenceData saveGeofence(GeofenceData geofenceData) throws DeviceManagementDAOException;
/**
* Retrieve a geofence record for specified Id
@ -51,7 +51,26 @@ public interface GeofenceDAO {
* @return List of geofences retrieved
* @throws DeviceManagementDAOException error occurs while reading the data
*/
List<GeofenceData> getGeofencesOfTenant(PaginationRequest request, int tenantId)
List<GeofenceData> getGeoFencesOfTenant(PaginationRequest request, int tenantId)
throws DeviceManagementDAOException;
/**
* Search geofence by fence name of a specific tenant
* @param fenceName searching name
* @param tenantId searching tenant
* @return list of found fences
* @throws DeviceManagementDAOException
*/
List<GeofenceData> getGeoFencesOfTenant(String fenceName, int tenantId)
throws DeviceManagementDAOException;
/**
* Get all fences of the specific tenant
* @param tenantId tenant id of the fences
* @return list of the fences owned by the tenant
* @throws DeviceManagementDAOException
*/
List<GeofenceData> getGeoFencesOfTenant(int tenantId)
throws DeviceManagementDAOException;
/**

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.core.dao.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationBasedServiceException;
import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData;
@ -31,6 +32,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
@ -39,7 +41,7 @@ import java.util.List;
public class GeofenceDAOImpl implements GeofenceDAO {
private static final Log log = LogFactory.getLog(GeofenceDAOImpl.class);
@Override
public int saveGeofence(GeofenceData geofenceData) throws DeviceManagementDAOException {
public GeofenceData saveGeofence(GeofenceData geofenceData) throws DeviceManagementDAOException {
try {
Connection conn = this.getConnection();
String sql = "INSERT INTO DM_GEOFENCE(" +
@ -54,7 +56,7 @@ public class GeofenceDAOImpl implements GeofenceDAO {
"OWNER, " +
"TENANT_ID) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, geofenceData.getFenceName());
stmt.setString(2, geofenceData.getDescription());
stmt.setDouble(3, geofenceData.getLatitude());
@ -65,7 +67,13 @@ public class GeofenceDAOImpl implements GeofenceDAO {
stmt.setTimestamp(8, new Timestamp(new Date().getTime()));
stmt.setString(9, geofenceData.getOwner());
stmt.setInt(10, geofenceData.getTenantId());
return stmt.executeUpdate();
if (stmt.executeUpdate() > 0) {
ResultSet generatedKeys = stmt.getGeneratedKeys();
if (generatedKeys.next()) {
geofenceData.setId(generatedKeys.getInt(1));
}
}
return geofenceData;
}
} catch (SQLException e) {
String msg = "Error occurred while creating Geofence for the tenant id "+geofenceData.getTenantId();
@ -110,7 +118,59 @@ public class GeofenceDAOImpl implements GeofenceDAO {
}
@Override
public List<GeofenceData> getGeofencesOfTenant(PaginationRequest request, int tenantId)
public List<GeofenceData> getGeoFencesOfTenant(PaginationRequest request, int tenantId)
throws DeviceManagementDAOException {
try {
boolean isNameProvided = false;
List<GeofenceData> geofenceData;
Connection conn = this.getConnection();
String sql = "SELECT " +
"ID, " +
"FENCE_NAME, " +
"DESCRIPTION, " +
"LATITUDE, " +
"LONGITUDE, " +
"RADIUS, " +
"GEO_JSON, " +
"FENCE_SHAPE, " +
"OWNER, " +
"TENANT_ID " +
"FROM DM_GEOFENCE " +
"WHERE TENANT_ID = ? ";
if (request.getProperty(DeviceManagementConstants.GeoServices.FENCE_NAME) != null) {
sql += "AND FENCE_NAME LIKE ?";
isNameProvided = true;
}
sql += "LIMIT ? OFFSET ?";
int index = 1;
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(index++, tenantId);
if (isNameProvided) {
stmt.setString(index++, request.getProperty(DeviceManagementConstants.GeoServices.FENCE_NAME).toString() + "%");
}
stmt.setInt(index++, request.getRowCount());
stmt.setInt(index, request.getStartIndex());
try (ResultSet rst = stmt.executeQuery()) {
geofenceData = extractGeofenceData(rst);
}
}
return geofenceData;
} catch (SQLException e) {
String msg = "Error occurred while retrieving Geofence of the tenant " + tenantId;
log.error(msg, e);
throw new DeviceManagementDAOException(msg, e);
}
}
@Override
public List<GeofenceData> getGeoFencesOfTenant(String fenceName, int tenantId)
throws DeviceManagementDAOException {
return null;
}
@Override
public List<GeofenceData> getGeoFencesOfTenant(int tenantId)
throws DeviceManagementDAOException {
try {
List<GeofenceData> geofenceData;
@ -127,12 +187,9 @@ public class GeofenceDAOImpl implements GeofenceDAO {
"OWNER, " +
"TENANT_ID " +
"FROM DM_GEOFENCE " +
"WHERE TENANT_ID = ? " +
"LIMIT ? OFFSET ?";
"WHERE TENANT_ID = ? ";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, tenantId);
stmt.setInt(2, request.getRowCount());
stmt.setInt(3, request.getStartIndex());
try (ResultSet rst = stmt.executeQuery()) {
geofenceData = extractGeofenceData(rst);
}

@ -38,7 +38,6 @@ 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.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.geo.service.Alert;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFence;
@ -46,6 +45,7 @@ import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService;
import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationBasedServiceException;
import org.wso2.carbon.device.mgt.common.geo.service.AlertAlreadyExistException;
import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData;
import org.wso2.carbon.device.mgt.core.cache.impl.GeoCacheManagerImpl;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.GeofenceDAO;
@ -1249,8 +1249,10 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
@Override
public boolean createGeofence(GeofenceData geofenceData) throws GeoLocationBasedServiceException {
int tenantId;
try {
geofenceData.setTenantId(DeviceManagementDAOUtil.getTenantId());
tenantId = DeviceManagementDAOUtil.getTenantId();
geofenceData.setTenantId(tenantId);
geofenceData.setOwner(PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername());
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving tenant Id";
@ -1260,7 +1262,10 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
try {
DeviceManagementDAOFactory.beginTransaction();
return geofenceDAO.saveGeofence(geofenceData) > 0;
geofenceData = geofenceDAO.saveGeofence(geofenceData);
GeoCacheManagerImpl.getInstance()
.addFenceToCache(geofenceData, geofenceData.getId(), tenantId);
return true;
} catch (TransactionManagementException e) {
String msg = "Failed to begin transaction for saving geofence";
log.error(msg, e);
@ -1276,10 +1281,28 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
}
@Override
public GeofenceData getGeofence(int fenceId) throws GeoLocationBasedServiceException {
public GeofenceData getGeoFences(int fenceId) throws GeoLocationBasedServiceException {
int tenantId;
try {
tenantId = DeviceManagementDAOUtil.getTenantId();
GeofenceData geofenceData = GeoCacheManagerImpl.getInstance()
.getGeoFenceFromCache(fenceId, tenantId);
if (geofenceData != null) {
return geofenceData;
}
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving tenant Id";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
}
try {
DeviceManagementDAOFactory.openConnection();
return geofenceDAO.getGeofence(fenceId);
GeofenceData geofence = geofenceDAO.getGeofence(fenceId);
if (geofence != null) {
GeoCacheManagerImpl.getInstance().addFenceToCache(geofence, fenceId, tenantId);
}
return geofence;
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving Geofence data with ID "+fenceId;
log.error(msg, e);
@ -1294,7 +1317,37 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
}
@Override
public List<GeofenceData> getGeofence(PaginationRequest request) throws GeoLocationBasedServiceException {
public List<GeofenceData> getGeoFences(PaginationRequest request) throws GeoLocationBasedServiceException {
int tenantId;
try {
tenantId = DeviceManagementDAOUtil.getTenantId();
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving tenant id while get geofence data";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
}
try {
if (log.isDebugEnabled()) {
log.debug("Retrieving geofence data for the tenant " + tenantId);
}
DeviceManagementDAOFactory.openConnection();
return geofenceDAO.getGeoFencesOfTenant(request, tenantId);
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving geofence data for the tenant " + tenantId;
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
} catch (SQLException e) {
String msg = "Failed to open the DB connection to retrieve Geofence";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
@Override
public List<GeofenceData> getGeoFences(String fenceName) throws GeoLocationBasedServiceException {
int tenantId;
try {
tenantId = DeviceManagementDAOUtil.getTenantId();
@ -1309,7 +1362,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
log.debug("Retrieving geofence data for the tenant " + tenantId);
}
DeviceManagementDAOFactory.openConnection();
return geofenceDAO.getGeofencesOfTenant(request, tenantId);
return geofenceDAO.getGeoFencesOfTenant(fenceName, tenantId);
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving geofence data for the tenant " + tenantId;
log.error(msg, e);
@ -1323,17 +1376,64 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
}
}
@Override
public List<GeofenceData> getGeoFences() throws GeoLocationBasedServiceException {
int tenantId;
try {
tenantId = DeviceManagementDAOUtil.getTenantId();
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving tenant id while get geofence data";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
}
try {
if (log.isDebugEnabled()) {
log.debug("Retrieving all fence data for the tenant " + tenantId);
}
DeviceManagementDAOFactory.openConnection();
List<GeofenceData> geoFencesOfTenant = geofenceDAO.getGeoFencesOfTenant(tenantId);
for (GeofenceData geofenceData : geoFencesOfTenant) {
GeoCacheManagerImpl.getInstance()
.addFenceToCache(geofenceData, geofenceData.getId(), tenantId);
}
return geoFencesOfTenant;
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving geofence data for the tenant " + tenantId;
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
} catch (SQLException e) {
String msg = "Failed to open the DB connection to retrieve Geofence";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
@Override
public boolean deleteGeofenceData(int fenceId) throws GeoLocationBasedServiceException {
int tenantId;
try {
tenantId = DeviceManagementDAOUtil.getTenantId();
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving tenant id while get geofence data";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
}
try {
DeviceManagementDAOFactory.beginTransaction();
if (geofenceDAO.deleteGeofenceById(fenceId) > 0) {
DeviceManagementDAOFactory.commitTransaction();
GeoCacheManagerImpl.getInstance().removeFenceFromCache(fenceId, tenantId);
return true;
}
DeviceManagementDAOFactory.rollbackTransaction();
return false;
} catch (DeviceManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while deleting geofence";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
@ -1349,9 +1449,22 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
@Override
public boolean updateGeofence(GeofenceData geofenceData, int fenceId)
throws GeoLocationBasedServiceException {
int tenantId;
try {
tenantId = DeviceManagementDAOUtil.getTenantId();
} catch (DeviceManagementDAOException e) {
String msg = "Error occurred while retrieving tenant id while get geofence data";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
}
try {
DeviceManagementDAOFactory.beginTransaction();
return geofenceDAO.updateGeofence(geofenceData, fenceId) > 0;
if (geofenceDAO.updateGeofence(geofenceData, fenceId) > 0) {
GeoCacheManagerImpl.getInstance().updateGeoFenceInCache(geofenceData, fenceId, tenantId);
return true;
}
return false;
} catch (TransactionManagementException e) {
String msg = "Failed to begin transaction for saving geofence";
log.error(msg, e);

@ -67,6 +67,7 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceNotFoundException;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData;
import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException;
@ -75,6 +76,7 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementExcept
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import org.wso2.carbon.device.mgt.core.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.core.cache.DeviceCacheKey;
import org.wso2.carbon.device.mgt.core.cache.GeoCacheKey;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
import org.wso2.carbon.device.mgt.core.config.datasource.DataSourceConfig;
@ -132,6 +134,7 @@ public final class DeviceManagerUtil {
public static final String GENERAL_CONFIG_RESOURCE_PATH = "general";
private static boolean isDeviceCacheInitialized = false;
private static boolean isGeoFenceCacheInitialized = false;
public static Document convertToDocument(File file) throws DeviceManagementException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@ -641,6 +644,44 @@ public final class DeviceManagerUtil {
}
}
public static void initializeGeofenceCache() {
DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
int geoCacheExpiry = config.getGeoFenceCacheConfiguration().getExpiryTime();
long geoCacheCapacity = config.getGeoFenceCacheConfiguration().getCapacity();
CacheManager manager = getCacheManager();
if (config.getGeoFenceCacheConfiguration().isEnabled()) {
if(!isGeoFenceCacheInitialized) {
isGeoFenceCacheInitialized = true;
if (manager != null) {
if (geoCacheExpiry > 0) {
manager.<GeoCacheKey, GeofenceData>createCacheBuilder(DeviceManagementConstants.GEOFENCE_CACHE).
setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(TimeUnit.SECONDS,
geoCacheExpiry)).setExpiry(CacheConfiguration.ExpiryType.ACCESSED, new CacheConfiguration.
Duration(TimeUnit.SECONDS, geoCacheExpiry)).setStoreByValue(true).build();
if(geoCacheCapacity > 0 ) {
((CacheImpl) manager.<GeoCacheKey, GeofenceData>getCache(DeviceManagementConstants.GEOFENCE_CACHE)).
setCapacity(geoCacheCapacity);
}
} else {
manager.<GeoCacheKey, GeofenceData>getCache(DeviceManagementConstants.GEOFENCE_CACHE);
}
} else {
if (geoCacheExpiry > 0) {
Caching.getCacheManager().
<GeoCacheKey, GeofenceData>createCacheBuilder(DeviceManagementConstants.GEOFENCE_CACHE).
setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration.Duration(TimeUnit.SECONDS,
geoCacheExpiry)).setExpiry(CacheConfiguration.ExpiryType.ACCESSED, new CacheConfiguration.
Duration(TimeUnit.SECONDS, geoCacheExpiry)).setStoreByValue(true).build();
((CacheImpl)(manager.<GeoCacheKey, GeofenceData>getCache(DeviceManagementConstants.GEOFENCE_CACHE))).
setCapacity(geoCacheCapacity);
} else {
Caching.getCacheManager().<GeoCacheKey, GeofenceData>getCache(DeviceManagementConstants.GEOFENCE_CACHE);
}
}
}
}
}
public static Cache<DeviceCacheKey, Device> getDeviceCache() {
DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
CacheManager manager = getCacheManager();
@ -659,6 +700,24 @@ public final class DeviceManagerUtil {
return deviceCache;
}
public static Cache<GeoCacheKey, GeofenceData> getGeoCache() {
DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
CacheManager manager = getCacheManager();
Cache<GeoCacheKey, GeofenceData> geoCache = null;
if (config.getGeoFenceCacheConfiguration().isEnabled()) {
if(!isGeoFenceCacheInitialized) {
initializeGeofenceCache();
}
if (manager != null) {
geoCache = manager.getCache(DeviceManagementConstants.GEOFENCE_CACHE);
} else {
geoCache = Caching.getCacheManager(DeviceManagementConstants.GEOFENCE_CACHE)
.getCache(DeviceManagementConstants.GEOFENCE_CACHE);
}
}
return geoCache;
}
/**
* Create an app and get app registration token from the application registration endpoint
*

@ -89,6 +89,14 @@
server environment-->
<Capacity>10000</Capacity>
</DeviceCacheConfiguration>
<GeoFenceCacheConfiguration>
<Enable>false</Enable>
<ExpiryTime>600</ExpiryTime>
<!--This configuration specifies the number of cache entries in device cache. default capacity is 10000 entries.
This can be configured to higher number if cache eviction happens due to large number of devices in the
server environment-->
<Capacity>10000</Capacity>
</GeoFenceCacheConfiguration>
<CertificateCacheConfiguration>
<Enable>false</Enable>
<ExpiryTime>86400</ExpiryTime>

@ -40,7 +40,6 @@ import org.apache.commons.lang.StringUtils;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
@ -205,7 +204,7 @@ public class PolicyManagerUtil {
if (log.isDebugEnabled()) {
log.debug("Retrieving geofence with ID " + fenceId);
}
GeofenceData geofence = geoLocationProviderService.getGeofence(fenceId);
GeofenceData geofence = geoLocationProviderService.getGeoFences(fenceId);
if (geofence != null) {
JsonObject operationPayload = new JsonObject();
operationPayload.addProperty("fenceId", geofence.getId());

@ -89,6 +89,14 @@
server environment-->
<Capacity>10000</Capacity>
</DeviceCacheConfiguration>
<GeoFenceCacheConfiguration>
<Enable>true</Enable>
<ExpiryTime>600</ExpiryTime>
<!--This configuration specifies the number of cache entries in device cache. default capacity is 10000 entries.
This can be configured to higher number if cache eviction happens due to large number of devices in the
server environment-->
<Capacity>10000</Capacity>
</GeoFenceCacheConfiguration>
<CertificateCacheConfiguration>
<Enable>true</Enable>
<ExpiryTime>86400</ExpiryTime>

Loading…
Cancel
Save