diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java index 15be83e36af..2121c6135ec 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java @@ -979,7 +979,11 @@ public interface GeoLocationBasedService { @ApiParam( name = "name", value = "Geo Fence name") - @QueryParam("name") String name); + @QueryParam("name") String name, + @ApiParam( + name = "requireEventData", + value = "Require geofence event data") + @QueryParam("requireEventData") boolean requireEventData); @DELETE diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java index 686d932f832..399d24383fd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java @@ -18,7 +18,9 @@ package org.wso2.carbon.device.mgt.jaxrs.service.impl; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import com.google.gson.Gson; import jdk.nashorn.internal.parser.JSONParser; import org.apache.commons.logging.Log; @@ -66,6 +68,7 @@ import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import javax.ws.rs.*; import javax.ws.rs.core.Response; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -674,16 +677,43 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { geofenceWrapper.setRadius(geofenceData.getRadius()); geofenceWrapper.setGeoJson(geofenceData.getGeoJson()); geofenceWrapper.setFenceShape(geofenceData.getFenceShape()); + geofenceWrapper.setGroupIds(geofenceData.getGroupIds()); + if (geofenceData.getEventConfig() != null) { + geofenceWrapper.setEventConfig(getEventConfigBean(geofenceData.getEventConfig())); + } return geofenceWrapper; } + private List getEventConfigBean(List eventConfig) { + List eventList = new ArrayList<>(); + org.wso2.carbon.device.mgt.jaxrs.beans.EventConfig eventData; + for (EventConfig event : eventConfig) { + eventData = new org.wso2.carbon.device.mgt.jaxrs.beans.EventConfig(); + eventData.setId(event.getEventId()); + eventData.setEventLogic(event.getEventLogic()); + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + try { + List eventActions = mapper.readValue(event.getActions(), mapper.getTypeFactory(). + constructCollectionType(List.class, EventAction.class)); + eventData.setActions(eventActions); + } catch (IOException e) { + log.error("Error occurred while parsing event actions of the event with ID " + event.getEventId()); + } + eventList.add(eventData); + } + return eventList; + } + @Path("/geo-fence") @GET @Consumes("application/json") @Produces("application/json") public Response getGeofence(@QueryParam("offset") int offset, @QueryParam("limit") int limit, - @QueryParam("name") String name) { + @QueryParam("name") String name, + @QueryParam("requireEventData") boolean requireEventData) { try { GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); if (offset >= 0 && limit != 0) { @@ -691,10 +721,18 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { if (name != null && !name.isEmpty()) { request.setProperty(DeviceManagementConstants.GeoServices.FENCE_NAME, name); } - return getResponse(geoService.getGeoFences(request)); + List geoFences = geoService.getGeoFences(request); + if (requireEventData) { + geoFences = geoService.getGeoFenceEvents(geoFences); + } + return getResponse(geoFences); } if (name != null && !name.isEmpty()) { - return getResponse(geoService.getGeoFences(name)); + List geoFences = geoService.getGeoFences(name); + if (requireEventData) { + geoFences = geoService.getGeoFenceEvents(geoFences); + } + return getResponse(geoFences); } return getResponse(geoService.getGeoFences()); } catch (GeoLocationBasedServiceException e) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoLocationProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoLocationProviderService.java index 99f56da8ffe..01d83d7167b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoLocationProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoLocationProviderService.java @@ -145,4 +145,6 @@ public interface GeoLocationProviderService { */ boolean updateGeoEventConfigurations(List eventConfig, List removedEventIdList, List groupIds, int fenceId) throws GeoLocationBasedServiceException; + + List getGeoFenceEvents(List geoFences) throws GeoLocationBasedServiceException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/GeofenceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/GeofenceDAO.java index a2c9e86d207..21be3bbb95f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/GeofenceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/GeofenceDAO.java @@ -19,9 +19,11 @@ package org.wso2.carbon.device.mgt.core.dao; import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.event.config.EventConfig; import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData; import java.util.List; +import java.util.Map; /** * Use to manage geofence data in DB @@ -128,4 +130,10 @@ public interface GeofenceDAO { * @throws DeviceManagementDAOException error occurred deleting geofence event mapping */ void deleteGeofenceEventMapping(List removedEventIdList) throws DeviceManagementDAOException; + + Map> getEventsOfGeoFences(List geofenceIds) throws DeviceManagementDAOException; + + List getEventsOfGeoFence(int geofenceId) throws DeviceManagementDAOException; + + Map> getGroupIdsOfGeoFences(List fenceIds) throws DeviceManagementDAOException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GeofenceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GeofenceDAOImpl.java index 2ef9f8b8962..a915486947e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GeofenceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GeofenceDAOImpl.java @@ -22,6 +22,7 @@ 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.event.config.EventConfig; import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationBasedServiceException; import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; @@ -35,8 +36,11 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class GeofenceDAOImpl implements GeofenceDAO { private static final Log log = LogFactory.getLog(GeofenceDAOImpl.class); @@ -408,4 +412,125 @@ public class GeofenceDAOImpl implements GeofenceDAO { throw new DeviceManagementDAOException(msg, e); } } + + @Override + public Map> getEventsOfGeoFences(List geofenceIds) throws DeviceManagementDAOException { + try { + Map> geoFenceEventMap = new HashMap<>(); + List eventList = new ArrayList<>(); + Connection conn = this.getConnection(); + String sql = "SELECT " + + "E.ID AS EVENT_ID, " + + "M.FENCE_ID AS FENCE_ID, " + + "EVENT_SOURCE, " + + "EVENT_LOGIC, " + + "ACTIONS " + + "FROM DM_DEVICE_EVENT E, DM_GEOFENCE_EVENT_MAPPING M " + + "WHERE E.ID = M.EVENT_ID " + + "AND M.FENCE_ID IN (%s)"; + String inClause = String.join(", ", Collections.nCopies(geofenceIds.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer geofenceId : geofenceIds) { + stmt.setInt(index++, geofenceId); + } + ResultSet resultSet = stmt.executeQuery(); + while (resultSet.next()) { + int fenceId = resultSet.getInt("FENCE_ID"); + List eventConfigList = geoFenceEventMap.get(fenceId); + if (eventConfigList == null) { + eventConfigList = new ArrayList<>(); + } + EventConfig event = new EventConfig(); + event.setEventId(resultSet.getInt("EVENT_ID")); + event.setEventSource(resultSet.getString("EVENT_SOURCE")); + event.setEventLogic(resultSet.getString("EVENT_LOGIC")); + event.setActions(resultSet.getString("ACTIONS")); + eventConfigList.add(event); + geoFenceEventMap.put(fenceId, eventConfigList); + } + return geoFenceEventMap; + } + } catch (SQLException e) { + String msg = "Error occurred while updating Geofence record with id "; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public List getEventsOfGeoFence(int geofenceId) throws DeviceManagementDAOException { + try { + List eventList = new ArrayList<>(); + Connection conn = this.getConnection(); + String sql = "SELECT " + + "ID AS EVENT_ID, " + + "EVENT_SOURCE, " + + "EVENT_LOGIC, " + + "ACTIONS " + + "FROM DM_DEVICE_EVENT " + + "WHERE ID IN (" + + "SELECT EVENT_ID FROM DM_GEOFENCE_EVENT_MAPPING " + + "WHERE FENCE_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, geofenceId); + return getEventConfigs(eventList, stmt); + } + } catch (SQLException e) { + String msg = "Error occurred while updating Geofence record with id "; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public Map> getGroupIdsOfGeoFences(List fenceIds) throws DeviceManagementDAOException { + try { + Map> fenceGroupMap = new HashMap<>(); + Connection conn = this.getConnection(); + String sql = "SELECT " + + "FENCE_ID, " + + "GROUP_ID " + + "FROM DM_GEOFENCE_GROUP_MAPPING " + + "WHERE FENCE_ID IN (%s) "; + String inClause = String.join(", ", Collections.nCopies(fenceIds.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer fenceId : fenceIds) { + stmt.setInt(index++, fenceId); + } + ResultSet rst = stmt.executeQuery(); + while (rst.next()) { + int fenceId = rst.getInt("FENCE_ID"); + List groupIdList = fenceGroupMap.get(fenceId); + if (groupIdList == null) { + groupIdList = new ArrayList<>(); + } + groupIdList.add(rst.getInt("GROUP_ID")); + fenceGroupMap.put(fenceId, groupIdList); + } + } + return fenceGroupMap; + } catch (SQLException e) { + String msg = "Error occurred while fetching group IDs of the fences"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + private List getEventConfigs(List eventList, PreparedStatement stmt) throws SQLException { + ResultSet resultSet = stmt.executeQuery(); + EventConfig event; + while (resultSet.next()) { + event = new EventConfig(); + event.setEventId(resultSet.getInt("EVENT_ID")); + event.setEventSource(resultSet.getString("EVENT_SOURCE")); + event.setEventLogic(resultSet.getString("EVENT_LOGIC")); + event.setActions(resultSet.getString("ACTIONS")); + eventList.add(event); + } + return eventList; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoLocationProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoLocationProviderServiceImpl.java index 38f7e01a1b0..735d8cd27d8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoLocationProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoLocationProviderServiceImpl.java @@ -1613,4 +1613,32 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } return true; } + + @Override + public List getGeoFenceEvents(List geoFences) throws GeoLocationBasedServiceException { + try { + DeviceManagementDAOFactory.openConnection(); + List fenceIds = new ArrayList<>(); + for (GeofenceData geoFence : geoFences) { + fenceIds.add(geoFence.getId()); + } + Map> eventsOfGeoFences = geofenceDAO.getEventsOfGeoFences(fenceIds); + Map> groupIdsOfGeoFences = geofenceDAO.getGroupIdsOfGeoFences(fenceIds); + for (GeofenceData geoFence : geoFences) { + geoFence.setEventConfig(eventsOfGeoFences.get(geoFence.getId())); + geoFence.setGroupIds(groupIdsOfGeoFences.get(geoFence.getId())); + } + return geoFences; + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred while retrieving geo fence events/groups data"; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } catch (SQLException e) { + String msg = "Failed open DB connection while getting geo fence event data"; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + } }