From af85ca47e00dea88e2fbbe27ad19f1b9aa74d3fd Mon Sep 17 00:00:00 2001 From: Pahansith Date: Mon, 9 Nov 2020 13:55:16 +0530 Subject: [PATCH] Change Geo fence edit API - Attach Events --- .../device/mgt/jaxrs/beans/EventAction.java | 6 +- .../device/mgt/jaxrs/beans/EventConfig.java | 20 +- .../mgt/jaxrs/beans/GeofenceWrapper.java | 13 +- .../service/api/GeoLocationBasedService.java | 7 +- .../impl/GeoLocationBasedServiceImpl.java | 68 ++++-- .../impl/util/RequestValidationUtil.java | 26 +++ .../mgt/common/event/config/EventConfig.java | 12 +- .../EventConfigurationProviderService.java | 23 +- .../service/GeoLocationProviderService.java | 19 +- .../device/mgt/core/dao/EventConfigDAO.java | 63 +++++- .../device/mgt/core/dao/GeofenceDAO.java | 37 ++++ .../mgt/core/dao/impl/EventConfigDAOImpl.java | 208 +++++++++++++++++- .../mgt/core/dao/impl/GeofenceDAOImpl.java | 86 ++++++++ ...EventConfigurationProviderServiceImpl.java | 99 ++++++++- .../GeoLocationProviderServiceImpl.java | 124 ++++++++++- .../main/resources/dbscripts/cdm/mysql.sql | 16 +- 16 files changed, 769 insertions(+), 58 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventAction.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventAction.java index cbffd99bba8..61f58704830 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventAction.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventAction.java @@ -24,12 +24,14 @@ public class EventAction { @ApiModelProperty( name = "actionType", - value = "Type of the event action to be triggered in the device level") + value = "Type of the event action to be triggered in the device level", + required = true) private String actionType; @ApiModelProperty( name = "payload", - value = "Payload of the event action") + value = "Payload of the event action", + required = true) private Object payload; public String getActionType() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventConfig.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventConfig.java index 18d85175ad7..2d1ba340052 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventConfig.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EventConfig.java @@ -23,14 +23,22 @@ import io.swagger.annotations.ApiModelProperty; import java.util.List; public class EventConfig { + + @ApiModelProperty( + name = "id", + value = "id of the event entry") + private int id; + @ApiModelProperty( name = "eventLogic", - value = "Logic of the event should be handled at the device level") + value = "Logic of the event should be handled at the device level", + required = true) private String eventLogic; @ApiModelProperty( name = "actions", - value = "List of actions to be triggered according to the logic") + value = "List of actions to be triggered according to the logic", + required = true) private List actions; public String getEventLogic() { @@ -48,4 +56,12 @@ public class EventConfig { public void setActions(List actions) { this.actions = actions; } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/GeofenceWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/GeofenceWrapper.java index a39b5a2f5d7..8e33462913e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/GeofenceWrapper.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/GeofenceWrapper.java @@ -37,8 +37,7 @@ public class GeofenceWrapper { @ApiModelProperty( name = "description", - value = "Description of the geo fence", - required = true) + value = "Description of the geo fence") private String description; @ApiModelProperty( @@ -63,14 +62,20 @@ public class GeofenceWrapper { @ApiModelProperty( name = "fenceShape", - value = "Shape of the fence") + value = "Shape of the fence", + required = true) private String fenceShape; @ApiModelProperty( name = "eventConfig", - value = "Event configuration of the geofence") + value = "Event configuration of the geofence", + required = true) private List eventConfig; + @ApiModelProperty( + name = "groupIds", + value = "Group ids to add geo fences", + required = true) private List groupIds; public int getId() { 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 56f74ec26d6..15be83e36af 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 @@ -51,6 +51,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.util.ArrayList; @SwaggerDefinition( info = @Info( @@ -1069,11 +1070,13 @@ public interface GeoLocationBasedService { response = Response.class) }) Response updateGeofence( - @ApiParam(name = "fence", value = "Geo fence data")GeofenceWrapper geofenceWrapper, + @ApiParam(name = "fence", value = "Geo fence data") + GeofenceWrapper geofenceWrapper, @ApiParam( name = "fenceId", value = "Id of the fence", required = true) - @PathParam("fenceId") int fenceId); + @PathParam("fenceId") int fenceId, + @ApiParam(name = "eventIds", value = "Event id list to be removed") @QueryParam("eventIds") int[] eventIds); } 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 3f1e4449625..686d932f832 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 @@ -23,6 +23,7 @@ import com.google.gson.Gson; import jdk.nashorn.internal.parser.JSONParser; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpStatus; import org.wso2.carbon.analytics.api.AnalyticsDataAPI; import org.wso2.carbon.analytics.api.AnalyticsDataAPIUtil; import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse; @@ -55,6 +56,7 @@ import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.EventAction; 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.InputValidationException; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.Constants; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; @@ -597,17 +599,9 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @Produces("application/json") public Response createGeofence(GeofenceWrapper geofenceWrapper) { RequestValidationUtil.validateGeofenceData(geofenceWrapper); + RequestValidationUtil.validateEventConfigurationData(geofenceWrapper.getEventConfig()); try { - GeofenceData geofenceData = new GeofenceData(); - geofenceData.setFenceName(geofenceWrapper.getFenceName()); - geofenceData.setDescription(geofenceWrapper.getDescription()); - geofenceData.setLatitude(geofenceWrapper.getLatitude()); - geofenceData.setLongitude(geofenceWrapper.getLongitude()); - geofenceData.setRadius(geofenceWrapper.getRadius()); - geofenceData.setGeoJson(geofenceWrapper.getGeoJson()); - geofenceData.setFenceShape(geofenceWrapper.getFenceShape()); - geofenceData.setGroupIds(geofenceWrapper.getGroupIds()); - geofenceData.setEventConfig(mapRequestEvent(geofenceWrapper.getEventConfig())); + GeofenceData geofenceData = mapRequestGeofenceData(geofenceWrapper); GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); if (!geoService.createGeofence(geofenceData)) { String msg = "Failed to create geofence"; @@ -633,6 +627,11 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { List savingEventList = new ArrayList<>(); for (org.wso2.carbon.device.mgt.jaxrs.beans.EventConfig event : eventConfig) { EventConfig savingConfig = new EventConfig(); + if (event.getId() > 0) { + savingConfig.setEventId(event.getId()); + } else { + savingConfig.setEventId(-1); + } savingConfig.setEventLogic(event.getEventLogic()); String eventJson = new Gson().toJson(event.getActions()); savingConfig.setActions(eventJson); @@ -740,28 +739,55 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @PUT @Consumes("application/json") @Produces("application/json") - public Response updateGeofence(GeofenceWrapper geofenceWrapper, @PathParam("fenceId") int fenceId) { + public Response updateGeofence(GeofenceWrapper geofenceWrapper, + @PathParam("fenceId") int fenceId, + @QueryParam("eventIds") int[] eventIds) { RequestValidationUtil.validateGeofenceData(geofenceWrapper); + RequestValidationUtil.validateEventConfigurationData(geofenceWrapper.getEventConfig()); try { - GeofenceData geofenceData = new GeofenceData(); - geofenceData.setFenceName(geofenceWrapper.getFenceName()); - geofenceData.setDescription(geofenceWrapper.getDescription()); - geofenceData.setLatitude(geofenceWrapper.getLatitude()); - geofenceData.setLongitude(geofenceWrapper.getLongitude()); - geofenceData.setRadius(geofenceWrapper.getRadius()); - geofenceData.setFenceShape(geofenceWrapper.getFenceShape()); - geofenceData.setGeoJson(geofenceWrapper.getGeoJson()); + GeofenceData geofenceData = mapRequestGeofenceData(geofenceWrapper); GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); if (!geoService.updateGeofence(geofenceData, fenceId)) { String msg = "No valid Geofence found for ID " + fenceId; log.error(msg); return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); } - return Response.status(Response.Status.CREATED).build(); + List eventsToRemove = new ArrayList<>(); + for (int eventId : eventIds) { + eventsToRemove.add(eventId); + } + geoService.updateGeoEventConfigurations(geofenceData.getEventConfig(), eventsToRemove, + geofenceData.getGroupIds(), fenceId); + return Response.status(Response.Status.CREATED).entity("Geo Fence update successfully").build(); } catch (GeoLocationBasedServiceException e) { - String msg = "Failed to create geofence"; + String msg = "Failed to update geofence"; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (EventConfigurationException e) { + String msg = "Failed to update geofence events"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + private GeofenceData mapRequestGeofenceData(GeofenceWrapper geofenceWrapper) { + GeofenceData geofenceData = new GeofenceData(); + geofenceData.setFenceName(geofenceWrapper.getFenceName()); + geofenceData.setDescription(geofenceWrapper.getDescription()); + geofenceData.setLatitude(geofenceWrapper.getLatitude()); + geofenceData.setLongitude(geofenceWrapper.getLongitude()); + geofenceData.setRadius(geofenceWrapper.getRadius()); + geofenceData.setFenceShape(geofenceWrapper.getFenceShape()); + geofenceData.setGeoJson(geofenceWrapper.getGeoJson()); + if (geofenceWrapper.getGroupIds() == null || geofenceWrapper.getGroupIds().isEmpty()) { + String msg = "Group ID / IDs are mandatory, since cannot be null or empty"; + log.error(msg); + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST) + .setMessage(msg).build()); } + geofenceData.setGroupIds(geofenceWrapper.getGroupIds()); + geofenceData.setEventConfig(mapRequestEvent(geofenceWrapper.getEventConfig())); + return geofenceData; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java index c588d7fd912..b227f9a231d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java @@ -35,6 +35,7 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.EventConfig; import org.wso2.carbon.device.mgt.jaxrs.beans.GeofenceWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; import org.wso2.carbon.device.mgt.jaxrs.beans.PolicyWrapper; @@ -719,4 +720,29 @@ public class RequestValidationUtil { new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build()); } } + + public static void validateEventConfigurationData(List eventConfig) { + if (eventConfig == null ||eventConfig.isEmpty()) { + String msg = "Event configuration is mandatory, since should not be null or empty"; + log.error(msg); + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build()); + } + + for (EventConfig config : eventConfig) { + if (config.getActions() == null || config.getActions().isEmpty()) { + String msg = "Event actions are mandatory, since should not be null or empty"; + log.error(msg); + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build()); + } + + if (config.getEventLogic() == null || config.getEventLogic().trim().isEmpty()) { + String msg = "Event logic is mandatory, since should not be null or empty"; + log.error(msg); + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(HttpStatus.SC_BAD_REQUEST).setMessage(msg).build()); + } + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/event/config/EventConfig.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/event/config/EventConfig.java index 45a53e3f622..c616ad433d2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/event/config/EventConfig.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/event/config/EventConfig.java @@ -18,8 +18,6 @@ package org.wso2.carbon.device.mgt.common.event.config; -import java.util.List; - public class EventConfig { private int eventId; private String eventSource; @@ -57,4 +55,14 @@ public class EventConfig { public void setEventSource(String eventSource) { this.eventSource = eventSource; } + + @Override + public boolean equals(Object obj) { + if (obj instanceof EventConfig) { + EventConfig eventConfig = (EventConfig) obj; + return this.eventSource.equalsIgnoreCase(eventConfig.getEventSource()) && + this.eventLogic.equalsIgnoreCase(eventConfig.getEventLogic()); + } + return false; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/event/config/EventConfigurationProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/event/config/EventConfigurationProviderService.java index acd22583c67..94af7cbac14 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/event/config/EventConfigurationProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/event/config/EventConfigurationProviderService.java @@ -21,6 +21,27 @@ package org.wso2.carbon.device.mgt.common.event.config; import java.util.List; public interface EventConfigurationProviderService { - boolean createEventOfDeviceGroup(List eventConfigList, List groupIds, int tenantId) + /** + * Create event configuration records + * @param eventConfigList event list to be added + * @param groupIds group ids of the events are mapped + * @param tenantId events owning tenant id + * @return generated event ids + * @throws EventConfigurationException errors thrown while creating event configuration + */ + List createEventsOfDeviceGroup(List eventConfigList, List groupIds, int tenantId) throws EventConfigurationException; + + /** + * Update event configuration records + * @param eventConfig updated event configuration list. event ids should be present for + * the updating events and event ids should be -1 for the newly creating events + * @param removedEventIdList event ids of removed while updating the event configuration + * @param groupIds group ids to be mapped with updated events + * @param tenantId + * @return + * @throws EventConfigurationException + */ + List updateEventsOfDeviceGroup(List eventConfig, List removedEventIdList, + List groupIds, int tenantId) throws EventConfigurationException; } 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 e67efc27636..99f56da8ffe 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 @@ -21,8 +21,10 @@ package org.wso2.carbon.device.mgt.common.geo.service; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.event.config.EventConfig; import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationException; +import java.util.ArrayList; import java.util.List; /** @@ -78,6 +80,7 @@ public interface GeoLocationProviderService { * @param geofenceData fence data * @return true if the fence creation success * @throws GeoLocationBasedServiceException error occurs while creating a geofence + * @throws EventConfigurationException for errors occur while creating event configuration for the geofence */ boolean createGeofence(GeofenceData geofenceData) throws GeoLocationBasedServiceException, EventConfigurationException; @@ -126,6 +129,20 @@ public interface GeoLocationProviderService { * @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 for errors occur while updating geo fences + * @throws EventConfigurationException for errors occur while updating event records of the geofence */ - boolean updateGeofence(GeofenceData geofenceData, int fenceId) throws GeoLocationBasedServiceException; + boolean updateGeofence(GeofenceData geofenceData, int fenceId) + throws GeoLocationBasedServiceException, EventConfigurationException; + + /** + * Update geofence event configuration + * @param eventConfig updated event configurations list + * @param removedEventIdList removed event ids + * @param groupIds newly added group ids to be mapped with event records + * @param fenceId updating fence id + * @return true for successful update of geofence event data + * @throws GeoLocationBasedServiceException any errors occurred while updating event records of the fence + */ + boolean updateGeoEventConfigurations(List eventConfig, List removedEventIdList, + List groupIds, int fenceId) throws GeoLocationBasedServiceException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EventConfigDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EventConfigDAO.java index 823f24c3b62..c7fe0a2280b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EventConfigDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EventConfigDAO.java @@ -23,7 +23,66 @@ import org.wso2.carbon.device.mgt.common.event.config.EventConfig; import java.util.List; public interface EventConfigDAO { - int[] storeEventRecords(List eventConfigList, int tenantId) throws EventManagementDAOException; + /** + * Create event configuration entries of the db for a selected tenant + * @param eventConfigList event list to be created + * @param tenantId corresponding tenant id of the events + * @return generated event ids while storing geofence data + * @throws EventManagementDAOException error occurred while creating event records + */ + List storeEventRecords(List eventConfigList, int tenantId) throws EventManagementDAOException; - boolean addEventGroupMappingRecords(int[] generatedEventIds, List groupIds) throws EventManagementDAOException; + /** + * Cerate even-group mapping records + * @param eventIds event ids to be mapped with groups + * @param groupIds group ids of the event attached with + * @return true for the successful creation + * @throws EventManagementDAOException error occurred while creating event-group mapping records + */ + boolean addEventGroupMappingRecords(List eventIds, List groupIds) throws EventManagementDAOException; + + /** + * Get events owned by a specific device group + * @param groupIds group ids of the events + * @param tenantId tenant of the events owning + * @return list of event configuration filtered by tenant id and group ids + * @throws EventManagementDAOException error occurred while reading event records + */ + List getEventsOfGroups(List groupIds, int tenantId) throws EventManagementDAOException; + + /** + * Delete event group mapping records using the group ids + * @param groupIdsToDelete id of groups + * @throws EventManagementDAOException error occurred while deleting event-group mapping records + */ + void deleteEventGroupMappingRecordsByGroupIds(List groupIdsToDelete) throws EventManagementDAOException; + + /** + * Update event records of the tenant + * @param eventsToUpdate updating event records + * @param tenantId event owning tenant id + * @throws EventManagementDAOException error occurred while updating events + */ + void updateEventRecords(List eventsToUpdate, int tenantId) throws EventManagementDAOException; + + /** + * Delete events using event ids + * @param eventsIdsToDelete ids of the events which should be deleted + * @param tenantId event owning tenant id + * @throws EventManagementDAOException error occurred while deleting event records + */ + void deleteEventRecords(List eventsIdsToDelete, int tenantId) throws EventManagementDAOException; + + /** + * Get event records by event ids + * @param eventIds filtering event ids + * @param tenantId tenant id of the events + * @return filtered event configuration list + * @throws EventManagementDAOException error occurred while reading events + */ + List getEventsById(List eventIds, int tenantId) throws EventManagementDAOException; + + List getGroupsOfEvents(List updateEventIdList) throws EventManagementDAOException; + + void deleteEventGroupMappingRecordsByEventIds(List removedEventIdList) throws EventManagementDAOException; } 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 d663c688c67..a2c9e86d207 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 @@ -90,5 +90,42 @@ public interface GeofenceDAO { */ int updateGeofence(GeofenceData geofenceData, int fenceId) throws DeviceManagementDAOException; + /** + * Create geofence-group mapping records for the fence associated groups + * @param geofenceData geofence data to be mapped with device group + * @param groupIds group ids of the geofence + * @return true for the successful record creation + * @throws DeviceManagementDAOException error occurred while saving event records + */ boolean createGeofenceGroupMapping(GeofenceData geofenceData, List groupIds) throws DeviceManagementDAOException; + + /** + * Get associated group ids of a geofence mapped with + * @param fenceId id of the fence + * @return list of group ids mapped with the specified fence + * @throws DeviceManagementDAOException error occurred while reading group id records + */ + List getGroupIdsOfGeoFence(int fenceId) throws DeviceManagementDAOException; + + /** + * Delete geofence-group mapping records + * @param groupIdsToDelete group ids to be removed from the mapping table + * @throws DeviceManagementDAOException error occurred while deleting group id mapping records + */ + void deleteGeofenceGroupMapping(List groupIdsToDelete) throws DeviceManagementDAOException; + + /** + * Create geofence-event mapping records + * @param fenceId geofence id of the mapping records to be placed + * @param eventIds generated event ids for the geofence event configuration + * @throws DeviceManagementDAOException error occurred while creating geofence event mapping records + */ + void createGeofenceEventMapping(int fenceId, List eventIds) throws DeviceManagementDAOException; + + /** + * Remove geofence-event mapping records + * @param removedEventIdList event ids should be removed from the records + * @throws DeviceManagementDAOException error occurred deleting geofence event mapping + */ + void deleteGeofenceEventMapping(List removedEventIdList) 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/EventConfigDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EventConfigDAOImpl.java index 37789bbcb00..fa27cc548cf 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EventConfigDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EventConfigDAOImpl.java @@ -32,6 +32,8 @@ import java.sql.ResultSet; 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.List; @@ -39,7 +41,7 @@ public class EventConfigDAOImpl implements EventConfigDAO { private static final Log log = LogFactory.getLog(EventConfigDAOImpl.class); @Override - public int[] storeEventRecords(List eventConfigList, int tenantId) throws EventManagementDAOException { + public List storeEventRecords(List eventConfigList, int tenantId) throws EventManagementDAOException { try { Connection conn = this.getConnection(); String sql = "INSERT INTO DM_DEVICE_EVENT(" + @@ -49,8 +51,6 @@ public class EventConfigDAOImpl implements EventConfigDAO { "CREATED_TIMESTAMP, " + "TENANT_ID) " + "VALUES (?, ?, ?, ?, ?)"; - - try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { for (EventConfig eventConfig : eventConfigList) { stmt.setString(1, eventConfig.getEventSource()); @@ -61,11 +61,11 @@ public class EventConfigDAOImpl implements EventConfigDAO { stmt.addBatch(); } int[] createdRowCount = stmt.executeBatch(); - int[] generatedIds = new int[createdRowCount.length]; + List generatedIds = new ArrayList<>(); ResultSet generatedKeys = stmt.getGeneratedKeys(); for (int i = 0; i < createdRowCount.length; i++) { if (generatedKeys.next()) { - generatedIds[i] = generatedKeys.getInt(1); + generatedIds.add(generatedKeys.getInt(1)); } } return generatedIds; @@ -78,7 +78,7 @@ public class EventConfigDAOImpl implements EventConfigDAO { } @Override - public boolean addEventGroupMappingRecords(int[] generatedEventIds, List groupIds) throws EventManagementDAOException { + public boolean addEventGroupMappingRecords(List eventIds, List groupIds) throws EventManagementDAOException { try { Connection conn = this.getConnection(); String sql = "INSERT INTO DM_DEVICE_EVENT_GROUP_MAPPING(" + @@ -87,8 +87,8 @@ public class EventConfigDAOImpl implements EventConfigDAO { "VALUES (?, ?)"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { for (Integer groupId : groupIds) { - for (int i = 0; i < generatedEventIds.length; i++) { - stmt.setInt(1, generatedEventIds[i]); + for (Integer eventId : eventIds) { + stmt.setInt(1, eventId); stmt.setInt(2, groupId); stmt.addBatch(); } @@ -102,6 +102,198 @@ public class EventConfigDAOImpl implements EventConfigDAO { } } + @Override + public List getEventsOfGroups(List groupIds, int tenantId) throws EventManagementDAOException { + try { + List eventList = new ArrayList<>(); + Connection conn = this.getConnection(); + String sql = "SELECT " + + "E.ID AS EVENT_ID, " + + "EVENT_SOURCE, " + + "EVENT_LOGIC, " + + "ACTIONS " + + "FROM DM_DEVICE_EVENT E, DM_DEVICE_EVENT_GROUP_MAPPING G " + + "WHERE G.EVENT_ID = E.ID " + + "AND G.GROUP_ID IN (%s) " + + "AND E.TENANT_ID = ? " + + "GROUP BY E.ID"; + String inClause = String.join(", ", Collections.nCopies(groupIds.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer groupId : groupIds) { + stmt.setInt(index++, groupId); + } + return getEventConfigs(tenantId, eventList, stmt, index); + } + } catch (SQLException e) { + String msg = "Error occurred while creating event group mapping records"; + log.error(msg, e); + throw new EventManagementDAOException(msg, e); + } + } + + @Override + public void deleteEventGroupMappingRecordsByEventIds(List eventsIdsToDelete) throws EventManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "DELETE FROM DM_DEVICE_EVENT_GROUP_MAPPING WHERE EVENT_ID IN (%s)"; + String inClause = String.join(", ", Collections.nCopies(eventsIdsToDelete.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer eventId : eventsIdsToDelete) { + stmt.setInt(index++, eventId); + stmt.addBatch(); + } + stmt.executeUpdate(); + } + } catch (SQLException e) { + String msg = "Error occurred while deleting event group mapping records"; + log.error(msg, e); + throw new EventManagementDAOException(msg, e); + } + } + + @Override + public void deleteEventGroupMappingRecordsByGroupIds(List groupIdsToDelete) throws EventManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "DELETE FROM DM_DEVICE_EVENT_GROUP_MAPPING WHERE GROUP_ID IN (%s)"; + String inClause = String.join(", ", Collections.nCopies(groupIdsToDelete.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer groupId : groupIdsToDelete) { + stmt.setInt(index++, groupId); + stmt.addBatch(); + } + stmt.executeUpdate(); + } + } catch (SQLException e) { + String msg = "Error occurred while deleting event group mapping records"; + log.error(msg, e); + throw new EventManagementDAOException(msg, e); + } + } + + @Override + public void updateEventRecords(List eventsToUpdate, int tenantId) throws EventManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "UPDATE DM_DEVICE_EVENT SET " + + "ACTIONS = ? " + + "WHERE ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (EventConfig updatingEvent : eventsToUpdate) { + stmt.setString(1, updatingEvent.getActions()); + stmt.setInt(2, updatingEvent.getEventId()); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + String msg = "Error occurred while updating event records of tenant " + tenantId; + log.error(msg, e); + throw new EventManagementDAOException(msg, e); + } + } + + @Override + public void deleteEventRecords(List eventsIdsToDelete, int tenantId) throws EventManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "DELETE FROM DM_DEVICE_EVENT WHERE ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer eventId : eventsIdsToDelete) { + stmt.setInt(1, eventId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + String msg = "Error occurred while deleting event records of tenant " + tenantId; + log.error(msg, e); + throw new EventManagementDAOException(msg, e); + } + } + + @Override + public List getEventsById(List eventIdList, int tenantId) throws EventManagementDAOException { + 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 (%s) "; + String inClause = String.join(", ", Collections.nCopies(eventIdList.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer eventId : eventIdList) { + if (eventId != -1) { + stmt.setInt(index++, eventId); + } + } + return getEventConfigs(tenantId, eventList, stmt, index); + } + } catch (SQLException e) { + String msg = "Error occurred while creating event group mapping records"; + log.error(msg, e); + throw new EventManagementDAOException(msg, e); + } + } + + @Override + public List getGroupsOfEvents(List eventIdList) throws EventManagementDAOException { + try { + List groupIdList = new ArrayList<>(); + Connection conn = this.getConnection(); + String sql = "SELECT " + + "GROUP_ID " + + "FROM DM_DEVICE_EVENT_GROUP_MAPPING " + + "WHERE EVENT_ID IN (%s) " + + "GROUP BY GROUP_ID"; + String inClause = String.join(", ", Collections.nCopies(eventIdList.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer eventId : eventIdList) { + if (eventId != -1) { + stmt.setInt(index++, eventId); + } + } + ResultSet resultSet = stmt.executeQuery(); + while (resultSet.next()) { + groupIdList.add(resultSet.getInt("GROUP_ID")); + } + return groupIdList; + } + } catch (SQLException e) { + String msg = "Error occurred while creating event group mapping records"; + log.error(msg, e); + throw new EventManagementDAOException(msg, e); + } + } + + private List getEventConfigs(int tenantId, List eventList, PreparedStatement stmt, int index) throws SQLException { + stmt.setInt(index, tenantId); + ResultSet rst = stmt.executeQuery(); + while (rst.next()) { + EventConfig event = new EventConfig(); + event.setEventId(rst.getInt("EVENT_ID")); + event.setEventSource(rst.getString("EVENT_SOURCE")); + event.setEventLogic(rst.getString("EVENT_LOGIC")); + event.setActions(rst.getString("ACTIONS")); + eventList.add(event); + } + return eventList; + } + private Connection getConnection() throws SQLException { return DeviceManagementDAOFactory.getConnection(); } 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 6e6abfb4ae9..2ef9f8b8962 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 @@ -322,4 +322,90 @@ public class GeofenceDAOImpl implements GeofenceDAO { } return geofenceDataList; } + + @Override + public List getGroupIdsOfGeoFence(int fenceId) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "SELECT " + + "GROUP_ID " + + "FROM DM_GEOFENCE_GROUP_MAPPING " + + "WHERE FENCE_ID = ? "; + List groupIds = new ArrayList<>(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, fenceId); + try (ResultSet rst = stmt.executeQuery()) { + while (rst.next()) { + groupIds.add(rst.getInt(1)); + } + } + } + return groupIds; + } catch (SQLException e) { + String msg = "Error occurred while fetching group IDs of the fence " + fenceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public void deleteGeofenceGroupMapping(List groupIdsToDelete) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "DELETE FROM DM_GEOFENCE_GROUP_MAPPING WHERE GROUP_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer groupId : groupIdsToDelete) { + stmt.setInt(1, groupId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + String msg = "Error occurred while deleting Geofence group mapping records"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public void createGeofenceEventMapping(int fenceId, List eventIds) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "INSERT INTO DM_GEOFENCE_EVENT_MAPPING(" + + "FENCE_ID, "+ + "EVENT_ID) " + + "VALUES (?, ?)"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer createdEventId : eventIds) { + stmt.setInt(1, fenceId); + stmt.setInt(2, createdEventId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + String msg = "Error occurred while creating geofence event group mapping records"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public void deleteGeofenceEventMapping(List removedEventIdList) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "DELETE FROM DM_GEOFENCE_EVENT_MAPPING WHERE EVENT_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer eventId : removedEventIdList) { + stmt.setInt(1, eventId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + String msg = "Error occurred while deleting Geofence event mapping records"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/event/config/EventConfigurationProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/event/config/EventConfigurationProviderServiceImpl.java index b6617480ae5..b02a1a1c30c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/event/config/EventConfigurationProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/event/config/EventConfigurationProviderServiceImpl.java @@ -29,6 +29,7 @@ import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.EventConfigDAO; import org.wso2.carbon.device.mgt.core.dao.EventManagementDAOException; +import java.util.ArrayList; import java.util.List; public class EventConfigurationProviderServiceImpl implements EventConfigurationProviderService { @@ -40,14 +41,24 @@ public class EventConfigurationProviderServiceImpl implements EventConfiguration } @Override - public boolean createEventOfDeviceGroup(List eventConfigList, List groupIds, int tenantId) + public List createEventsOfDeviceGroup(List eventConfigList, List groupIds, int tenantId) throws EventConfigurationException { try { DeviceManagementDAOFactory.beginTransaction(); - int[] generatedEventIds = eventConfigDAO.storeEventRecords(eventConfigList, tenantId); - boolean isRecordsCreated = eventConfigDAO.addEventGroupMappingRecords(generatedEventIds, groupIds); + if (log.isDebugEnabled()) { + log.debug("Creating event records of tenant " + tenantId); + } + List generatedEventIds = eventConfigDAO.storeEventRecords(eventConfigList, tenantId); + if (log.isDebugEnabled()) { + log.debug("Created events with event ids : " + generatedEventIds.toString()); + log.debug("Creating event group mapping for created events with group ids : " + groupIds.toString()); + } + eventConfigDAO.addEventGroupMappingRecords(generatedEventIds, groupIds); DeviceManagementDAOFactory.commitTransaction(); - return isRecordsCreated; + if (log.isDebugEnabled()) { + log.debug("Event configuration added successfully for the tenant " + tenantId); + } + return generatedEventIds; } catch (TransactionManagementException e) { String msg = "Failed to start/open transaction to store device event configurations"; throw new EventConfigurationException(msg, e); @@ -60,4 +71,84 @@ public class EventConfigurationProviderServiceImpl implements EventConfiguration DeviceManagementDAOFactory.closeConnection(); } } + + @Override + public List updateEventsOfDeviceGroup(List newEventList, + List removedEventIdList, + List groupIds, int tenantId) throws EventConfigurationException { + //todo when concerning about other event types, all of this steps might not necessary. + // so divide them into separate service methods + if (log.isDebugEnabled()) { + log.debug("Updating event configurations of tenant " + tenantId); + } + List eventsToAdd; + try { + DeviceManagementDAOFactory.beginTransaction(); + eventsToAdd = new ArrayList<>(); + List eventsToUpdate = new ArrayList<>(); + List updateEventIdList = new ArrayList<>(); + for (EventConfig newEvent : newEventList) { + if (newEvent.getEventId() == -1) { + eventsToAdd.add(newEvent); + continue; + } + eventsToUpdate.add(newEvent); + updateEventIdList.add(newEvent.getEventId()); + } + List savedGroups = eventConfigDAO.getGroupsOfEvents(updateEventIdList); + List groupIdsToAdd = new ArrayList<>(); + List groupIdsToDelete = new ArrayList<>(); + for (Integer savedGroup : savedGroups) { + if (!groupIds.contains(savedGroup)) { + groupIdsToDelete.add(savedGroup); + } + } + + for (Integer newGroupId : groupIds) { + if (!savedGroups.contains(newGroupId)) { + groupIdsToAdd.add(newGroupId); + } + } + if (log.isDebugEnabled()) { + log.debug("Updating event records "); + } + eventConfigDAO.updateEventRecords(eventsToUpdate, tenantId); + + if (log.isDebugEnabled()) { + log.debug("Deleting event group mapping records of groups"); + } + eventConfigDAO.deleteEventGroupMappingRecordsByGroupIds(groupIdsToDelete); + + if (log.isDebugEnabled()) { + log.debug("Creating event group mapping records for updated events"); + } + eventConfigDAO.addEventGroupMappingRecords(updateEventIdList, groupIdsToAdd); + + if (log.isDebugEnabled()) { + log.debug("Deleting event group mapping records of removing events"); + } + eventConfigDAO.deleteEventGroupMappingRecordsByEventIds(removedEventIdList); + + if (log.isDebugEnabled()) { + log.debug("Deleting removed event records"); + } + eventConfigDAO.deleteEventRecords(removedEventIdList, tenantId); + DeviceManagementDAOFactory.commitTransaction(); + } catch (TransactionManagementException e) { + String msg = "Failed to start/open transaction to store device event configurations"; + throw new EventConfigurationException(msg, e); + } catch (EventManagementDAOException e) { + String msg = "Error occurred while saving event records"; + log.error(msg, e); + DeviceManagementDAOFactory.rollbackTransaction(); + throw new EventConfigurationException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + if (log.isDebugEnabled()) { + log.debug("Adding new events while updating event"); + } + return createEventsOfDeviceGroup(eventsToAdd, groupIds, tenantId); + } } 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 af7366d96d5..38f7e01a1b0 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 @@ -1288,11 +1288,11 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic try { EventConfigurationProviderService eventConfigService = DeviceManagerUtil.getEventConfigService(); - for (EventConfig eventConfig : geofenceData.getEventConfig()) { - eventConfig.setEventSource(DeviceManagementConstants.EventServices.GEOFENCE); - } - return eventConfigService.createEventOfDeviceGroup(geofenceData.getEventConfig(), - geofenceData.getGroupIds(), tenantId); + setEventSource(geofenceData.getEventConfig()); + List createdEventIds = eventConfigService.createEventsOfDeviceGroup(geofenceData.getEventConfig(), geofenceData.getGroupIds(), tenantId); + DeviceManagementDAOFactory.beginTransaction(); + geofenceDAO.createGeofenceEventMapping(geofenceData.getId(), createdEventIds); + DeviceManagementDAOFactory.commitTransaction(); } catch (EventConfigurationException e) { String msg = "Failed to store Geofence event configurations"; log.error(msg, e); @@ -1302,6 +1302,24 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } this.deleteGeofenceData(geofenceData.getId()); throw new EventConfigurationException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Failed to begin transaction for saving geofence"; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } catch (DeviceManagementDAOException e) { + DeviceManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while creating geofence event mapping records"; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + return true; + } + + private void setEventSource(List eventConfig) { + for (EventConfig eventConfigEntry : eventConfig) { + eventConfigEntry.setEventSource(DeviceManagementConstants.EventServices.GEOFENCE); } } @@ -1473,7 +1491,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic @Override public boolean updateGeofence(GeofenceData geofenceData, int fenceId) - throws GeoLocationBasedServiceException { + throws GeoLocationBasedServiceException, EventConfigurationException { int tenantId; try { tenantId = DeviceManagementDAOUtil.getTenantId(); @@ -1483,15 +1501,30 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic throw new GeoLocationBasedServiceException(msg, e); } + List savedGroupIds; try { DeviceManagementDAOFactory.beginTransaction(); int updatedRowCount = geofenceDAO.updateGeofence(geofenceData, fenceId); + savedGroupIds = geofenceDAO.getGroupIdsOfGeoFence(fenceId); + geofenceData.setId(fenceId); + List groupIdsToDelete = new ArrayList<>(); + List groupIdsToAdd = new ArrayList<>(); + for (Integer savedGroupId : savedGroupIds) { + if (!geofenceData.getGroupIds().contains(savedGroupId)) { + groupIdsToDelete.add(savedGroupId); + } + } + for (Integer newGroupId : geofenceData.getGroupIds()) { + if (!savedGroupIds.contains(newGroupId)) { + groupIdsToAdd.add(newGroupId); + } + } + geofenceDAO.deleteGeofenceGroupMapping(groupIdsToDelete); + geofenceDAO.createGeofenceGroupMapping(geofenceData, groupIdsToAdd); DeviceManagementDAOFactory.commitTransaction(); if (updatedRowCount > 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); @@ -1504,5 +1537,80 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } finally { DeviceManagementDAOFactory.closeConnection(); } + return true; + } + + @Override + public boolean updateGeoEventConfigurations(List eventConfig, + List removedEventIdList, List groupIds, int fenceId) + throws GeoLocationBasedServiceException { + if (log.isDebugEnabled()) { + log.debug("Updating event configuration of geofence " + fenceId); + } + try { + if (log.isDebugEnabled()) { + log.debug("Deleting geofence event mapping records of geofence " + fenceId); + } + DeviceManagementDAOFactory.beginTransaction(); + geofenceDAO.deleteGeofenceEventMapping(removedEventIdList); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + DeviceManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while deleting geofence event mapping of fence " + fenceId; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Failed to begin transaction deleting geofence event mapping of fence " + fenceId; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + List createdEventIds; + try { + int tenantId = DeviceManagementDAOUtil.getTenantId(); + setEventSource(eventConfig); + EventConfigurationProviderService eventConfigService = DeviceManagerUtil.getEventConfigService(); + if (eventConfigService == null) { + String msg = "Failed to load EventConfigurationProviderService osgi service of tenant " + tenantId; + log.error(msg); + throw new GeoLocationBasedServiceException(msg); + } + createdEventIds = eventConfigService.updateEventsOfDeviceGroup(eventConfig, removedEventIdList, groupIds, tenantId); + } catch (EventConfigurationException e) { + String msg = "Error occurred while updating event configuration data"; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } catch (DeviceManagementDAOException e) { + String msg = "Error occurred while retrieving tenant id while update geofence data"; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } + + if (log.isDebugEnabled()) { + log.debug("Creating geofence event mapping records of geofence " + + fenceId + ". created events " + createdEventIds.toString()); + } + try { + DeviceManagementDAOFactory.beginTransaction(); + geofenceDAO.createGeofenceEventMapping(fenceId, createdEventIds); + DeviceManagementDAOFactory.commitTransaction(); + } catch (DeviceManagementDAOException e) { + DeviceManagementDAOFactory.rollbackTransaction(); + String msg = "Error occurred while creating geofence event mapping records of geofence " + fenceId; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Failed to begin transaction while creating geofence event mapping of fence " + fenceId; + log.error(msg, e); + throw new GeoLocationBasedServiceException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + if (log.isDebugEnabled()) { + log.debug("Update geofence event completed."); + } + return true; } } diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index 03863388c90..00ff301f6d3 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -772,4 +772,18 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_EVENT_GROUP_MAPPING ( DM_GROUP (ID) ON DELETE NO ACTION ON UPDATE NO ACTION ) ENGINE=InnoDB; --- END OF DM_DEVICE_EVENT_GROUP_MAPPING TABLE-- \ No newline at end of file +-- END OF DM_DEVICE_EVENT_GROUP_MAPPING TABLE-- + +-- DM_GEOFENCE_GROUP_MAPPING TABLE-- +CREATE TABLE IF NOT EXISTS DM_GEOFENCE_EVENT_MAPPING ( + ID INT NOT NULL AUTO_INCREMENT, + FENCE_ID INT NOT NULL, + EVENT_ID INT NOT NULL, + PRIMARY KEY (ID), + CONSTRAINT fk_dm_geofence_event_mapping_geofence FOREIGN KEY (FENCE_ID) REFERENCES + DM_GEOFENCE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION, + CONSTRAINT fk_dm_geofence_event_mapping_event FOREIGN KEY (EVENT_ID) REFERENCES + DM_DEVICE_EVENT (ID) ON DELETE NO ACTION ON UPDATE NO ACTION +) ENGINE=InnoDB; + +-- END OF DM_GEOFENCE_GROUP_MAPPING TABLE-- \ No newline at end of file