mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
adding randomly assigned task functionality and other improvements
This commit is contained in:
parent
9d39197844
commit
c6db9eeecc
@ -23,13 +23,14 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException;
|
import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||||
import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl;
|
import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl;
|
||||||
import org.wso2.carbon.ntask.core.Task;
|
import org.wso2.carbon.device.mgt.core.task.impl.RandomlyAssignedScheduleTask;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ScheduledAppSubscriptionCleanupTask implements Task {
|
public class ScheduledAppSubscriptionCleanupTask extends RandomlyAssignedScheduleTask {
|
||||||
private static Log log = LogFactory.getLog(ScheduledAppSubscriptionCleanupTask.class);
|
private static Log log = LogFactory.getLog(ScheduledAppSubscriptionCleanupTask.class);
|
||||||
private SubscriptionManager subscriptionManager;
|
private SubscriptionManager subscriptionManager;
|
||||||
|
private static final String TASK_NAME = "SCHEDULE_APP_SUBSCRIPTION_CLEANUP";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProperties(Map<String, String> properties) {
|
public void setProperties(Map<String, String> properties) {
|
||||||
@ -37,18 +38,25 @@ public class ScheduledAppSubscriptionCleanupTask implements Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void executeRandomlyAssignedTask() {
|
||||||
|
try {
|
||||||
|
if(super.isQualifiedToExecuteTask()) {
|
||||||
|
subscriptionManager.cleanScheduledSubscriptions();
|
||||||
|
}
|
||||||
|
} catch (SubscriptionManagementException e) {
|
||||||
|
log.error("Error occurred while cleaning up tasks.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setup() {
|
||||||
if (this.subscriptionManager == null) {
|
if (this.subscriptionManager == null) {
|
||||||
this.subscriptionManager = new SubscriptionManagerImpl();
|
this.subscriptionManager = new SubscriptionManagerImpl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public String getTaskName() {
|
||||||
try {
|
return TASK_NAME;
|
||||||
subscriptionManager.cleanScheduledSubscriptions();
|
|
||||||
} catch (SubscriptionManagementException e) {
|
|
||||||
log.error("Error occurred while cleaning up tasks.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,15 +33,17 @@ import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManage
|
|||||||
import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl;
|
import org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl;
|
||||||
import org.wso2.carbon.device.application.mgt.core.util.Constants;
|
import org.wso2.carbon.device.application.mgt.core.util.Constants;
|
||||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
import org.wso2.carbon.ntask.core.Task;
|
import org.wso2.carbon.device.mgt.core.task.impl.RandomlyAssignedScheduleTask;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ScheduledAppSubscriptionTask implements Task {
|
public class ScheduledAppSubscriptionTask extends RandomlyAssignedScheduleTask {
|
||||||
private static Log log = LogFactory.getLog(ScheduledAppSubscriptionTask.class);
|
private static Log log = LogFactory.getLog(ScheduledAppSubscriptionTask.class);
|
||||||
|
private static final String TASK_NAME = "SCHEDULE_APP_SUBSCRIPTION";
|
||||||
|
|
||||||
private SubscriptionManager subscriptionManager;
|
private SubscriptionManager subscriptionManager;
|
||||||
private String subscribers;
|
private String subscribers;
|
||||||
private String subscriptionType;
|
private String subscriptionType;
|
||||||
@ -65,14 +67,8 @@ public class ScheduledAppSubscriptionTask implements Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void executeRandomlyAssignedTask() {
|
||||||
if (this.subscriptionManager == null) {
|
if(super.isQualifiedToExecuteTask()) {
|
||||||
this.subscriptionManager = new SubscriptionManagerImpl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute() {
|
|
||||||
try {
|
try {
|
||||||
ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription(
|
ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription(
|
||||||
this.taskName);
|
this.taskName);
|
||||||
@ -130,3 +126,16 @@ public class ScheduledAppSubscriptionTask implements Task {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setup() {
|
||||||
|
if (this.subscriptionManager == null) {
|
||||||
|
this.subscriptionManager = new SubscriptionManagerImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTaskName() {
|
||||||
|
return TASK_NAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -68,14 +68,13 @@ public class DeviceStatusMonitoringTask extends DynamicPartitionedScheduleTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void executeDynamicTask() {
|
||||||
List<OperationEnrolmentMapping> operationEnrolmentMappings;
|
List<OperationEnrolmentMapping> operationEnrolmentMappings;
|
||||||
List<EnrolmentInfo> enrolmentInfoTobeUpdated = new ArrayList<>();
|
List<EnrolmentInfo> enrolmentInfoTobeUpdated = new ArrayList<>();
|
||||||
Map<Integer, Long> lastActivities = null;
|
Map<Integer, Long> lastActivities = null;
|
||||||
EnrolmentInfo enrolmentInfo;
|
EnrolmentInfo enrolmentInfo;
|
||||||
DeviceIdentifier deviceIdentifier;
|
DeviceIdentifier deviceIdentifier;
|
||||||
Device device;
|
Device device;
|
||||||
super.refreshContext();
|
|
||||||
try {
|
try {
|
||||||
operationEnrolmentMappings = this.getOperationEnrolmentMappings(super.getTaskContext());
|
operationEnrolmentMappings = this.getOperationEnrolmentMappings(super.getTaskContext());
|
||||||
if (operationEnrolmentMappings.size() > 0) {
|
if (operationEnrolmentMappings.size() > 0) {
|
||||||
|
|||||||
@ -65,8 +65,7 @@ public class DeviceDetailsRetrieverTask extends DynamicPartitionedScheduleTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void executeDynamicTask() {
|
||||||
super.refreshContext();
|
|
||||||
deviceManagementProviderService = DeviceManagementDataHolder.getInstance()
|
deviceManagementProviderService = DeviceManagementDataHolder.getInstance()
|
||||||
.getDeviceManagementProvider();
|
.getDeviceManagementProvider();
|
||||||
OperationMonitoringTaskConfig operationMonitoringTaskConfig = deviceManagementProviderService
|
OperationMonitoringTaskConfig operationMonitoringTaskConfig = deviceManagementProviderService
|
||||||
|
|||||||
@ -36,22 +36,12 @@ public abstract class DynamicPartitionedScheduleTask implements Task {
|
|||||||
@Override
|
@Override
|
||||||
public final void init() {
|
public final void init() {
|
||||||
try {
|
try {
|
||||||
ServerCtxInfo ctxInfo = DeviceManagementDataHolder.getInstance().getHeartBeatService().getServerCtxInfo();
|
boolean dynamicTaskEnabled = DeviceManagementDataHolder.getInstance().getHeartBeatService().isTaskPartitioningEnabled();
|
||||||
if(ctxInfo!=null){
|
if(dynamicTaskEnabled){
|
||||||
taskContext = new DynamicTaskContext();
|
taskContext = new DynamicTaskContext();
|
||||||
updateContext(ctxInfo);
|
|
||||||
|
|
||||||
if(ctxInfo.getActiveServerCount() > 0){
|
|
||||||
taskContext.setPartitioningEnabled(true);
|
taskContext.setPartitioningEnabled(true);
|
||||||
}
|
|
||||||
|
|
||||||
if(log.isDebugEnabled()){
|
|
||||||
log.debug("Initiating execution of dynamic task for server : " + taskContext.getServerHashIndex() +
|
|
||||||
" where active server count is : " + taskContext.getActiveServerCount() +
|
|
||||||
" partitioning task enabled : " + taskContext.isPartitioningEnabled());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.error("Error Instantiating Variables necessary for Dynamic Task Scheduling. Dynamic Tasks will not function.");
|
log.info("Error Instantiating Variables necessary for Dynamic Task Scheduling. Dynamic Tasks will not function.");
|
||||||
}
|
}
|
||||||
} catch (HeartBeatManagementException e) {
|
} catch (HeartBeatManagementException e) {
|
||||||
log.error("Error Instantiating Variables necessary for Dynamic Task Scheduling. Dynamic Tasks will not function." , e);
|
log.error("Error Instantiating Variables necessary for Dynamic Task Scheduling. Dynamic Tasks will not function." , e);
|
||||||
@ -59,29 +49,56 @@ public abstract class DynamicPartitionedScheduleTask implements Task {
|
|||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicTaskContext refreshContext(){
|
@Override
|
||||||
try {
|
public final void execute() {
|
||||||
ServerCtxInfo ctxInfo = DeviceManagementDataHolder.getInstance().getHeartBeatService().getServerCtxInfo();
|
refreshContext();
|
||||||
if(ctxInfo != null) {
|
executeDynamicTask();
|
||||||
updateContext(ctxInfo);
|
|
||||||
} else {
|
|
||||||
log.info("Dynamic Task Context not present. Tasks will run on regular worker/manager mode.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void refreshContext(){
|
||||||
|
if(taskContext != null && taskContext.isPartitioningEnabled()) {
|
||||||
|
try {
|
||||||
|
updateContext();
|
||||||
} catch (HeartBeatManagementException e) {
|
} catch (HeartBeatManagementException e) {
|
||||||
log.error("Error refreshing Variables necessary for Dynamic Task Scheduling. Dynamic Tasks will not function.", e);
|
log.error("Error refreshing Variables necessary for Dynamic Task Scheduling. Dynamic Tasks will not function.", e);
|
||||||
}
|
}
|
||||||
return taskContext;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateContext(ServerCtxInfo ctxInfo) {
|
private void updateContext() throws HeartBeatManagementException {
|
||||||
|
ServerCtxInfo ctxInfo = DeviceManagementDataHolder.getInstance().getHeartBeatService().getServerCtxInfo();
|
||||||
|
if(ctxInfo != null) {
|
||||||
|
populateContext(ctxInfo);
|
||||||
|
} else {
|
||||||
|
log.info("Dynamic Task Context not present. Tasks will run on regular worker/manager mode.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateContext(ServerCtxInfo ctxInfo) {
|
||||||
taskContext.setActiveServerCount(ctxInfo.getActiveServerCount());
|
taskContext.setActiveServerCount(ctxInfo.getActiveServerCount());
|
||||||
taskContext.setServerHashIndex(ctxInfo.getLocalServerHashIdx());
|
taskContext.setServerHashIndex(ctxInfo.getLocalServerHashIdx());
|
||||||
|
|
||||||
|
if(log.isDebugEnabled()){
|
||||||
|
log.debug("Initiating execution of dynamic task for server : " + taskContext.getServerHashIndex() +
|
||||||
|
" where active server count is : " + taskContext.getActiveServerCount() +
|
||||||
|
" partitioning task enabled : " + taskContext.isPartitioningEnabled());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void setup();
|
protected abstract void setup();
|
||||||
|
|
||||||
|
protected abstract void executeDynamicTask();
|
||||||
|
|
||||||
public static DynamicTaskContext getTaskContext() {
|
public static DynamicTaskContext getTaskContext() {
|
||||||
return taskContext;
|
return taskContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isDynamicTaskEligible(){
|
||||||
|
if(taskContext != null && taskContext.isPartitioningEnabled()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://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.task.impl;
|
||||||
|
|
||||||
|
import io.entgra.server.bootup.heartbeat.beacon.exception.HeartBeatManagementException;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
|
||||||
|
import org.wso2.carbon.ntask.core.Task;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class RandomlyAssignedScheduleTask implements Task {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(RandomlyAssignedScheduleTask.class);
|
||||||
|
|
||||||
|
private static String taskName = "UNSPECIFIED";
|
||||||
|
private static boolean qualifiedToExecuteTask = false;
|
||||||
|
private static boolean dynamicTaskEnabled = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void init() {
|
||||||
|
try {
|
||||||
|
dynamicTaskEnabled = DeviceManagementDataHolder.getInstance().getHeartBeatService().isTaskPartitioningEnabled();
|
||||||
|
} catch (HeartBeatManagementException e) {
|
||||||
|
log.error("Error Instantiating Variables necessary for Randomly Assigned Task Scheduling." , e);
|
||||||
|
}
|
||||||
|
//This is done so that sub class extending this abstract class is forced to specify a task name.
|
||||||
|
taskName = getTaskName();
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void execute() {
|
||||||
|
refreshContext();
|
||||||
|
executeRandomlyAssignedTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refreshContext(){
|
||||||
|
if(dynamicTaskEnabled) {
|
||||||
|
try {
|
||||||
|
qualifiedToExecuteTask = DeviceManagementDataHolder.getInstance().getHeartBeatService().isQualifiedToExecuteTask();
|
||||||
|
log.info("## NODE Qualified to execute Randomly Assigned Task : " + taskName);
|
||||||
|
DeviceManagementDataHolder.getInstance().getHeartBeatService().updateTaskExecutionAcknowledgement(taskName);
|
||||||
|
} catch (HeartBeatManagementException e) {
|
||||||
|
log.error("Error refreshing Variables necessary for Randomly Assigned Scheduled Task. " +
|
||||||
|
"Dynamic Tasks will not function.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void setup();
|
||||||
|
|
||||||
|
protected abstract void executeRandomlyAssignedTask();
|
||||||
|
|
||||||
|
public static boolean isQualifiedToExecuteTask() {
|
||||||
|
return qualifiedToExecuteTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getTaskName();
|
||||||
|
}
|
||||||
@ -7,6 +7,11 @@ import io.entgra.server.bootup.heartbeat.beacon.service.HeartBeatManagementServi
|
|||||||
import org.wso2.carbon.device.mgt.common.ServerCtxInfo;
|
import org.wso2.carbon.device.mgt.common.ServerCtxInfo;
|
||||||
|
|
||||||
public class TestHeartBeatManagementService implements HeartBeatManagementService {
|
public class TestHeartBeatManagementService implements HeartBeatManagementService {
|
||||||
|
@Override
|
||||||
|
public boolean isTaskPartitioningEnabled() throws HeartBeatManagementException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerCtxInfo getServerCtxInfo() throws HeartBeatManagementException {
|
public ServerCtxInfo getServerCtxInfo() throws HeartBeatManagementException {
|
||||||
return null;
|
return null;
|
||||||
@ -21,4 +26,20 @@ public class TestHeartBeatManagementService implements HeartBeatManagementServic
|
|||||||
public boolean recordHeartBeat(HeartBeatEvent event) throws HeartBeatManagementException {
|
public boolean recordHeartBeat(HeartBeatEvent event) throws HeartBeatManagementException {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void electCandidate(int elapsedTimeInSeconds) throws HeartBeatManagementException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateTaskExecutionAcknowledgement(String newTask)
|
||||||
|
throws HeartBeatManagementException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isQualifiedToExecuteTask() throws HeartBeatManagementException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,9 +19,11 @@
|
|||||||
package io.entgra.server.bootup.heartbeat.beacon.dao;
|
package io.entgra.server.bootup.heartbeat.beacon.dao;
|
||||||
|
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dao.exception.HeartBeatDAOException;
|
import io.entgra.server.bootup.heartbeat.beacon.dao.exception.HeartBeatDAOException;
|
||||||
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ElectedCandidate;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.HeartBeatEvent;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.HeartBeatEvent;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,4 +41,12 @@ public interface HeartBeatDAO {
|
|||||||
|
|
||||||
Map<String, ServerContext> getActiveServerDetails(int elapsedTimeInSeconds) throws HeartBeatDAOException;
|
Map<String, ServerContext> getActiveServerDetails(int elapsedTimeInSeconds) throws HeartBeatDAOException;
|
||||||
|
|
||||||
|
boolean recordElectedCandidate(String serverUUID) throws HeartBeatDAOException;
|
||||||
|
|
||||||
|
void purgeCandidates() throws HeartBeatDAOException;
|
||||||
|
|
||||||
|
ElectedCandidate retrieveCandidate() throws HeartBeatDAOException;
|
||||||
|
|
||||||
|
boolean acknowledgeTask(String uuid, List<String> taskList) throws HeartBeatDAOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,8 +22,11 @@ import io.entgra.server.bootup.heartbeat.beacon.dao.HeartBeatBeaconDAOFactory;
|
|||||||
import io.entgra.server.bootup.heartbeat.beacon.dao.HeartBeatDAO;
|
import io.entgra.server.bootup.heartbeat.beacon.dao.HeartBeatDAO;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dao.exception.HeartBeatDAOException;
|
import io.entgra.server.bootup.heartbeat.beacon.dao.exception.HeartBeatDAOException;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dao.util.HeartBeatBeaconDAOUtil;
|
import io.entgra.server.bootup.heartbeat.beacon.dao.util.HeartBeatBeaconDAOUtil;
|
||||||
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ElectedCandidate;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.HeartBeatEvent;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.HeartBeatEvent;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
@ -32,6 +35,7 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -41,6 +45,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
*/
|
*/
|
||||||
public class GenericHeartBeatDAOImpl implements HeartBeatDAO {
|
public class GenericHeartBeatDAOImpl implements HeartBeatDAO {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(GenericHeartBeatDAOImpl.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String recordServerCtx(ServerContext ctx) throws HeartBeatDAOException {
|
public String recordServerCtx(ServerContext ctx) throws HeartBeatDAOException {
|
||||||
PreparedStatement stmt = null;
|
PreparedStatement stmt = null;
|
||||||
@ -69,6 +75,83 @@ public class GenericHeartBeatDAOImpl implements HeartBeatDAO {
|
|||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean recordElectedCandidate(String serverUUID) throws HeartBeatDAOException {
|
||||||
|
PreparedStatement stmt = null;
|
||||||
|
try {
|
||||||
|
Connection conn = HeartBeatBeaconDAOFactory.getConnection();
|
||||||
|
String sql;
|
||||||
|
sql = "INSERT INTO ELECTED_LEADER_META_INFO(UUID) VALUES (?)";
|
||||||
|
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||||
|
stmt.setString(1, serverUUID);
|
||||||
|
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new HeartBeatDAOException("Error occurred while persisting UUID of chosen " +
|
||||||
|
"elected dynamic task execution candidate : " + serverUUID , e);
|
||||||
|
} finally {
|
||||||
|
HeartBeatBeaconDAOUtil.cleanupResources(stmt, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void purgeCandidates() throws HeartBeatDAOException {
|
||||||
|
Statement stmt = null;
|
||||||
|
try {
|
||||||
|
Connection conn = HeartBeatBeaconDAOFactory.getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
String sql = "TRUNCATE TABLE ELECTED_LEADER_META_INFO";
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
stmt.execute(sql);
|
||||||
|
conn.commit();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new HeartBeatDAOException("Error occurred while truncating ELECTED_LEADER_META_INFO table.", e);
|
||||||
|
} finally {
|
||||||
|
HeartBeatBeaconDAOUtil.cleanupResources(stmt, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElectedCandidate retrieveCandidate() throws HeartBeatDAOException {
|
||||||
|
Statement stmt = null;
|
||||||
|
ResultSet resultSet = null;
|
||||||
|
ElectedCandidate candidate = null;
|
||||||
|
try {
|
||||||
|
Connection conn = HeartBeatBeaconDAOFactory.getConnection();
|
||||||
|
String sql = "SELECT * from ELECTED_LEADER_META_INFO";
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
resultSet = stmt.executeQuery(sql);
|
||||||
|
while (resultSet.next()){
|
||||||
|
candidate = HeartBeatBeaconDAOUtil.populateCandidate(resultSet);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new HeartBeatDAOException("Error occurred while retrieving meta information of elected candidate", e);
|
||||||
|
} finally {
|
||||||
|
HeartBeatBeaconDAOUtil.cleanupResources(stmt, resultSet);
|
||||||
|
}
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acknowledgeTask(String uuid, List<String> taskList) throws HeartBeatDAOException {
|
||||||
|
PreparedStatement stmt = null;
|
||||||
|
try {
|
||||||
|
Connection conn = HeartBeatBeaconDAOFactory.getConnection();
|
||||||
|
String sql;
|
||||||
|
sql = "UPDATE ELECTED_LEADER_META_INFO SET ACKNOWLEDGED_TASK_LIST = ? WHERE UUID = ?";
|
||||||
|
stmt = conn.prepareStatement(sql, new String[]{"UUID"});
|
||||||
|
stmt.setString(1, String.join(",", taskList));
|
||||||
|
stmt.setString(2, uuid);
|
||||||
|
|
||||||
|
return stmt.executeUpdate() > 0;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new HeartBeatDAOException("Error occurred while updating task list of elected server : '" +
|
||||||
|
uuid + "' and task list " + taskList, e);
|
||||||
|
} finally {
|
||||||
|
HeartBeatBeaconDAOUtil.cleanupResources(stmt, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean recordHeatBeat(HeartBeatEvent event) throws HeartBeatDAOException {
|
public boolean recordHeatBeat(HeartBeatEvent event) throws HeartBeatDAOException {
|
||||||
PreparedStatement stmt = null;
|
PreparedStatement stmt = null;
|
||||||
@ -152,8 +235,7 @@ public class GenericHeartBeatDAOImpl implements HeartBeatDAO {
|
|||||||
"WHERE LAST_UPDATED_TIMESTAMP > ? " +
|
"WHERE LAST_UPDATED_TIMESTAMP > ? " +
|
||||||
"ORDER BY UUID";
|
"ORDER BY UUID";
|
||||||
stmt = conn.prepareStatement(sql);
|
stmt = conn.prepareStatement(sql);
|
||||||
stmt.setInt(1, elapsedTimeInSeconds);
|
stmt.setTimestamp(1, new Timestamp(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(elapsedTimeInSeconds)));
|
||||||
stmt.setTimestamp(2, new Timestamp(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(elapsedTimeInSeconds)));
|
|
||||||
resultSet = stmt.executeQuery();
|
resultSet = stmt.executeQuery();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
ctxList.put(resultSet.getString("UUID"), HeartBeatBeaconDAOUtil.populateContext(resultSet));
|
ctxList.put(resultSet.getString("UUID"), HeartBeatBeaconDAOUtil.populateContext(resultSet));
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package io.entgra.server.bootup.heartbeat.beacon.dao.util;
|
package io.entgra.server.bootup.heartbeat.beacon.dao.util;
|
||||||
|
|
||||||
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ElectedCandidate;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
@ -27,6 +28,8 @@ import javax.sql.DataSource;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +62,29 @@ public final class HeartBeatBeaconDAOUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup resources used to transaction
|
||||||
|
*
|
||||||
|
* @param stmt Statement used
|
||||||
|
* @param rs Obtained results set
|
||||||
|
*/
|
||||||
|
public static void cleanupResources(Statement stmt, ResultSet rs) {
|
||||||
|
if (rs != null) {
|
||||||
|
try {
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.warn("Error occurred while closing result set", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stmt != null) {
|
||||||
|
try {
|
||||||
|
stmt.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.warn("Error occurred while closing prepared statement", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup datasource using name and jndi properties
|
* Lookup datasource using name and jndi properties
|
||||||
*
|
*
|
||||||
@ -88,4 +114,15 @@ public final class HeartBeatBeaconDAOUtil {
|
|||||||
ctx.setCarbonServerPort(resultSet.getInt("SERVER_PORT"));
|
ctx.setCarbonServerPort(resultSet.getInt("SERVER_PORT"));
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ElectedCandidate populateCandidate(ResultSet resultSet) throws SQLException {
|
||||||
|
ElectedCandidate candidate = new ElectedCandidate();
|
||||||
|
candidate.setServerUUID(resultSet.getString("UUID"));
|
||||||
|
candidate.setTimeOfElection(resultSet.getTimestamp("ELECTED_TIME"));
|
||||||
|
String tasksList = resultSet.getString("ACKNOWLEDGED_TASK_LIST");
|
||||||
|
if(tasksList != null && !tasksList.isEmpty()){
|
||||||
|
candidate.setAcknowledgedTaskList(Arrays.asList(tasksList.split(",")));
|
||||||
|
}
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Entgra Pvt Ltd. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Entgra Pvt Ltd. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.entgra.server.bootup.heartbeat.beacon.dto;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ElectedCandidate {
|
||||||
|
|
||||||
|
private String serverUUID;
|
||||||
|
private Timestamp timeOfElection;
|
||||||
|
private List<String> acknowledgedTaskList = null;
|
||||||
|
|
||||||
|
public List<String> getAcknowledgedTaskList() {
|
||||||
|
return acknowledgedTaskList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAcknowledgedTaskList(List<String> acknowledgedTaskList) {
|
||||||
|
this.acknowledgedTaskList = acknowledgedTaskList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerUUID() {
|
||||||
|
return serverUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerUUID(String serverUUID) {
|
||||||
|
this.serverUUID = serverUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timestamp getTimeOfElection() {
|
||||||
|
return timeOfElection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeOfElection(Timestamp timeOfElection) {
|
||||||
|
this.timeOfElection = timeOfElection;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -47,7 +47,7 @@ public class HeartBeatBeaconComponent {
|
|||||||
protected void activate(ComponentContext componentContext) {
|
protected void activate(ComponentContext componentContext) {
|
||||||
try {
|
try {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Initializing email sender core bundle");
|
log.debug("Initializing heart beat management bundle");
|
||||||
}
|
}
|
||||||
this.registerHeartBeatServices(componentContext);
|
this.registerHeartBeatServices(componentContext);
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ public class HeartBeatBeaconComponent {
|
|||||||
/* This is to avoid mobile device management component getting initialized before the underlying datasources
|
/* This is to avoid mobile device management component getting initialized before the underlying datasources
|
||||||
are registered */
|
are registered */
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Data source service set to mobile service component");
|
log.debug("Data source service set to heart beat management component");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,13 +57,17 @@ public class HeartBeatExecutor {
|
|||||||
uuid = HeartBeatBeaconDataHolder.getInstance().getHeartBeatManagementService().updateServerContext(ctx);
|
uuid = HeartBeatBeaconDataHolder.getInstance().getHeartBeatManagementService().updateServerContext(ctx);
|
||||||
HeartBeatBeaconUtils.saveUUID(uuid);
|
HeartBeatBeaconUtils.saveUUID(uuid);
|
||||||
}
|
}
|
||||||
|
int timeOutIntervalInSeconds = CONFIG.getServerTimeOutIntervalInSeconds();
|
||||||
|
int timeSkew = CONFIG.getTimeSkew();
|
||||||
|
int cumilativeTimeOut = timeOutIntervalInSeconds + timeSkew;
|
||||||
final String designatedUUID = uuid;
|
final String designatedUUID = uuid;
|
||||||
HeartBeatBeaconDataHolder.getInstance().setLocalServerUUID(designatedUUID);
|
HeartBeatBeaconDataHolder.getInstance().setLocalServerUUID(designatedUUID);
|
||||||
Runnable periodicTask = new Runnable() {
|
Runnable periodicTask = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
recordHeartBeat(designatedUUID);
|
recordHeartBeat(designatedUUID);
|
||||||
} catch (HeartBeatManagementException e) {
|
electDynamicTaskExecutionCandidate(cumilativeTimeOut);
|
||||||
|
} catch (Exception e) {
|
||||||
log.error("Error while executing record heart beat task. This will result in schedule operation malfunction.", e);
|
log.error("Error while executing record heart beat task. This will result in schedule operation malfunction.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,4 +87,9 @@ public class HeartBeatExecutor {
|
|||||||
HeartBeatBeaconDataHolder.getInstance().getHeartBeatManagementService().recordHeartBeat(new HeartBeatEvent(uuid));
|
HeartBeatBeaconDataHolder.getInstance().getHeartBeatManagementService().recordHeartBeat(new HeartBeatEvent(uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void electDynamicTaskExecutionCandidate(int cumilativeTimeOut) throws HeartBeatManagementException {
|
||||||
|
HeartBeatBeaconDataHolder.getInstance().getHeartBeatManagementService().electCandidate(cumilativeTimeOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package io.entgra.server.bootup.heartbeat.beacon.service;
|
package io.entgra.server.bootup.heartbeat.beacon.service;
|
||||||
|
|
||||||
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ElectedCandidate;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.HeartBeatEvent;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.HeartBeatEvent;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.exception.HeartBeatManagementException;
|
import io.entgra.server.bootup.heartbeat.beacon.exception.HeartBeatManagementException;
|
||||||
@ -25,10 +26,18 @@ import org.wso2.carbon.device.mgt.common.ServerCtxInfo;
|
|||||||
|
|
||||||
public interface HeartBeatManagementService {
|
public interface HeartBeatManagementService {
|
||||||
|
|
||||||
|
boolean isTaskPartitioningEnabled() throws HeartBeatManagementException;
|
||||||
|
|
||||||
ServerCtxInfo getServerCtxInfo() throws HeartBeatManagementException;
|
ServerCtxInfo getServerCtxInfo() throws HeartBeatManagementException;
|
||||||
|
|
||||||
String updateServerContext(ServerContext ctx) throws HeartBeatManagementException;
|
String updateServerContext(ServerContext ctx) throws HeartBeatManagementException;
|
||||||
|
|
||||||
boolean recordHeartBeat(HeartBeatEvent event) throws HeartBeatManagementException;
|
boolean recordHeartBeat(HeartBeatEvent event) throws HeartBeatManagementException;
|
||||||
|
|
||||||
|
void electCandidate(int elapsedTimeInSeconds) throws HeartBeatManagementException;
|
||||||
|
|
||||||
|
boolean updateTaskExecutionAcknowledgement(String newTask) throws HeartBeatManagementException;
|
||||||
|
|
||||||
|
boolean isQualifiedToExecuteTask() throws HeartBeatManagementException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,18 +22,29 @@ import io.entgra.server.bootup.heartbeat.beacon.config.HeartBeatBeaconConfig;
|
|||||||
import io.entgra.server.bootup.heartbeat.beacon.dao.HeartBeatBeaconDAOFactory;
|
import io.entgra.server.bootup.heartbeat.beacon.dao.HeartBeatBeaconDAOFactory;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dao.HeartBeatDAO;
|
import io.entgra.server.bootup.heartbeat.beacon.dao.HeartBeatDAO;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dao.exception.HeartBeatDAOException;
|
import io.entgra.server.bootup.heartbeat.beacon.dao.exception.HeartBeatDAOException;
|
||||||
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ElectedCandidate;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.HeartBeatEvent;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.HeartBeatEvent;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
import io.entgra.server.bootup.heartbeat.beacon.dto.ServerContext;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.exception.HeartBeatManagementException;
|
import io.entgra.server.bootup.heartbeat.beacon.exception.HeartBeatManagementException;
|
||||||
import io.entgra.server.bootup.heartbeat.beacon.internal.HeartBeatBeaconDataHolder;
|
import io.entgra.server.bootup.heartbeat.beacon.internal.HeartBeatBeaconDataHolder;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.wso2.carbon.device.mgt.common.ServerCtxInfo;
|
import org.wso2.carbon.device.mgt.common.ServerCtxInfo;
|
||||||
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
|
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class HeartBeatManagementServiceImpl implements HeartBeatManagementService {
|
public class HeartBeatManagementServiceImpl implements HeartBeatManagementService {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(HeartBeatManagementServiceImpl.class);
|
||||||
|
|
||||||
private final HeartBeatDAO heartBeatDAO;
|
private final HeartBeatDAO heartBeatDAO;
|
||||||
|
|
||||||
public HeartBeatManagementServiceImpl(){
|
public HeartBeatManagementServiceImpl(){
|
||||||
@ -77,6 +88,19 @@ public class HeartBeatManagementServiceImpl implements HeartBeatManagementServic
|
|||||||
return serverCtxInfo;
|
return serverCtxInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTaskPartitioningEnabled() throws HeartBeatManagementException {
|
||||||
|
boolean enabled = false;
|
||||||
|
if(HeartBeatBeaconConfig.getInstance() != null){
|
||||||
|
enabled = HeartBeatBeaconConfig.getInstance().isEnabled();
|
||||||
|
} else {
|
||||||
|
String msg = "Issue instantiating heart beat config.";
|
||||||
|
throw new HeartBeatManagementException(msg);
|
||||||
|
}
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String updateServerContext(ServerContext ctx) throws HeartBeatManagementException {
|
public String updateServerContext(ServerContext ctx) throws HeartBeatManagementException {
|
||||||
String uuid = null;
|
String uuid = null;
|
||||||
@ -105,6 +129,124 @@ public class HeartBeatManagementServiceImpl implements HeartBeatManagementServic
|
|||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isQualifiedToExecuteTask() throws HeartBeatManagementException {
|
||||||
|
boolean isQualified = false;
|
||||||
|
if(HeartBeatBeaconConfig.getInstance().isEnabled()) {
|
||||||
|
try {
|
||||||
|
String localServerUUID = HeartBeatBeaconDataHolder.getInstance().getLocalServerUUID();
|
||||||
|
HeartBeatBeaconDAOFactory.openConnection();
|
||||||
|
ElectedCandidate candidate = heartBeatDAO.retrieveCandidate();
|
||||||
|
if(candidate != null && candidate.getServerUUID().equalsIgnoreCase(localServerUUID)){
|
||||||
|
isQualified = true;
|
||||||
|
if(log.isDebugEnabled()){
|
||||||
|
log.debug("Node : " + localServerUUID + " Qualified to execute randomly assigned task.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (HeartBeatDAOException e) {
|
||||||
|
String msg = "Error occurred while checking if server is qualified to execute randomly designated task.";
|
||||||
|
throw new HeartBeatManagementException(msg, e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
String msg = "Error occurred while opening a connection to the underlying data source";
|
||||||
|
throw new HeartBeatManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
HeartBeatBeaconDAOFactory.closeConnection();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String msg = "Heart Beat Configuration Disabled. Error occurred while checking if server is qualified to execute randomly designated task.";
|
||||||
|
throw new HeartBeatManagementException(msg);
|
||||||
|
}
|
||||||
|
return isQualified;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateTaskExecutionAcknowledgement(String newTask) throws HeartBeatManagementException {
|
||||||
|
boolean result = false;
|
||||||
|
if(HeartBeatBeaconConfig.getInstance().isEnabled()) {
|
||||||
|
try {
|
||||||
|
String serverUUID = HeartBeatBeaconDataHolder.getInstance().getLocalServerUUID();
|
||||||
|
HeartBeatBeaconDAOFactory.beginTransaction();
|
||||||
|
ElectedCandidate candidate = heartBeatDAO.retrieveCandidate();
|
||||||
|
if(candidate != null && candidate.getServerUUID().equals(serverUUID)){
|
||||||
|
List<String> taskList = candidate.getAcknowledgedTaskList();
|
||||||
|
boolean taskExecuted = false;
|
||||||
|
for(String task : taskList){
|
||||||
|
if(task.equalsIgnoreCase(newTask)){
|
||||||
|
taskExecuted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!taskExecuted) {
|
||||||
|
taskList.add(newTask);
|
||||||
|
result = heartBeatDAO.acknowledgeTask(serverUUID, taskList);
|
||||||
|
HeartBeatBeaconDAOFactory.commitTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (HeartBeatDAOException e) {
|
||||||
|
String msg = "Error occurred while updating acknowledged task.";
|
||||||
|
throw new HeartBeatManagementException(msg, e);
|
||||||
|
} catch (TransactionManagementException e) {
|
||||||
|
HeartBeatBeaconDAOFactory.rollbackTransaction();
|
||||||
|
String msg = "Error occurred while updating acknowledged task.. Issue in opening a connection to the underlying data source";
|
||||||
|
throw new HeartBeatManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
HeartBeatBeaconDAOFactory.closeConnection();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String msg = "Heart Beat Configuration Disabled. Updating acknowledged task list failed.";
|
||||||
|
throw new HeartBeatManagementException(msg);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void electCandidate(int elapsedTimeInSeconds) throws HeartBeatManagementException {
|
||||||
|
if (HeartBeatBeaconConfig.getInstance().isEnabled()) {
|
||||||
|
try {
|
||||||
|
HeartBeatBeaconDAOFactory.beginTransaction();
|
||||||
|
Map<String, ServerContext> servers = heartBeatDAO.getActiveServerDetails(elapsedTimeInSeconds);
|
||||||
|
if (servers != null && !servers.isEmpty()) {
|
||||||
|
ElectedCandidate presentCandidate = heartBeatDAO.retrieveCandidate();
|
||||||
|
if (presentCandidate != null &&
|
||||||
|
presentCandidate.getTimeOfElection().before(new Timestamp(System.currentTimeMillis()
|
||||||
|
- TimeUnit.SECONDS.toMillis(elapsedTimeInSeconds)))) {
|
||||||
|
heartBeatDAO.purgeCandidates();
|
||||||
|
electCandidate(servers);
|
||||||
|
} else {
|
||||||
|
electCandidate(servers);
|
||||||
|
}
|
||||||
|
HeartBeatBeaconDAOFactory.commitTransaction();
|
||||||
|
}
|
||||||
|
} catch (HeartBeatDAOException e) {
|
||||||
|
String msg = "Error occurred while electing candidate for dynamic task execution.";
|
||||||
|
throw new HeartBeatManagementException(msg, e);
|
||||||
|
} catch (TransactionManagementException e) {
|
||||||
|
HeartBeatBeaconDAOFactory.rollbackTransaction();
|
||||||
|
String msg = "Error occurred while electing candidate for dynamic task execution. Issue in opening a connection to the underlying data source";
|
||||||
|
throw new HeartBeatManagementException(msg, e);
|
||||||
|
} finally {
|
||||||
|
HeartBeatBeaconDAOFactory.closeConnection();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String msg = "Heart Beat Configuration Disabled. Error electing candidate for dynamic task execution.";
|
||||||
|
throw new HeartBeatManagementException(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void electCandidate(Map<String, ServerContext> servers) throws HeartBeatDAOException {
|
||||||
|
String electedCandidate = getRandomElement(servers.keySet());
|
||||||
|
heartBeatDAO.recordElectedCandidate(electedCandidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String getRandomElement(Set<String> valueSet)
|
||||||
|
{
|
||||||
|
Random rand = new Random();
|
||||||
|
List<String> items = new ArrayList<>(valueSet);
|
||||||
|
return items.get(rand.nextInt(items.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean recordHeartBeat(HeartBeatEvent event) throws HeartBeatManagementException {
|
public boolean recordHeartBeat(HeartBeatEvent event) throws HeartBeatManagementException {
|
||||||
|
|||||||
@ -49,8 +49,7 @@ public class DelegationTask extends DynamicPartitionedScheduleTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void executeDynamicTask() {
|
||||||
super.refreshContext();
|
|
||||||
try {
|
try {
|
||||||
PolicyManager policyManager = new PolicyManagerImpl();
|
PolicyManager policyManager = new PolicyManagerImpl();
|
||||||
UpdatedPolicyDeviceListBean updatedPolicyDeviceList = policyManager.applyChangesMadeToPolicies();
|
UpdatedPolicyDeviceListBean updatedPolicyDeviceList = policyManager.applyChangesMadeToPolicies();
|
||||||
@ -70,7 +69,7 @@ public class DelegationTask extends DynamicPartitionedScheduleTask {
|
|||||||
try {
|
try {
|
||||||
devices = new ArrayList<>();
|
devices = new ArrayList<>();
|
||||||
toBeNotified = new ArrayList<>();
|
toBeNotified = new ArrayList<>();
|
||||||
if(super.getTaskContext() != null && super.getTaskContext().isPartitioningEnabled()) {
|
if(super.isDynamicTaskEligible()) {
|
||||||
devices.addAll(service.getAllocatedDevices(deviceType,
|
devices.addAll(service.getAllocatedDevices(deviceType,
|
||||||
super.getTaskContext().getActiveServerCount(),
|
super.getTaskContext().getActiveServerCount(),
|
||||||
super.getTaskContext().getServerHashIndex()));
|
super.getTaskContext().getServerHashIndex()));
|
||||||
|
|||||||
@ -45,12 +45,10 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void executeDynamicTask() {
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Monitoring task started to run.");
|
log.debug("Monitoring task started to run.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.executeforAllTenants();
|
this.executeforAllTenants();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +94,6 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void executeTask() {
|
private void executeTask() {
|
||||||
super.refreshContext();
|
|
||||||
MonitoringManager monitoringManager = PolicyManagementDataHolder.getInstance().getMonitoringManager();
|
MonitoringManager monitoringManager = PolicyManagementDataHolder.getInstance().getMonitoringManager();
|
||||||
List<String> deviceTypes = new ArrayList<>();
|
List<String> deviceTypes = new ArrayList<>();
|
||||||
List<String> configDeviceTypes = new ArrayList<>();
|
List<String> configDeviceTypes = new ArrayList<>();
|
||||||
@ -122,7 +119,7 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask {
|
|||||||
PolicyManagementDataHolder.getInstance().getDeviceManagementService()
|
PolicyManagementDataHolder.getInstance().getDeviceManagementService()
|
||||||
.getPolicyMonitoringManager(deviceType);
|
.getPolicyMonitoringManager(deviceType);
|
||||||
List<Device> devices;
|
List<Device> devices;
|
||||||
if(super.getTaskContext()!= null && super.getTaskContext().isPartitioningEnabled()){
|
if(super.isDynamicTaskEligible()){
|
||||||
devices = deviceManagementProviderService.getAllocatedDevices(deviceType,
|
devices = deviceManagementProviderService.getAllocatedDevices(deviceType,
|
||||||
super.getTaskContext().getActiveServerCount(),
|
super.getTaskContext().getActiveServerCount(),
|
||||||
super.getTaskContext().getServerHashIndex());
|
super.getTaskContext().getServerHashIndex());
|
||||||
|
|||||||
@ -7,6 +7,11 @@ import io.entgra.server.bootup.heartbeat.beacon.service.HeartBeatManagementServi
|
|||||||
import org.wso2.carbon.device.mgt.common.ServerCtxInfo;
|
import org.wso2.carbon.device.mgt.common.ServerCtxInfo;
|
||||||
|
|
||||||
public class TestHeartBeatManagementService implements HeartBeatManagementService {
|
public class TestHeartBeatManagementService implements HeartBeatManagementService {
|
||||||
|
@Override
|
||||||
|
public boolean isTaskPartitioningEnabled() throws HeartBeatManagementException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServerCtxInfo getServerCtxInfo() throws HeartBeatManagementException {
|
public ServerCtxInfo getServerCtxInfo() throws HeartBeatManagementException {
|
||||||
return null;
|
return null;
|
||||||
@ -21,4 +26,20 @@ public class TestHeartBeatManagementService implements HeartBeatManagementServic
|
|||||||
public boolean recordHeartBeat(HeartBeatEvent event) throws HeartBeatManagementException {
|
public boolean recordHeartBeat(HeartBeatEvent event) throws HeartBeatManagementException {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void electCandidate(int elapsedTimeInSeconds) throws HeartBeatManagementException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateTaskExecutionAcknowledgement(String newTask)
|
||||||
|
throws HeartBeatManagementException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isQualifiedToExecuteTask() throws HeartBeatManagementException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<HeartBeatBeaconConfig>
|
<HeartBeatBeaconConfig>
|
||||||
<Enable>true</Enable>
|
<Enable>false</Enable>
|
||||||
<DataSourceConfiguration>
|
<DataSourceConfiguration>
|
||||||
<JndiLookupDefinition>
|
<JndiLookupDefinition>
|
||||||
<Name>jdbc/HeartBeat_DS</Name>
|
<Name>jdbc/HeartBeat_DS</Name>
|
||||||
|
|||||||
@ -9,3 +9,10 @@ CREATE TABLE IF NOT EXISTS SERVER_HEART_BEAT_EVENTS (
|
|||||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (ID)
|
PRIMARY KEY (ID)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ELECTED_LEADER_META_INFO (
|
||||||
|
UUID VARCHAR(100) NOT NULL,
|
||||||
|
ELECTED_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ACKNOWLEDGED_TASK_LIST TEXT DEFAULT NULL,
|
||||||
|
PRIMARY KEY (UUID)
|
||||||
|
);
|
||||||
|
|||||||
@ -11,4 +11,9 @@ CREATE TABLE SERVER_HEART_BEAT_EVENTS (
|
|||||||
LAST_UPDATED_TIMESTAMP DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
LAST_UPDATED_TIMESTAMP DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (ID));
|
PRIMARY KEY (ID));
|
||||||
|
|
||||||
|
IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[ELECTED_LEADER_META_INFO]') AND TYPE IN (N'U'))
|
||||||
|
CREATE TABLE ELECTED_LEADER_META_INFO (
|
||||||
|
UUID VARCHAR(100) NOT NULL,
|
||||||
|
ELECTED_TIME DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ACKNOWLEDGED_TASK_LIST VARCHAR(MAX) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (UUID));
|
||||||
|
|||||||
@ -9,3 +9,10 @@ CREATE TABLE IF NOT EXISTS SERVER_HEART_BEAT_EVENTS (
|
|||||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (ID)
|
PRIMARY KEY (ID)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ELECTED_LEADER_META_INFO (
|
||||||
|
UUID VARCHAR(100) NOT NULL,
|
||||||
|
ELECTED_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ACKNOWLEDGED_TASK_LIST TEXT DEFAULT NULL,
|
||||||
|
PRIMARY KEY (UUID)
|
||||||
|
);
|
||||||
|
|||||||
@ -11,3 +11,11 @@ CREATE TABLE SERVER_HEART_BEAT_EVENTS (
|
|||||||
CONSTRAINT PK_SERVER_HEART_BEAT_EVENTS PRIMARY KEY (ID)
|
CONSTRAINT PK_SERVER_HEART_BEAT_EVENTS PRIMARY KEY (ID)
|
||||||
)
|
)
|
||||||
/
|
/
|
||||||
|
|
||||||
|
CREATE TABLE ELECTED_LEADER_META_INFO (
|
||||||
|
UUID VARCHAR(100) NOT NULL,
|
||||||
|
ELECTED_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ACKNOWLEDGED_TASK_LIST BLOB DEFAULT NULL,
|
||||||
|
CONSTRAINT PK_SERVER_HEART_BEAT_EVENTS PRIMARY KEY (UUID)
|
||||||
|
)
|
||||||
|
/
|
||||||
|
|||||||
@ -9,3 +9,10 @@
|
|||||||
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
LAST_UPDATED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (ID)
|
PRIMARY KEY (ID)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ELECTED_LEADER_META_INFO (
|
||||||
|
UUID VARCHAR(100) NOT NULL,
|
||||||
|
ELECTED_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
ACKNOWLEDGED_TASK_LIST TEXT DEFAULT NULL,
|
||||||
|
PRIMARY KEY (UUID)
|
||||||
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user