Merge branch 'event-modify-branch-1' into 'master'

Modify event creation task

See merge request entgra/carbon-device-mgt!725
revert-70ac1926
Charitha Goonetilleke 4 years ago
commit 1e2afa6439

@ -73,10 +73,13 @@ public interface EventConfigurationProviderService {
void deleteEvents(List<EventConfig> eventList) throws EventConfigurationException;
/**
* Create task entry to be executed at the time of event operation task running
* @param eventTaskEntry event task entry
* @param groupIds group ids of the event task entry assigned
* @throws EventConfigurationException error thrown while creating task records
* Create event operation and add them into the corresponding devices
* @param eventType EVENT_REVOKE / EVENT_CONFIG
* @param eventCode unique code of the event
* @param eventMeta event metadata
* @param tenantId tenant id
* @param groupIds group ids of the corresponding event
*/
void createEventOperationTask(EventTaskEntry eventTaskEntry, List<Integer> groupIds) throws EventConfigurationException;
void createEventOperationTask(String eventType, String eventCode, EventMetaData eventMeta, int tenantId,
List<Integer> groupIds) throws EventConfigurationException;
}

@ -1,98 +0,0 @@
/*
* 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.common.event.config;
public class EventTaskEntry {
private int id;
private int deviceId;
private int groupId;
private String operationCode;
private String eventSource;
private int eventMetaId;
private int tenantId;
private ExecutionStatus executionStatus;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getDeviceId() {
return deviceId;
}
public void setDeviceId(int deviceId) {
this.deviceId = deviceId;
}
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public String getOperationCode() {
return operationCode;
}
public void setOperationCode(String operationCode) {
this.operationCode = operationCode;
}
public ExecutionStatus getExecutionStatus() {
return executionStatus;
}
public void setExecutionStatus(ExecutionStatus executionStatus) {
this.executionStatus = executionStatus;
}
public String getEventSource() {
return eventSource;
}
public void setEventSource(String eventSource) {
this.eventSource = eventSource;
}
public int getEventMetaId() {
return eventMetaId;
}
public void setEventMetaId(int eventMetaId) {
this.eventMetaId = eventMetaId;
}
public int getTenantId() {
return tenantId;
}
public void setTenantId(int tenantId) {
this.tenantId = tenantId;
}
public enum ExecutionStatus {
CREATED, PENDING, COMPLETED;
}
}

@ -19,7 +19,6 @@
package org.wso2.carbon.device.mgt.core.dao;
import org.wso2.carbon.device.mgt.common.event.config.EventConfig;
import org.wso2.carbon.device.mgt.common.event.config.EventTaskEntry;
import java.util.List;
import java.util.Map;
@ -114,33 +113,4 @@ public interface EventConfigDAO {
* @throws EventManagementDAOException thrown errors while retrieving event sources
*/
List<String> getEventSourcesOfGroups(int groupId, int tenantId) throws EventManagementDAOException;
/**
* Create record for event creation task which will be executed periodically
* @param eventTaskEntry event task object
* @param groupIds group ids of the event assigned
* @return true if record added successfully
* @throws EventManagementDAOException failed while creating the entry record
*/
boolean createEventTaskEntry(EventTaskEntry eventTaskEntry, List<Integer> groupIds) throws EventManagementDAOException;
/**
* Retrieve task entries by status of the task
* @param status status of the task
* @return map of tenant id and event task entries
* @throws EventManagementDAOException if errors occurred while retrieving records
*/
Map<Integer, List<EventTaskEntry>> getAvailableEventTaskEntries(String status) throws EventManagementDAOException;
/**
* Update event task records of group and set them as COMPLETED
* @param code operation code
* @param eventSource source of the event to be updated
* @param groupIds groupId list of the task entries
* @param tenantId tenant of the records
* @return true if the update done successfully
* @throws EventManagementDAOException if errors occurred while retrieving records
*/
boolean setEventTaskComplete(String code, String eventSource, List<Integer> groupIds, int tenantId)
throws EventManagementDAOException;
}

@ -24,7 +24,6 @@ import org.wso2.carbon.device.mgt.common.event.config.EventConfig;
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 org.wso2.carbon.device.mgt.common.event.config.EventTaskEntry;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ -327,117 +326,6 @@ public abstract class AbstractEventConfigDAO implements EventConfigDAO {
}
}
@Override
public boolean createEventTaskEntry(EventTaskEntry eventTaskEntry, List<Integer> groupIds)
throws EventManagementDAOException {
try {
Connection connection = this.getConnection();
String sql = "INSERT INTO DM_EVENT_OPERATION_ASSIGNMENT_TASK(" +
"DEVICE_ID, " +
"GROUP_ID, " +
"OPERATION_CODE, " +
"EVENT_SOURCE, " +
"EVENT_META_ID, " +
"STATUS, " +
"TENANT_ID, " +
"CREATED_TIMESTAMP) " +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement stm = connection.prepareStatement(sql)){
for (Integer groupId : groupIds) {
stm.setInt(1, eventTaskEntry.getDeviceId());
stm.setInt(2, groupId);
stm.setString(3, eventTaskEntry.getOperationCode());
stm.setString(4, eventTaskEntry.getEventSource());
stm.setInt(5, eventTaskEntry.getEventMetaId());
stm.setString(6, eventTaskEntry.getExecutionStatus().toString());
stm.setInt(7, eventTaskEntry.getTenantId());
stm.setTimestamp(8, new Timestamp(System.currentTimeMillis()));
stm.addBatch();
}
return stm.executeBatch().length > 0;
}
} catch (SQLException e) {
String msg = "Failed while creating event task entry for event operation " + eventTaskEntry.getOperationCode()
+ " of the tenant " + eventTaskEntry.getTenantId();
log.error(msg, e);
throw new EventManagementDAOException(msg, e);
}
}
@Override
public Map<Integer, List<EventTaskEntry>> getAvailableEventTaskEntries(String status) throws EventManagementDAOException {
Map<Integer, List<EventTaskEntry>> eventTaskEntries = new HashMap<>();
try {
Connection connection = this.getConnection();
String sql = "SELECT " +
"ID, "+
"DEVICE_ID, " +
"GROUP_ID, " +
"OPERATION_CODE, " +
"EVENT_SOURCE, " +
"EVENT_META_ID, " +
"TENANT_ID " +
"FROM DM_EVENT_OPERATION_ASSIGNMENT_TASK " +
"WHERE STATUS = ?";
try (PreparedStatement stm = connection.prepareStatement(sql)){
stm.setString(1, status);
ResultSet resultSet = stm.executeQuery();
while (resultSet.next()) {
int tenantId = resultSet.getInt("TENANT_ID");
List<EventTaskEntry> eventsOfTenant = eventTaskEntries.get(tenantId);
if (eventsOfTenant == null) {
eventsOfTenant = new ArrayList<>();
}
EventTaskEntry eventTaskEntry = new EventTaskEntry();
eventTaskEntry.setId(resultSet.getInt("ID"));
eventTaskEntry.setOperationCode(resultSet.getString("OPERATION_CODE"));
eventTaskEntry.setGroupId(resultSet.getInt("GROUP_ID"));
eventTaskEntry.setEventMetaId(resultSet.getInt("EVENT_META_ID"));
eventTaskEntry.setDeviceId(resultSet.getInt("DEVICE_ID"));
eventTaskEntry.setTenantId(tenantId);
eventTaskEntry.setEventSource(resultSet.getString("EVENT_SOURCE"));
eventsOfTenant.add(eventTaskEntry);
eventTaskEntries.put(tenantId, eventsOfTenant);
}
return eventTaskEntries;
}
} catch (SQLException e) {
String msg = "Failed while retrieving event task entries";
log.error(msg, e);
throw new EventManagementDAOException(msg, e);
}
}
@Override
public boolean setEventTaskComplete(String code, String eventSource, List<Integer> groupIds, int tenantId)
throws EventManagementDAOException {
try {
Connection connection = this.getConnection();
String sql = "UPDATE DM_EVENT_OPERATION_ASSIGNMENT_TASK " +
"SET STATUS = ?, "+
"COMPLETED_TIMESTAMP = ? " +
"WHERE STATUS = ? AND OPERATION_CODE = ? AND EVENT_SOURCE = ? AND GROUP_ID = ? AND TENANT_ID = ?";
try (PreparedStatement stm = connection.prepareStatement(sql)){
for (Integer groupId : groupIds) {
stm.setString(1, EventTaskEntry.ExecutionStatus.COMPLETED.toString());
stm.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
stm.setString(3, EventTaskEntry.ExecutionStatus.CREATED.toString());
stm.setString(4, code);
stm.setString(5, eventSource);
stm.setInt(6, groupId);
stm.setInt(7, tenantId);
stm.addBatch();
}
return stm.executeBatch().length > 0;
}
} catch (SQLException e) {
String msg = "Failed while retrieving event task entries";
log.error(msg, e);
throw new EventManagementDAOException(msg, e);
}
}
private Connection getConnection() throws SQLException {
return DeviceManagementDAOFactory.getConnection();
}

@ -24,13 +24,16 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.event.config.EventConfig;
import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationException;
import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationProviderService;
import org.wso2.carbon.device.mgt.common.event.config.EventMetaData;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
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.EventConfigDAO;
import org.wso2.carbon.device.mgt.core.dao.EventManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.common.event.config.EventTaskEntry;
import org.wso2.carbon.device.mgt.core.geo.task.GeoFenceEventOperationManager;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import java.sql.SQLException;
import java.util.ArrayList;
@ -38,6 +41,8 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EventConfigurationProviderServiceImpl implements EventConfigurationProviderService {
private static final Log log = LogFactory.getLog(EventConfigurationProviderServiceImpl.class);
@ -239,26 +244,10 @@ public class EventConfigurationProviderServiceImpl implements EventConfiguration
}
@Override
public void createEventOperationTask(EventTaskEntry eventTaskEntry, List<Integer> groupIds)
throws EventConfigurationException {
try {
DeviceManagementDAOFactory.beginTransaction();
eventConfigDAO.createEventTaskEntry(eventTaskEntry, groupIds);
DeviceManagementDAOFactory.commitTransaction();
} catch (TransactionManagementException e) {
String msg = "Failed to start transaction while creating event operation task entries of tenant "
+ eventTaskEntry.getTenantId();
log.error(msg, e);
throw new EventConfigurationException(msg, e);
} catch (EventManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while creating event task entries for event " + eventTaskEntry
.getEventSource() + " with code " + eventTaskEntry.getOperationCode() + " of the tenant "
+ eventTaskEntry.getTenantId();
log.error(msg, e);
throw new EventConfigurationException(msg, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
public void createEventOperationTask(String eventType, String eventCode, EventMetaData eventMeta, int tenantId,
List<Integer> groupIds) {
GeoFenceEventOperationManager geoFenceEventOperationManager = new GeoFenceEventOperationManager(eventType, tenantId, null);
EventOperationExecutor executor = geoFenceEventOperationManager.getEventOperationExecutor(groupIds, eventMeta);
DeviceManagementDataHolder.getInstance().getEventConfigExecutors().submit(executor);
}
}

@ -0,0 +1,233 @@
/*
* 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.event.config;
import com.google.gson.Gson;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.event.config.EventConfig;
import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationException;
import org.wso2.carbon.device.mgt.common.event.config.EventMetaData;
import org.wso2.carbon.device.mgt.common.event.config.EventOperation;
import org.wso2.carbon.device.mgt.common.event.config.EventRevokeOperation;
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFenceEventMeta;
import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationBasedServiceException;
import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService;
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.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
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.GeofenceDAO;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationMgtConstants;
import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Event create/revoke operation creation task.
* Use at the time of single event create, update, delete
*/
public class EventOperationExecutor implements Runnable {
private static final Log log = LogFactory.getLog(EventOperationExecutor.class);
private final GroupManagementProviderService groupManagementService;
private final EventConfigDAO eventConfigDAO;
private final GeofenceDAO geofenceDAO;
private final List<Integer> groupIds;
private final String eventSource;
private final EventMetaData eventMetaData;
private final int tenantId;
private final String operationCode;
public EventOperationExecutor(EventMetaData eventMetaData, List<Integer> groupIds, int tenantId,
String eventSource, String operationCode) {
this.groupManagementService = DeviceManagementDataHolder.getInstance().getGroupManagementProviderService();
this.eventConfigDAO = DeviceManagementDAOFactory.getEventConfigDAO();
this.geofenceDAO = DeviceManagementDAOFactory.getGeofenceDAO();
this.eventMetaData = eventMetaData;
this.groupIds = groupIds;
this.tenantId = tenantId;
this.eventSource = eventSource;
this.operationCode = operationCode;
}
/**
* Build operation to create EVENT_REVOKE operation.
* @param operation Operation object to build
*/
private void buildEventRevokeOperation(ProfileOperation operation) {
if (eventSource.equalsIgnoreCase(DeviceManagementConstants.EventServices.GEOFENCE)) {
createGeoFenceRevokeOperation(operation);
} //extend with another cases to handle other types of events
}
/**
* Build operation to create EVENT_CONFIG operation.
* @param operation Operation object to build
* @throws EventConfigurationException Failed while build the operation object
*/
private void buildEventConfigOperation(ProfileOperation operation) throws EventConfigurationException {
if (eventSource.equalsIgnoreCase(DeviceManagementConstants.EventServices.GEOFENCE)) {
createGeoFenceConfigOperation(operation);
} //extend with another cases to handle other types of events
}
/**
* Create EVENT_CONFIG operation object and attach payload to configure geo fence events
* @param operation operation object to set the payload
* @throws EventConfigurationException Failed while retrieving event list of geo fence
*/
private void createGeoFenceConfigOperation(ProfileOperation operation) throws EventConfigurationException {
GeoFenceEventMeta geoFenceMeta = (GeoFenceEventMeta) eventMetaData;
try {
GeoLocationProviderService geoLocationProviderService = DeviceManagementDataHolder
.getInstance().getGeoLocationProviderService();
List<EventConfig> eventConfigList = geoLocationProviderService.getEventsOfGeoFence(geoFenceMeta.getId());
if (log.isDebugEnabled()) {
log.debug("Retrieved event records of Geo Fence " + geoFenceMeta.getId() +
". events " + Arrays.toString(eventConfigList.toArray()));
}
List<EventOperation> eventOperations = new ArrayList<>();
EventOperation eventOperation = new EventOperation();
eventOperation.setEventDefinition(eventMetaData);
eventOperation.setEventSource(eventSource);
eventOperation.setEventTriggers(eventConfigList);
eventOperations.add(eventOperation);
operation.setPayLoad(new Gson().toJson(eventOperations));
}catch (GeoLocationBasedServiceException e) {
throw new EventConfigurationException("Failed to retrieve event data of Geo fence " + geoFenceMeta.getId()
+ " : " + geoFenceMeta.getFenceName(), e);
}
}
/**
* Create EVENT_REVOKE operation object and attach payload to configure geo fence events
* @param operation operation object to set the payload
*/
private void createGeoFenceRevokeOperation(ProfileOperation operation) {
GeoFenceEventMeta geoFenceMeta = (GeoFenceEventMeta) eventMetaData;
EventRevokeOperation eventRevokeOperation = new EventRevokeOperation();
eventRevokeOperation.setEventSource(eventSource);
eventRevokeOperation.setId(geoFenceMeta.getId());
operation.setPayLoad(new Gson().toJson(eventRevokeOperation));
}
@Override
public void run() {
if (operationCode == null || groupIds == null || groupIds.isEmpty()) {
log.error("No valid group ids or operation code found for create operations");
return;
}
if (log.isDebugEnabled()) {
log.debug("Starting " + operationCode + " operation creation task for event " + eventSource
+ " tenant " + tenantId + " group Ids "+ Arrays.toString(groupIds.toArray()));
}
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
Set<Device> devices = new HashSet<>();
for (Integer groupId : groupIds) {
DeviceGroup group;
try {
group = groupManagementService.getGroup(groupId, false);
} catch (GroupManagementException e) {
log.error("Failed to retrieve group with group ID " + groupId, e);
continue;
}
try {
if (group != null) {
List<Device> allDevicesOfGroup = groupManagementService.getAllDevicesOfGroup(group.getName(), false);
if (allDevicesOfGroup == null || allDevicesOfGroup.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("No devices found in group " + group.getName());
}
} else {
devices.addAll(allDevicesOfGroup);
}
}
} catch (GroupManagementException e) {
log.error("Failed to retrieve devices of group with ID " + groupId + " and name " + group.getName(), e);
}
}
if (log.isDebugEnabled()) {
log.debug("Starting " + operationCode + " operation creation task for event " + eventSource
+ " tenant " + tenantId + " group Ids "+ Arrays.toString(groupIds.toArray()));
}
ProfileOperation operation = new ProfileOperation();
operation.setType(Operation.Type.PROFILE);
try {
if (operationCode.equalsIgnoreCase(OperationMgtConstants.OperationCodes.EVENT_CONFIG)) {
operation.setCode(OperationMgtConstants.OperationCodes.EVENT_CONFIG);
buildEventConfigOperation(operation);
} else if (operationCode.equalsIgnoreCase(OperationMgtConstants.OperationCodes.EVENT_REVOKE)){
operation.setCode(OperationMgtConstants.OperationCodes.EVENT_REVOKE);
buildEventRevokeOperation(operation);
}
} catch (EventConfigurationException e) {
log.error("Event creation failed with message : " + e.getMessage(), e);
return;
}
if (devices.isEmpty()) {
log.warn("No devices found for the specified groups " + Arrays.toString(groupIds.toArray()));
return;
}
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
for (Device device : devices) {
if (device.getType().equalsIgnoreCase("android")) {
//TODO introduce a proper mechanism for event handling for each device types
deviceIdentifiers.add(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
}
}
DeviceManagementProviderService deviceManagementProvider = DeviceManagementDataHolder
.getInstance().getDeviceManagementProvider();
try {
if (log.isDebugEnabled()) {
log.debug("Creating event operations stared for devices" + Arrays.toString(deviceIdentifiers.toArray()));
}
deviceManagementProvider.addOperation("android", operation, deviceIdentifiers);
//TODO introduce a proper mechanism
} catch (OperationManagementException e) {
log.error("Creating event operation failed with error ", e);
return;
} catch (InvalidDeviceException e) {
log.error("Creating event operation failed.\n" +
"Could not found device/devices for the defined device identifiers.", e);
return;
}
}
}

@ -22,7 +22,7 @@ import javax.xml.bind.annotation.XmlElement;
public class EventOperationTaskConfiguration {
private boolean isEnabled;
private int frequency;
private int poolSize;
@XmlElement(name = "Enable", required = true)
public boolean isEnabled() {
@ -30,15 +30,6 @@ public class EventOperationTaskConfiguration {
}
public void setEnabled(boolean enabled) {
isEnabled = enabled;
}
@XmlElement(name = "Frequency", required = true)
public int getFrequency() {
return frequency;
}
public void setFrequency(int frequency) {
this.frequency = frequency;
this.isEnabled = enabled;
}
}

@ -49,8 +49,8 @@ import java.util.List;
* Event create/revoke operation creation task.
* Use at the time of devices assign into group, remove from group.
*/
public class GroupEventOperationExecutor implements Runnable {
private static final Log log = LogFactory.getLog(GroupEventOperationExecutor.class);
public class GroupAssignmentEventOperationExecutor implements Runnable {
private static final Log log = LogFactory.getLog(GroupAssignmentEventOperationExecutor.class);
private final int groupId;
private final List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
@ -59,8 +59,11 @@ public class GroupEventOperationExecutor implements Runnable {
private final GeoLocationProviderService geoLocationProviderService;
private final EventConfigurationProviderService eventConfigurationService;
private EventCreateCallback callback;
private List<String> eventSources;
public GroupEventOperationExecutor(int groupId, List<DeviceIdentifier> deviceIdentifiers, int tenantId, String operationCode) {
private List<GeofenceData> geoFencesOfGroup;
public GroupAssignmentEventOperationExecutor(int groupId, List<DeviceIdentifier> deviceIdentifiers, int tenantId, String operationCode) {
this.groupId = groupId;
for (DeviceIdentifier deviceIdentifier : deviceIdentifiers) {
if (deviceIdentifier.getType().equalsIgnoreCase("android")) {
@ -75,16 +78,32 @@ public class GroupEventOperationExecutor implements Runnable {
@Override
public void run() {
log.info("Starting event operation creation task for devices in group " + groupId + " tenant " + tenantId);
if (log.isDebugEnabled()) {
log.debug("Event creation operation started for devices with IDs " + Arrays.toString(deviceIdentifiers.toArray()));
log.debug("Starting tenant flow for tenant with ID : " + tenantId);
}
ProfileOperation operation = new ProfileOperation();
try {
this.eventSources = eventConfigurationService.getEventsSourcesOfGroup(groupId, tenantId);
if (this.eventSources == null || this.eventSources.isEmpty()) {
String msg = "No events applied for queried group with ID " + groupId;
if (log.isDebugEnabled()) {
log.debug(msg);
}
return;
}
} catch (EventConfigurationException e) {
String msg = "Failed while retrieving event records of group " + groupId + "of the tenant " + tenantId;
log.error(msg, e);
return;
}
if (operationCode != null) {
ProfileOperation operation = new ProfileOperation();
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
try {
initEventMeta(); // Initialize all event based meta data of the group
operation.setCode(operationCode);
operation.setType(Operation.Type.PROFILE);
if (operationCode.equalsIgnoreCase(OperationMgtConstants.OperationCodes.EVENT_CONFIG)) {
@ -92,7 +111,6 @@ public class GroupEventOperationExecutor implements Runnable {
} else if (operationCode.equalsIgnoreCase(OperationMgtConstants.OperationCodes.EVENT_REVOKE)) {
buildEventRevokeOperation(operation);
}
} catch (EventConfigurationException e) {
log.error("Failed to retrieve event sources of group " + groupId + ". Event creation operation failed.", e);
return;
@ -107,7 +125,9 @@ public class GroupEventOperationExecutor implements Runnable {
}
deviceManagementProvider.addOperation("android", operation, deviceIdentifiers); //TODO introduce a proper mechanism
} else {
log.info("Device identifiers are empty, Hence ignoring adding event operation");
if (log.isDebugEnabled()) {
log.debug("Device identifiers are empty, Hence ignoring adding event operation");
}
}
} catch (OperationManagementException e) {
log.error("Creating event operation failed with error ", e);
@ -115,7 +135,6 @@ public class GroupEventOperationExecutor implements Runnable {
log.error("Creating event operation failed.\n" +
"Could not found device/devices for the defined device identifiers.", e);
}
log.info("Event operation creation succeeded");
if (callback != null) {
callback.onCompleteEventOperation(null);
}
@ -123,22 +142,25 @@ public class GroupEventOperationExecutor implements Runnable {
}
/**
* This method is using for retrieve all types of events mapped with the specific group
* @throws EventConfigurationException when fails to retrieve event data of the group
*/
private void initEventMeta() throws EventConfigurationException {
this.geoFencesOfGroup = getGeoFencesOfGroup();
//Need to be added other event sources which will be declared in future
}
/**
* Build EVENT_REVOKE operation attaching event payload
* @param operation operation object to build
* @throws EventConfigurationException if not events found for the specific group
*/
private void buildEventRevokeOperation(ProfileOperation operation) throws EventConfigurationException {
List<String> eventSources = eventConfigurationService.getEventsSourcesOfGroup(groupId, tenantId);
if (eventSources == null || eventSources.isEmpty()) {
String msg = "No events applied for queried group with ID " + groupId;
log.info(msg);
throw new EventConfigurationException(msg);
}
for (String eventSource : eventSources) {
for (String eventSource : this.eventSources) {
if (eventSource.equalsIgnoreCase(DeviceManagementConstants.EventServices.GEOFENCE)) {
setGeoFenceRevokeOperationContent(operation);
} //extend with another cases to handle other types of events
} //add other cases to handle other types of events
}
}
@ -148,29 +170,20 @@ public class GroupEventOperationExecutor implements Runnable {
* @throws EventConfigurationException if not events found for the specific group
*/
private void buildEventConfigOperationObject(ProfileOperation operation) throws EventConfigurationException {
List<String> eventSources = eventConfigurationService.getEventsSourcesOfGroup(groupId, tenantId);
if (eventSources == null || eventSources.isEmpty()) {
String msg = "No events applied for queried group with ID " + groupId;
log.info(msg);
throw new EventConfigurationException(msg);
}
for (String eventSource : eventSources) {
for (String eventSource : this.eventSources) {
if (eventSource.equalsIgnoreCase(DeviceManagementConstants.EventServices.GEOFENCE)) {
setGeoFenceConfigOperationContent(operation);
} //extend with another cases to handle other types of events
} //add other cases to handle other types of events
}
}
/**
* Set operation payload GeoFence for EVENT_CONFIG operation
* @param operation operation object to attach payload
* @throws EventConfigurationException failed while getting events of group
*/
private void setGeoFenceConfigOperationContent(ProfileOperation operation) throws EventConfigurationException {
log.info("Geo fence events found attached with group " + groupId + ", Started retrieving geo fences");
List<GeofenceData> geoFencesOfGroup = getGeoFencesOfGroup();
private void setGeoFenceConfigOperationContent(ProfileOperation operation) {
List<EventOperation> eventOperationList = new ArrayList<>();
for (GeofenceData geofenceData : geoFencesOfGroup) {
for (GeofenceData geofenceData : this.geoFencesOfGroup) {
GeoFenceEventMeta geoFenceEventMeta = new GeoFenceEventMeta(geofenceData);
EventOperation eventOperation = new EventOperation();
eventOperation.setEventDefinition(geoFenceEventMeta);
@ -204,12 +217,10 @@ public class GroupEventOperationExecutor implements Runnable {
/**
* Set operation payload GeoFence for EVENT_REVOKE operation
* @param operation operation object to attach payload
* @throws EventConfigurationException failed while getting events of group
*/
private void setGeoFenceRevokeOperationContent(ProfileOperation operation) throws EventConfigurationException {
List<GeofenceData> geoFencesOfGroup = getGeoFencesOfGroup();
private void setGeoFenceRevokeOperationContent(ProfileOperation operation){
List<EventRevokeOperation> revokeOperationList = new ArrayList<>();
for (GeofenceData geofenceData : geoFencesOfGroup) {
for (GeofenceData geofenceData : this.geoFencesOfGroup) {
EventRevokeOperation eventRevokeOperation = new EventRevokeOperation();
eventRevokeOperation.setEventSource(DeviceManagementConstants.EventServices.GEOFENCE);
eventRevokeOperation.setId(geofenceData.getId());

@ -1,307 +0,0 @@
/*
* 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.event.config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
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.event.config.EventConfig;
import org.wso2.carbon.device.mgt.common.event.config.EventOperation;
import org.wso2.carbon.device.mgt.common.event.config.EventRevokeOperation;
import org.wso2.carbon.device.mgt.common.event.config.EventTaskEntry;
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFenceEventMeta;
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.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
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.EventConfigDAO;
import org.wso2.carbon.device.mgt.core.dao.EventManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GeofenceDAO;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationMgtConstants;
import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
import org.wso2.carbon.device.mgt.core.task.impl.RandomlyAssignedScheduleTask;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Event create/revoke operation creation task.
* Use at the time of single event create, update, delete
*/
public class GroupEventOperationCreationTask extends RandomlyAssignedScheduleTask {
private static final Log log = LogFactory.getLog(GroupEventOperationCreationTask.class);
private static final String TASK_NAME = "GROUP_EVENT_CREATE_TASK";
private GroupManagementProviderService groupManagementService;
private EventConfigDAO eventConfigDAO;
private GeofenceDAO geofenceDAO;
private int tenantId;
@Override
protected void setup() {
if (this.groupManagementService == null) {
this.groupManagementService = DeviceManagementDataHolder.getInstance().getGroupManagementProviderService();
}
if (this.eventConfigDAO == null) {
this.eventConfigDAO = DeviceManagementDAOFactory.getEventConfigDAO();
}
if (this.geofenceDAO == null) {
this.geofenceDAO = DeviceManagementDAOFactory.getGeofenceDAO();
}
}
@Override
protected void executeRandomlyAssignedTask() {
if (log.isDebugEnabled()) {
log.debug("Starting event operation creation task");
}
try {
DeviceManagementDAOFactory.openConnection();
Map<Integer, List<EventTaskEntry>> eventTaskEntries = eventConfigDAO
.getAvailableEventTaskEntries(EventTaskEntry.ExecutionStatus.CREATED.toString());
DeviceManagementDAOFactory.closeConnection();
for (Map.Entry<Integer, List<EventTaskEntry>> eventTaskEntry : eventTaskEntries.entrySet()) {
this.tenantId = eventTaskEntry.getKey();
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(this.tenantId, true);
this.processEventsOfTenant(eventTaskEntry.getValue());
PrivilegedCarbonContext.endTenantFlow();
}
} catch (EventManagementDAOException e) {
log.error("Failed while retrieving event task entries", e);
} catch (SQLException e) {
log.error("Failed while opening connection", e);
}
}
/**
* Process event entries of a particular tenant
* @param eventTaskEntries list of geo fence task entries
*/
private void processEventsOfTenant(List<EventTaskEntry> eventTaskEntries) {
Map<String, List<EventTaskEntry>> eventSourceTaskMap = new HashMap<>();
for (EventTaskEntry eventTaskEntry : eventTaskEntries) {
List<EventTaskEntry> eventsOfSource = eventSourceTaskMap.get(eventTaskEntry.getEventSource());
if (eventsOfSource == null) {
eventsOfSource = new ArrayList<>();
}
eventsOfSource.add(eventTaskEntry);
eventSourceTaskMap.put(eventTaskEntry.getEventSource(), eventsOfSource);
}
for (Map.Entry<String, List<EventTaskEntry>> eventEntry : eventSourceTaskMap.entrySet()) {
switch (eventEntry.getKey()) {
case DeviceManagementConstants.EventServices.GEOFENCE :
processGeoFenceEventList(eventEntry.getValue());
break;
default:
log.error("Invalid event source" + eventEntry.getKey());
}
}
}
/**
* Devide event task entries into configuration entries and revoke entries
* @param geoFenceTaskList list of geo fence task entries
*/
private void processGeoFenceEventList(List<EventTaskEntry> geoFenceTaskList) {
Map<Integer, List<Integer>> geoFenceConfigEventMap = new HashMap<>();
Map<Integer, List<Integer>> geoFenceRevokeEventMap = new HashMap<>();
for (EventTaskEntry geoFenceTask : geoFenceTaskList) {
if (geoFenceTask.getOperationCode().equals(OperationMgtConstants.OperationCodes.EVENT_CONFIG)) {
List<Integer> groupIdList = geoFenceConfigEventMap.get(geoFenceTask.getEventMetaId());
if (groupIdList == null) {
groupIdList = new ArrayList<>();
}
groupIdList.add(geoFenceTask.getGroupId());
geoFenceConfigEventMap.put(geoFenceTask.getEventMetaId(), groupIdList);
} else if (geoFenceTask.getOperationCode().equals(OperationMgtConstants.OperationCodes.EVENT_REVOKE)) {
List<Integer> groupIdList = geoFenceRevokeEventMap.get(geoFenceTask.getEventMetaId());
if (groupIdList == null) {
groupIdList = new ArrayList<>();
}
groupIdList.add(geoFenceTask.getGroupId());
geoFenceRevokeEventMap.put(geoFenceTask.getEventMetaId(), groupIdList);
}
}
if (!geoFenceConfigEventMap.isEmpty()) {
buildGeoFenceConfigOperation(geoFenceConfigEventMap);
}
if (!geoFenceRevokeEventMap.isEmpty()) {
buildGeoFenceRevokeOperation(geoFenceRevokeEventMap);
}
}
/**
* Build EVENT_REVOKE operation for geo fence event operation
* @param geoFenceRevokeEventMap group Ids mapped with geofence ID
*/
private void buildGeoFenceRevokeOperation(Map<Integer, List<Integer>> geoFenceRevokeEventMap) {
try {
DeviceManagementDAOFactory.openConnection();
for (Map.Entry<Integer, List<Integer>> eventGroupEntry : geoFenceRevokeEventMap.entrySet()) {
ProfileOperation revokeOperation = new ProfileOperation();
revokeOperation.setType(Operation.Type.PROFILE);
revokeOperation.setCode(OperationMgtConstants.OperationCodes.EVENT_REVOKE);
GeofenceData geofence = geofenceDAO.getGeofence(eventGroupEntry.getKey());
EventRevokeOperation eventRevokeOperation = new EventRevokeOperation();
eventRevokeOperation.setEventSource(DeviceManagementConstants.EventServices.GEOFENCE);
eventRevokeOperation.setId(geofence.getId());
JSONArray payloadArray = new JSONArray();
payloadArray.put(new JSONObject(eventRevokeOperation));
revokeOperation.setPayLoad(payloadArray.toString());
createOperationEntryForGroup(revokeOperation, DeviceManagementConstants.EventServices.GEOFENCE,
eventGroupEntry.getValue());
}
DeviceManagementDAOFactory.closeConnection();
} catch (SQLException e) {
log.error("Failed while opening connection", e);
} catch (DeviceManagementDAOException e) {
log.error("Error occurred while retrieving geofence data", e);
}
}
/**
* Build EVENT_CONFIG operation for geo fence event operation
* @param geoFenceConfigEventMap group Ids mapped with geofence ID
*/
private void buildGeoFenceConfigOperation(Map<Integer, List<Integer>> geoFenceConfigEventMap) {
try {
DeviceManagementDAOFactory.openConnection();
for (Map.Entry<Integer, List<Integer>> eventGroupEntry : geoFenceConfigEventMap.entrySet()) {
ProfileOperation configOperation = new ProfileOperation();
configOperation.setType(Operation.Type.PROFILE);
configOperation.setCode(OperationMgtConstants.OperationCodes.EVENT_CONFIG);
GeofenceData geofence = geofenceDAO.getGeofence(eventGroupEntry.getKey());
List<EventConfig> eventsOfGeoFence = geofenceDAO.getEventsOfGeoFence(geofence.getId());
EventOperation eventOperation = new EventOperation();
eventOperation.setEventDefinition(new GeoFenceEventMeta(geofence));
eventOperation.setEventSource(DeviceManagementConstants.EventServices.GEOFENCE);
eventOperation.setEventTriggers(eventsOfGeoFence);
JSONArray payloadArray = new JSONArray();
payloadArray.put(new JSONObject(eventOperation));
configOperation.setPayLoad(payloadArray.toString());
createOperationEntryForGroup(configOperation, DeviceManagementConstants.EventServices.GEOFENCE,
eventGroupEntry.getValue());
}
DeviceManagementDAOFactory.closeConnection();
} catch (SQLException e) {
log.error("Failed while opening connection", e);
} catch (DeviceManagementDAOException e) {
log.error("Error occurred while retrieving geofence data", e);
}
}
/**
* Create event operation of the groups
* @param operation creating operation
* @param eventSource event source type
* @param groupIds group Id list
*/
private void createOperationEntryForGroup(ProfileOperation operation, String eventSource, List<Integer> groupIds) {
Set<Device> devices = new HashSet<>();
for (Integer groupId : groupIds) {
DeviceGroup group;
try {
group = groupManagementService.getGroup(groupId, false);
} catch (GroupManagementException e) {
log.error("Failed to retrieve group with group ID " + groupId, e);
continue;
}
try {
if (group != null) {
List<Device> allDevicesOfGroup = groupManagementService.getAllDevicesOfGroup(group.getName(), false);
if (allDevicesOfGroup == null || allDevicesOfGroup.isEmpty()) {
log.warn("No devices found in group " + group.getName());
} else {
devices.addAll(allDevicesOfGroup);
}
}
} catch (GroupManagementException e) {
log.error("Failed to retrieve devices of group with ID " + groupId + " and name " + group.getName(), e);
}
}
if (devices.isEmpty()) {
log.warn("No devices found for the specified groups " + Arrays.toString(groupIds.toArray()));
return;
}
List<DeviceIdentifier> deviceIdentifiers = new ArrayList<>();
for (Device device : devices) {
if (device.getType().equalsIgnoreCase("android")) {
//TODO introduce a proper mechanism for event handling for each device types
deviceIdentifiers.add(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType()));
}
}
DeviceManagementProviderService deviceManagementProvider = DeviceManagementDataHolder
.getInstance().getDeviceManagementProvider();
try {
if (log.isDebugEnabled()) {
log.debug("Creating event operations stared for devices" + Arrays.toString(deviceIdentifiers.toArray()));
}
deviceManagementProvider.addOperation("android", operation, deviceIdentifiers);
//TODO introduce a proper mechanism
} catch (OperationManagementException e) {
log.error("Creating event operation failed with error ", e);
return;
} catch (InvalidDeviceException e) {
log.error("Creating event operation failed.\n" +
"Could not found device/devices for the defined device identifiers.", e);
return;
}
if (log.isDebugEnabled()) {
log.debug("Event operation creation task completed");
}
try {
eventConfigDAO.setEventTaskComplete(operation.getCode(), eventSource, groupIds, this.tenantId);
} catch (EventManagementDAOException e) {
log.error("Failed while updating event task records", e);
}
}
@Override
public String getTaskName() {
return TASK_NAME;
}
@Override
public void setProperties(Map<String, String> map) {
}
}

@ -0,0 +1,37 @@
/*
* Copyright (c) 2021, 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.event.config.exception;
public class EventManagementException extends Exception{
public EventManagementException(String message) {
super(message);
}
public EventManagementException(String message, Throwable cause) {
super(message, cause);
}
public EventManagementException(Throwable cause) {
super(cause);
}
protected EventManagementException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

@ -42,10 +42,10 @@ 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.event.config.EventConfigurationException;
import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationProviderService;
import org.wso2.carbon.device.mgt.common.event.config.EventTaskEntry;
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;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFenceEventMeta;
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;
@ -56,7 +56,6 @@ import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.GeofenceDAO;
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
import org.wso2.carbon.device.mgt.core.dto.event.config.GeoFenceGroupMap;
import org.wso2.carbon.device.mgt.core.geo.task.GeoFenceEventOperationManager;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationMgtConstants;
import org.wso2.carbon.event.processor.stub.EventProcessorAdminServiceStub;
@ -92,9 +91,6 @@ import java.util.Map;
import java.util.Properties;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices.DAS_PORT;
import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices.DEFAULT_HTTP_PROTOCOL;
@ -1323,8 +1319,9 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
}
try {
eventConfigService.createEventOperationTask(getEventOperationTask(OperationMgtConstants
.OperationCodes.EVENT_CONFIG, geofenceData.getId(), tenantId), geofenceData.getGroupIds());
eventConfigService.createEventOperationTask(OperationMgtConstants.OperationCodes.EVENT_CONFIG,
DeviceManagementConstants.EventServices.GEOFENCE, new GeoFenceEventMeta(geofenceData),
tenantId, geofenceData.getGroupIds());
} catch (EventConfigurationException e) {
String msg = "Failed while creating EVENT_REVOKE operation creation task entry while updating geo fence "
+ geofenceData.getFenceName() + " of the tenant " + tenantId;
@ -1652,8 +1649,9 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
log.debug("Update geofence event completed.");
}
try {
eventConfigService.createEventOperationTask(getEventOperationTask(OperationMgtConstants
.OperationCodes.EVENT_REVOKE, geofenceData.getId(), tenantId), geofenceData.getGroupIds());
eventConfigService.createEventOperationTask(OperationMgtConstants.OperationCodes.EVENT_REVOKE,
DeviceManagementConstants.EventServices.GEOFENCE,
new GeoFenceEventMeta(geofenceData), tenantId, geofenceData.getGroupIds());
} catch (EventConfigurationException e) {
String msg = "Failed while creating EVENT_REVOKE operation creation task entry while updating geo fence "
+ geofenceData.getFenceName() + " of the tenant " + tenantId;
@ -1767,8 +1765,9 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
EventConfigurationProviderService eventConfigService = DeviceManagementDataHolder
.getInstance().getEventConfigurationService();
eventConfigService.deleteEvents(eventList);
eventConfigService.createEventOperationTask(getEventOperationTask(OperationMgtConstants
.OperationCodes.EVENT_REVOKE, geofenceData.getId(), tenantId), geofenceData.getGroupIds());
eventConfigService.createEventOperationTask(OperationMgtConstants.OperationCodes.EVENT_REVOKE,
DeviceManagementConstants.EventServices.GEOFENCE, new GeoFenceEventMeta(geofenceData),
tenantId, geofenceData.getGroupIds());
} catch (EventConfigurationException e) {
DeviceManagementDAOFactory.rollbackTransaction();
String msg = "Failed to delete Geofence event configurations";
@ -1778,21 +1777,4 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic
DeviceManagementDAOFactory.closeConnection();
}
}
/**
* Build and retrieve the EventTaskEntry object
* @param operationCode operationCode of the requesting EventTask
* @param geoFenceId id of the geofence which the task creating
* @param tenantId id of the tenant owns the geofence
* @return built EventTaskEntry object
*/
private EventTaskEntry getEventOperationTask(String operationCode, int geoFenceId, int tenantId) {
EventTaskEntry eventTaskEntry = new EventTaskEntry();
eventTaskEntry.setEventSource(DeviceManagementConstants.EventServices.GEOFENCE);
eventTaskEntry.setExecutionStatus(EventTaskEntry.ExecutionStatus.CREATED);
eventTaskEntry.setOperationCode(operationCode);
eventTaskEntry.setEventMetaId(geoFenceId);
eventTaskEntry.setTenantId(tenantId);
return eventTaskEntry;
}
}

@ -1,84 +0,0 @@
/*
* 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.geo.task;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.core.event.config.EventOperationTaskConfiguration;
import org.wso2.carbon.device.mgt.core.event.config.GroupEventOperationCreationTask;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.status.task.DeviceStatusTaskException;
import org.wso2.carbon.ntask.common.TaskException;
import org.wso2.carbon.ntask.core.TaskInfo;
import org.wso2.carbon.ntask.core.TaskManager;
import org.wso2.carbon.ntask.core.service.TaskService;
public class EventOperationTaskManagerImpl {
private static final Log log = LogFactory.getLog(EventOperationTaskManagerImpl.class);
public static final String GROUP_EVENT_OPERATION_TASK_TYPE = "GROUP_EVENT_CREATION";
private static final String TASK_NAME = "GROUP_EVENT_TASK";
private static final String TASK_CLASS = GroupEventOperationCreationTask.class.getName();
public void startGroupEventOperationTask(EventOperationTaskConfiguration eventTaskConfig)
throws EventOperationTaskException {
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
taskService.registerTaskType(GROUP_EVENT_OPERATION_TASK_TYPE);
if (log.isDebugEnabled()) {
log.debug("Group event creation task is started");
log.debug(
"Group event creation task is at frequency of : " + eventTaskConfig.getFrequency());
}
TaskManager taskManager = taskService.getTaskManager(GROUP_EVENT_OPERATION_TASK_TYPE);
TaskInfo.TriggerInfo triggerInfo = new TaskInfo.TriggerInfo();
//Convert to milli seconds
triggerInfo.setIntervalMillis(eventTaskConfig.getFrequency());
triggerInfo.setRepeatCount(-1);
if (!taskManager.isTaskScheduled(GROUP_EVENT_OPERATION_TASK_TYPE)) {
TaskInfo taskInfo = new TaskInfo(TASK_NAME, TASK_CLASS, null, triggerInfo);
taskManager.registerTask(taskInfo);
taskManager.rescheduleTask(taskInfo.getName());
} else {
String msg = "Group event creation task is already started";
log.error(msg);
throw new EventOperationTaskException(msg);
}
} catch (TaskException e) {
String msg = "Error occurred while creating the group event operation task";
log.error(msg, e);
throw new EventOperationTaskException(msg, e);
}
}
public void stopGroupEventOperationTaskTask() throws EventOperationTaskException {
try {
TaskService taskService = DeviceManagementDataHolder.getInstance().getTaskService();
if (taskService != null && taskService.isServerInit()) {
TaskManager taskManager = taskService.getTaskManager(GROUP_EVENT_OPERATION_TASK_TYPE);
taskManager.deleteTask(TASK_NAME);
}
} catch (TaskException e) {
String msg = "Error occurred while stopping the group event operation task";
log.error(msg, e);
throw new EventOperationTaskException(msg, e);
}
}
}

@ -18,11 +18,14 @@
package org.wso2.carbon.device.mgt.core.geo.task;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.geo.service.GeoFenceEventMeta;
import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData;
import org.wso2.carbon.device.mgt.core.event.config.GroupEventOperationExecutor;
import org.wso2.carbon.device.mgt.common.event.config.EventMetaData;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.event.config.EventOperationExecutor;
import org.wso2.carbon.device.mgt.core.event.config.GroupAssignmentEventOperationExecutor;
import java.util.List;
@ -31,14 +34,19 @@ import java.util.List;
* Wrap event operation executor creation
*/
public class GeoFenceEventOperationManager {
private static final Log log = LogFactory.getLog(GeoFenceEventOperationManager.class);
private final int tenantId;
private final String eventOperationCode;
private final EventCreateCallback callback;
private final boolean isEventEnabled;
public GeoFenceEventOperationManager(String eventOperationCode, int tenantId, EventCreateCallback callback) {
this.eventOperationCode = eventOperationCode;
this.tenantId = tenantId;
this.callback = callback;
isEventEnabled= DeviceConfigurationManager.getInstance().getDeviceManagementConfig()
.getEventOperationTaskConfiguration().isEnabled();
}
/**
@ -46,11 +54,37 @@ public class GeoFenceEventOperationManager {
* assigned into a group or removed from a group
* @param groupId Id of the assigned / removed group
* @param deviceIdentifiers Device identifiers assigned to / removed from the group
* @return {@link GroupEventOperationExecutor} Created executor to create operations
* @return {@link GroupAssignmentEventOperationExecutor} Created executor to create operations
*/
public GroupAssignmentEventOperationExecutor getGroupAssignmentEventExecutor(int groupId,
List<DeviceIdentifier> deviceIdentifiers) {
if (this.isEventEnabled) {
GroupAssignmentEventOperationExecutor executor = new GroupAssignmentEventOperationExecutor(groupId,
deviceIdentifiers, tenantId, eventOperationCode);
executor.setCallback(callback);
return executor;
}
if (log.isDebugEnabled()) {
log.debug("Ignoring geo fence event creation since not enabled from configurations");
}
return null;
}
/**
* Get executor for create EVENT_CONFIG / EVENT_REVOKE operations at the time of a event is created
* @param groupIds list of group ids to apply the created event
* @param eventMetaData contains all the data of the related event
* @return {@link EventOperationExecutor} The created event executor object
*/
public GroupEventOperationExecutor getEventOperationExecutor(int groupId, List<DeviceIdentifier> deviceIdentifiers) {
GroupEventOperationExecutor executor = new GroupEventOperationExecutor(groupId, deviceIdentifiers, tenantId, eventOperationCode);
executor.setCallback(callback);
return executor;
public EventOperationExecutor getEventOperationExecutor(List<Integer> groupIds, EventMetaData eventMetaData) {
if (this.isEventEnabled) {
EventOperationExecutor executor = new EventOperationExecutor(eventMetaData, groupIds,
this.tenantId, DeviceManagementConstants.EventServices.GEOFENCE, this.eventOperationCode);
return executor;
}
if (log.isDebugEnabled()) {
log.debug("Ignoring geo fence event creation since not enabled from configurations");
}
return null;
}
}

@ -33,7 +33,7 @@ import org.wso2.carbon.device.mgt.core.config.license.LicenseConfig;
import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.core.geo.task.EventOperationTaskManagerImpl;
import org.wso2.carbon.device.mgt.core.geo.task.GeoFenceEventOperationManager;
import org.wso2.carbon.device.mgt.core.privacy.PrivacyComplianceProvider;
import org.wso2.carbon.device.mgt.core.push.notification.mgt.PushNotificationProviderRepository;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
@ -50,6 +50,7 @@ import org.wso2.carbon.utils.ConfigurationContextService;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
public class DeviceManagementDataHolder {
@ -78,7 +79,8 @@ public class DeviceManagementDataHolder {
private PrivacyComplianceProvider privacyComplianceProvider;
private EventConfigurationProviderService eventConfigurationService;
private GeoLocationProviderService geoLocationProviderService;
private EventOperationTaskManagerImpl eventOperationTaskManager;
private GeoFenceEventOperationManager geoFenceEventOperationManager;
private ExecutorService eventConfigExecutors;
private final Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
new HashMap<>());
@ -321,11 +323,19 @@ public class DeviceManagementDataHolder {
this.geoLocationProviderService = geoLocationProviderService;
}
public void setEventOperationTaskManager(EventOperationTaskManagerImpl eventOperationTaskManager) {
this.eventOperationTaskManager = eventOperationTaskManager;
public GeoFenceEventOperationManager getGeoFenceEventOperationManager() {
return geoFenceEventOperationManager;
}
public EventOperationTaskManagerImpl getEventOperationTaskManager() {
return eventOperationTaskManager;
public void setGeoFenceEventOperationManager(GeoFenceEventOperationManager geoFenceEventOperationManager) {
this.geoFenceEventOperationManager = geoFenceEventOperationManager;
}
public ExecutorService getEventConfigExecutors() {
return eventConfigExecutors;
}
public void setEventConfigExecutors(ExecutorService eventConfigExecutors) {
this.eventConfigExecutors = eventConfigExecutors;
}
}

@ -89,6 +89,7 @@ import org.wso2.carbon.utils.ConfigurationContextService;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -372,6 +373,9 @@ public class DeviceManagementServiceComponent {
DeviceManagementDataHolder.getInstance().setDeviceInformationManager(deviceInformationManager);
bundleContext.registerService(SearchManagerService.class, new SearchManagerServiceImpl(), null);
ExecutorService executorService = Executors.newFixedThreadPool(50);
DeviceManagementDataHolder.getInstance().setEventConfigExecutors(executorService);
}
private void setupDeviceManagementSchema(DataSourceConfig config) throws DeviceManagementException {

@ -26,10 +26,7 @@ import org.wso2.carbon.device.mgt.common.DeviceStatusTaskPluginConfig;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
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.event.config.EventOperationTaskConfiguration;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.geo.task.EventOperationTaskException;
import org.wso2.carbon.device.mgt.core.geo.task.EventOperationTaskManagerImpl;
import org.wso2.carbon.device.mgt.core.status.task.DeviceStatusTaskException;
import org.wso2.carbon.device.mgt.core.status.task.DeviceStatusTaskManagerService;
import org.wso2.carbon.device.mgt.core.status.task.impl.DeviceStatusTaskManagerServiceImpl;
@ -63,7 +60,6 @@ public class DeviceTaskManagerServiceComponent {
log.debug("Initializing device task manager bundle.");
}
startOperationMonitoringTask(componentContext.getBundleContext());
startGroupEventCreationTask(componentContext.getBundleContext());
//Start the DeviceStatusMonitoringTask for registered DeviceTypes
deviceManagementConfig = DeviceConfigurationManager.getInstance().
getDeviceManagementConfig();
@ -112,9 +108,6 @@ public class DeviceTaskManagerServiceComponent {
stopOperationMonitoringTask();
if (deviceManagementConfig != null && deviceManagementConfig.getDeviceStatusTaskConfig().isEnabled()) {
stopDeviceStatusMonitoringTask();
} else if (deviceManagementConfig != null && deviceManagementConfig.getEventOperationTaskConfiguration()
.isEnabled()) {
stopGroupEventCreationTask();
}
} catch (Throwable e) {
log.error("Error occurred while shutting down device task manager service.", e);
@ -150,38 +143,6 @@ public class DeviceTaskManagerServiceComponent {
}
}
/**
* Start event operation creation task
* @param bundleContext OsgiBundle context
*/
private void startGroupEventCreationTask(BundleContext bundleContext) {
DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
EventOperationTaskConfiguration eventTaskConfig = deviceManagementConfig.getEventOperationTaskConfiguration();
if (eventTaskConfig.isEnabled()) {
EventOperationTaskManagerImpl eventOperationTaskManager = new EventOperationTaskManagerImpl();
DeviceManagementDataHolder.getInstance().setEventOperationTaskManager(eventOperationTaskManager);
bundleContext.registerService(EventOperationTaskManagerImpl.class, eventOperationTaskManager, null);
try {
eventOperationTaskManager.startGroupEventOperationTask(eventTaskConfig);
} catch (EventOperationTaskException e) {
log.error("Error occurred while creating group event creation task");
}
}
}
/**
* Stop event operation creation task
*/
private void stopGroupEventCreationTask() {
EventOperationTaskManagerImpl eventOperationTaskManager = DeviceManagementDataHolder.getInstance()
.getEventOperationTaskManager();
try {
eventOperationTaskManager.stopGroupEventOperationTaskTask();
} catch (EventOperationTaskException e) {
log.error("Error occurred while stopping group event creation task");
}
}
protected void setTaskService(TaskService taskService) {
if (log.isDebugEnabled()) {
log.debug("Setting the task service.");

@ -36,11 +36,14 @@ import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException;
import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.dao.DeviceDAO;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.GroupDAO;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOException;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.event.config.EventOperationTaskConfiguration;
import org.wso2.carbon.device.mgt.core.event.config.GroupAssignmentEventOperationExecutor;
import org.wso2.carbon.device.mgt.core.geo.task.GeoFenceEventOperationManager;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.operation.mgt.OperationMgtConstants;
@ -54,9 +57,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class GroupManagementProviderServiceImpl implements GroupManagementProviderService {
@ -1061,10 +1063,20 @@ public class GroupManagementProviderServiceImpl implements GroupManagementProvid
* @param deviceIdentifiers devices assigning to/removing from group
* @param tenantId tenant of the group
*/
private void createEventTask(String eventOperationCode, int groupId, List<DeviceIdentifier> deviceIdentifiers, int tenantId) {
private void createEventTask(String eventOperationCode, int groupId, List<DeviceIdentifier> deviceIdentifiers,
int tenantId) {
GeoFenceEventOperationManager eventManager = new GeoFenceEventOperationManager(eventOperationCode, tenantId, null);
ScheduledExecutorService eventOperationExecutor = Executors.newSingleThreadScheduledExecutor();
eventOperationExecutor.schedule(eventManager
.getEventOperationExecutor(groupId, deviceIdentifiers), 10, TimeUnit.SECONDS);
GroupAssignmentEventOperationExecutor eventOperationExecutor = eventManager
.getGroupAssignmentEventExecutor(groupId, deviceIdentifiers);
if (eventOperationExecutor != null) {
ExecutorService eventConfigExecutors = DeviceManagementDataHolder.getInstance().getEventConfigExecutors();
if (eventConfigExecutors != null) {
eventConfigExecutors.submit(eventOperationExecutor);
}
} else {
if (log.isDebugEnabled()) {
log.debug("Ignoring event creation since not enabled. Tenant id: " + tenantId + " Group Id: " + groupId);
}
}
}
}

@ -97,6 +97,9 @@
server environment-->
<Capacity>10000</Capacity>
</GeoFenceCacheConfiguration>
<EventOperationTaskConfiguration>
<Enable>true</Enable>
</EventOperationTaskConfiguration>
<CertificateCacheConfiguration>
<Enable>false</Enable>
<ExpiryTime>86400</ExpiryTime>

@ -121,6 +121,9 @@
<GeoLocationConfiguration>
<Enabled>false</Enabled>
</GeoLocationConfiguration>
<EventOperationTaskConfiguration>
<Enable>true</Enable>
</EventOperationTaskConfiguration>
<OperationAnalyticsConfiguration>
<PublishLocationResponse>false</PublishLocationResponse>
<PublishDeviceInfoResponse>false</PublishDeviceInfoResponse>

@ -92,14 +92,10 @@
<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>
<EventOperationTaskConfiguration>
<Enable>true</Enable>
<Frequency>60000</Frequency>
</EventOperationTaskConfiguration>
<CertificateCacheConfiguration>
<Enable>true</Enable>

@ -722,22 +722,4 @@ CREATE TABLE IF NOT EXISTS DM_GEOFENCE_EVENT_MAPPING (
DM_DEVICE_EVENT (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
-- END OF DM_GEOFENCE_GROUP_MAPPING TABLE--
-- DM_GROUP_EVENT_ASSIGNMENT_TASK TABLE--
CREATE TABLE IF NOT EXISTS DM_EVENT_OPERATION_ASSIGNMENT_TASK (
ID INT NOT NULL AUTO_INCREMENT,
DEVICE_ID INT DEFAULT NULL,
GROUP_ID INT DEFAULT NULL,
OPERATION_CODE VARCHAR(100) NOT NULL,
EVENT_SOURCE VARCHAR(250) NOT NULL,
EVENT_META_ID INT DEFAULT NULL,
STATUS VARCHAR(100) NOT NULL,
TENANT_ID INT NOT NULL,
CREATED_TIMESTAMP TIMESTAMP NOT NULL,
COMPLETED_TIMESTAMP TIMESTAMP DEFAULT NULL,
PRIMARY KEY (ID)
);
-- END OF DM_GROUP_EVENT_ASSIGNMENT_TASK TABLE--
-- END OF DM_GEOFENCE_GROUP_MAPPING TABLE--

@ -786,22 +786,4 @@ CREATE TABLE IF NOT EXISTS DM_GEOFENCE_EVENT_MAPPING (
DM_DEVICE_EVENT (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB;
-- END OF DM_GEOFENCE_GROUP_MAPPING TABLE--
-- DM_GROUP_EVENT_ASSIGNMENT_TASK TABLE--
CREATE TABLE IF NOT EXISTS DM_EVENT_OPERATION_ASSIGNMENT_TASK (
ID INT NOT NULL AUTO_INCREMENT,
DEVICE_ID INT DEFAULT NULL,
GROUP_ID INT DEFAULT NULL,
OPERATION_CODE VARCHAR(100) NOT NULL,
EVENT_SOURCE VARCHAR(250) NOT NULL,
EVENT_META_ID INT DEFAULT NULL,
STATUS VARCHAR(100) NOT NULL,
TENANT_ID INT NOT NULL,
CREATED_TIMESTAMP TIMESTAMP NOT NULL,
COMPLETED_TIMESTAMP TIMESTAMP DEFAULT NULL,
PRIMARY KEY (ID)
) ENGINE=InnoDB;
-- END OF DM_GROUP_EVENT_ASSIGNMENT_TASK TABLE--
-- END OF DM_GEOFENCE_GROUP_MAPPING TABLE--
Loading…
Cancel
Save