add Geo fence crossing updates and fences on low power

fixes https://roadmap.entgra.net/issues/11418
geo-fence-issue-id-11418
Inosh Perara 5 months ago
parent 03d6a145d8
commit 0dc138dbb3

@ -0,0 +1,211 @@
/*
* Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.device.mgt.common.geo.service;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* Holds Device updates on events related to fence crossings
*/
@ApiModel(value = "GeoEventDeviceUpdate", description = "This class holds Device updates on events related to fence crossings")
public class GeoEventDeviceUpdate implements Serializable {
private static final long serialVersionUID = 1448121761L;
@ApiModelProperty(name = "id", value = "ID of the event in the database.")
private int id;
@ApiModelProperty(name = "deviceId", value = "IDs of the reporting device")
private String deviceId;
@ApiModelProperty(name = "eventType", value = "Type of fence crossing event.")
private String eventType;
@ApiModelProperty(name = "fenceIds", value = "IDs of the event in the database.")
private int fenceId;
@ApiModelProperty(name = "lat", value = "latitude of the current position")
private double lat;
@ApiModelProperty(name = "lon", value = "longitude of the current position")
private double lon;
@ApiModelProperty(name = "street1", value = "street1 of the current position")
private String street1;
@ApiModelProperty(name = "street2", value = "street2 of the current position")
private String street2;
@ApiModelProperty(name = "city", value = "city of the current position")
private String city;
@ApiModelProperty(name = "zip", value = "zip of the current position")
private String zip;
@ApiModelProperty(name = "state", value = "state of the current position")
private String state;
@ApiModelProperty(name = "country", value = "country of the current position")
private String country;
@ApiModelProperty(name = "altitude", value = "altitude of the current position")
private double altitude;
@ApiModelProperty(name = "speed", value = "speed of the current position")
private float speed;
@ApiModelProperty(name = "bearing", value = "bearing of the current position")
private float bearing;
@ApiModelProperty(name = "distance", value = "distance of the current position")
private float distance;
@ApiModelProperty(name = "updatedTimestamp", value = "updatedTimestamp of the current position")
private long updatedTimestamp;
public long getUpdatedTimestamp() {
return updatedTimestamp;
}
public void setUpdatedTimestamp(long updatedTimestamp) {
this.updatedTimestamp = updatedTimestamp;
}
public String getStreet1() {
return street1;
}
public void setStreet1(String street1) {
this.street1 = street1;
}
public String getStreet2() {
return street2;
}
public void setStreet2(String street2) {
this.street2 = street2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public double getAltitude() {
return altitude;
}
public void setAltitude(double altitude) {
this.altitude = altitude;
}
public float getSpeed() {
return speed;
}
public void setSpeed(float speed) {
this.speed = speed;
}
public float getBearing() {
return bearing;
}
public void setBearing(float bearing) {
this.bearing = bearing;
}
public float getDistance() {
return distance;
}
public void setDistance(float distance) {
this.distance = distance;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public int getFenceId() {
return fenceId;
}
public void setFenceId(int fenceId) {
this.fenceId = fenceId;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLon() {
return lon;
}
public void setLon(double lon) {
this.lon = lon;
}
}

@ -178,4 +178,19 @@ public interface GeoLocationProviderService {
* @throws GeoLocationBasedServiceException any errors occurred while reading event records to geofence * @throws GeoLocationBasedServiceException any errors occurred while reading event records to geofence
*/ */
int getGeoFenceCount() throws GeoLocationBasedServiceException; int getGeoFenceCount() throws GeoLocationBasedServiceException;
/**
* Saves the geo-fence crossing event data for a device.
*
* <p>This method handles the transaction for saving the geo-fence crossing event data
* for a device, including retrieving the tenant ID and handling the necessary
* database operations. If any error occurs during the transaction, appropriate
* exceptions are thrown.
*
* @param geofenceData the geo-fence crossing event data to be saved.
* @return always returns {@code false}.
* @throws GeoLocationBasedServiceException if there is an error during the transaction
* or database operations.
*/
boolean saveGeoFenceCrossingDevice(GeoEventDeviceUpdate geofenceData) throws GeoLocationBasedServiceException;
} }

@ -20,6 +20,7 @@ package io.entgra.device.mgt.core.device.mgt.core.dao;
import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest;
import io.entgra.device.mgt.core.device.mgt.common.event.config.EventConfig; import io.entgra.device.mgt.core.device.mgt.common.event.config.EventConfig;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoEventDeviceUpdate;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeofenceData; import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeofenceData;
import io.entgra.device.mgt.core.device.mgt.core.dto.event.config.GeoFenceGroupMap; import io.entgra.device.mgt.core.device.mgt.core.dto.event.config.GeoFenceGroupMap;
@ -182,4 +183,18 @@ public interface GeofenceDAO {
* @throws DeviceManagementDAOException * @throws DeviceManagementDAOException
*/ */
int getGeofenceCount(int tenantId) throws DeviceManagementDAOException; int getGeofenceCount(int tenantId) throws DeviceManagementDAOException;
/**
* Adds a geo-fence crossing event to the database for a specific device.
*
* <p>This method inserts the geo-fence crossing event data into the database. The data includes
* details about the device, event type, location coordinates, and additional contextual information.
* The method returns the generated ID of the newly inserted record.
*
* @param tenantId the tenant ID associated with the event.
* @param deviceEvent the geo-fence crossing event data to be added.
* @return the generated ID of the newly inserted record, or -1 if the insertion failed.
* @throws DeviceManagementDAOException if there is an error during the database operation.
*/
int addGeoFenceCrossingDevice(int tenantId, GeoEventDeviceUpdate deviceEvent) throws DeviceManagementDAOException;
} }

@ -18,6 +18,7 @@
package io.entgra.device.mgt.core.device.mgt.core.dao.impl; package io.entgra.device.mgt.core.device.mgt.core.dao.impl;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoEventDeviceUpdate;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import io.entgra.device.mgt.core.device.mgt.common.DeviceManagementConstants; import io.entgra.device.mgt.core.device.mgt.common.DeviceManagementConstants;
@ -28,6 +29,7 @@ import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOExceptio
import io.entgra.device.mgt.core.device.mgt.core.dao.EventManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.EventManagementDAOFactory;
import io.entgra.device.mgt.core.device.mgt.core.dao.GeofenceDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.GeofenceDAO;
import io.entgra.device.mgt.core.device.mgt.core.dto.event.config.GeoFenceGroupMap; import io.entgra.device.mgt.core.device.mgt.core.dto.event.config.GeoFenceGroupMap;
import org.wso2.carbon.context.CarbonContext;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -668,4 +670,66 @@ public abstract class AbstractGeofenceDAOImpl implements GeofenceDAO {
} }
} }
@Override
public int addGeoFenceCrossingDevice(int tenantId, GeoEventDeviceUpdate deviceEvent) throws DeviceManagementDAOException {
try {
CarbonContext context = CarbonContext.getThreadLocalCarbonContext();
String username = context.getUsername();
int genId = -1;
Connection conn = this.getConnection();
String sql = "INSERT INTO DM_GEOFECE_DEVICE_EVENT(" +
"DEVICE_ID, " +
"EVENT_TYPE, " +
"FENCE_ID, " +
"LATITUDE, " +
"LONGITUDE, " +
"UPDATE_TIMESTAMP, " +
"USERNAME, " +
"TENANT_ID," +
"STREET1, " +
"STREET2, " +
"CITY, " +
"ZIP, " +
"STATE, " +
"COUNTRY, " +
"ALTITUDE," +
"SPEED, " +
"BEARING," +
"DISTANCE) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
stmt.setString(1, deviceEvent.getDeviceId());
stmt.setString(2, deviceEvent.getEventType());
stmt.setInt(3, deviceEvent.getFenceId());
stmt.setDouble(4, deviceEvent.getLat());
stmt.setDouble(5, deviceEvent.getLon());
stmt.setTimestamp(6, new Timestamp(deviceEvent.getUpdatedTimestamp()));
stmt.setString(7, username);
stmt.setInt(8, tenantId);
stmt.setString(9, deviceEvent.getStreet1());
stmt.setString(10, deviceEvent.getStreet2());
stmt.setString(11, deviceEvent.getCity());
stmt.setString(12, deviceEvent.getZip());
stmt.setString(13, deviceEvent.getState());
stmt.setString(14, deviceEvent.getCountry());
stmt.setDouble(15, deviceEvent.getAltitude());
stmt.setFloat(16, deviceEvent.getSpeed());
stmt.setFloat(17, deviceEvent.getBearing());
stmt.setFloat(18, deviceEvent.getDistance());
if (stmt.executeUpdate() > 0) {
ResultSet generatedKeys = stmt.getGeneratedKeys();
if (generatedKeys.next()) {
genId = generatedKeys.getInt(1);
}
}
return genId;
}
} catch (SQLException e) {
String msg = "Error occurred while creating Geofence event for the fence id " + deviceEvent.getFenceId() + " from device id: " + deviceEvent.getDeviceId();
log.error(msg, e);
throw new DeviceManagementDAOException(msg, e);
}
}
} }

@ -20,6 +20,7 @@ package io.entgra.device.mgt.core.device.mgt.core.geo.service;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.*;
import org.apache.axis2.AxisFault; import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options; import org.apache.axis2.client.Options;
import org.apache.axis2.client.Stub; import org.apache.axis2.client.Stub;
@ -43,13 +44,6 @@ import io.entgra.device.mgt.core.device.mgt.common.event.config.EventConfig;
import io.entgra.device.mgt.core.device.mgt.common.event.config.EventConfigurationException; import io.entgra.device.mgt.core.device.mgt.common.event.config.EventConfigurationException;
import io.entgra.device.mgt.core.device.mgt.common.event.config.EventConfigurationProviderService; import io.entgra.device.mgt.core.device.mgt.common.event.config.EventConfigurationProviderService;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException; import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.Alert;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.AlertAlreadyExistException;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoFence;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoFenceEventMeta;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoLocationBasedServiceException;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeoLocationProviderService;
import io.entgra.device.mgt.core.device.mgt.common.geo.service.GeofenceData;
import io.entgra.device.mgt.core.device.mgt.core.cache.impl.GeoCacheManagerImpl; import io.entgra.device.mgt.core.device.mgt.core.cache.impl.GeoCacheManagerImpl;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory;
@ -1773,6 +1767,37 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
} }
} }
@Override
public boolean saveGeoFenceCrossingDevice(GeoEventDeviceUpdate geofenceData) 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 {
EventManagementDAOFactory.beginTransaction();
geofenceDAO.addGeoFenceCrossingDevice(tenantId, geofenceData);
EventManagementDAOFactory.commitTransaction();
} catch (TransactionManagementException e) {
String msg = "Failed to begin transaction for saving geofence";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
} catch (DeviceManagementDAOException e) {
EventManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while saving geofence";
log.error(msg, e);
throw new GeoLocationBasedServiceException(msg, e);
} finally {
EventManagementDAOFactory.closeConnection();
}
return false;
}
/** /**
* Delete events of geofence * Delete events of geofence
* *

Loading…
Cancel
Save