com.persistent.cloudninja.scheduler.Scheduler.java Source code

Java tutorial

Introduction

Here is the source code for com.persistent.cloudninja.scheduler.Scheduler.java

Source

/*******************************************************************************
 * Copyright 2012 Persistent Systems Ltd.
 * 
 * Licensed 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 com.persistent.cloudninja.scheduler;

import java.net.URISyntaxException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;

import com.microsoft.windowsazure.services.core.storage.StorageException;
import com.microsoft.windowsazure.services.queue.client.CloudQueueMessage;
import com.persistent.cloudninja.dao.TaskScheduleDao;
import com.persistent.cloudninja.domainobject.TaskScheduleEntity;
import com.persistent.cloudninja.utils.SchedulerSettings;

/**
 * This class schedules the task depending on the schedule time.
 *
 */
public class Scheduler {

    private static final Logger LOGGER = Logger.getLogger(Scheduler.class);

    private StorageUtility storageUtility;

    private TaskScheduleDao taskScheduleDao;

    private List<String> taskList;

    @Autowired
    private TenantDeletionTask tenantDeletionTask;

    @Autowired
    private TenantCreationTask tenantCreationTask;

    @Autowired
    private PerformanceMonitor performanceMonitor;

    @Autowired
    private DeploymentMonitor deploymentMonitor;

    @Autowired
    private AzureStorageCleanupTask azureStorageCleanupTask;

    private static final String TASK_SCHEDULER_PREFIX = "taskscheduler-";

    /**
     * Constructor which initializes the tasks.
     * 
     * @param storageUtility
     * @param taskScheduleDao
     */
    public Scheduler(StorageUtility storageUtility, TaskScheduleDao taskScheduleDao) {
        this.storageUtility = storageUtility;
        this.taskScheduleDao = taskScheduleDao;
        initializeTaskScheduleContainer();
        storageUtility.enableLoggingForBlobs();
        taskList = new ArrayList<String>();
        registerTask(SchedulerSettings.DatabaseSizeTask, 20);
        registerTask(SchedulerSettings.BlobStorageSizeTask, 20);
        registerTask(SchedulerSettings.DBBandwidthTask, 20);
        registerTask(SchedulerSettings.WebBandWidthUsageTask, 20);
        registerTask(SchedulerSettings.MonitorPerformanceTask, 10);
        registerTask(SchedulerSettings.MonitorDeploymentTask, 60);
        registerTask(SchedulerSettings.AzureStorageCleanupTask, 60);
        registerTask(SchedulerSettings.StorageBandwidthTask, 10);
    }

    /**
     * Creates blob container 'taskscheduler' if not exists.
     * 
     */
    private void initializeTaskScheduleContainer() {
        try {
            // container for page blobs required while acquiring lease.
            storageUtility.initializeBlobContainer("taskscheduler");
            // container to store poison messages
            storageUtility.initializeBlobContainer("poison-messages");
        } catch (URISyntaxException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (StorageException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * Register a task in TaskSchedule table.
     * 
     * @param taskId : ID of task.
     * @param frequencyInMin : frequency in minutes.
     */
    private void registerTask(String taskId, long frequencyInMin) {
        try {
            TaskScheduleEntity taskScheduleEntity = new TaskScheduleEntity();
            taskScheduleEntity.setTaskId(taskId);
            taskScheduleEntity.setFrequency(frequencyInMin);

            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.SECOND, (int) frequencyInMin * 60);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S z");
            dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
            String nextScheduledStartTime = dateFormat.format(calendar.getTime());

            taskScheduleEntity.setNextScheduledStartTime(dateFormat.parse(nextScheduledStartTime));
            taskScheduleDao.updateTaskSchedule(taskScheduleEntity);
            taskList.add(taskId);

            storageUtility.initializeQueue(TASK_SCHEDULER_PREFIX + taskId.toLowerCase());
        } catch (ParseException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (URISyntaxException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (StorageException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * This method will query the TaskSchedule table to find out the
     * eligible tasks for scheduling.
     * 
     */
    @Scheduled(fixedDelay = SchedulerSettings.SchedulerInterval)
    public void doSchedule() {
        LOGGER.debug("Start schedule");
        String taskId = "";

        List<TaskScheduleEntity> listTaskSchedule = taskScheduleDao.getTaskScheduledList();

        for (TaskScheduleEntity taskScheduleEntity : listTaskSchedule) {
            try {
                Date nextScheduledTime = taskScheduleEntity.getNextScheduledStartTime();
                Calendar calendar = Calendar.getInstance();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S z");
                dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
                String nextScheduledStartTime = dateFormat.format(calendar.getTime());
                Date currentTime = dateFormat.parse(nextScheduledStartTime);
                if (taskList.contains(taskScheduleEntity.getTaskId())
                        && nextScheduledTime.getTime() < currentTime.getTime()) {
                    taskId = taskScheduleEntity.getTaskId();
                    String leaseId = "";
                    leaseId = acquireLock(taskId);
                    LOGGER.debug("doSchedule : lease " + leaseId);
                    if (!leaseId.isEmpty()) {
                        try {
                            storageUtility.putMessage(TASK_SCHEDULER_PREFIX + taskId.toLowerCase(), taskId);
                            LOGGER.debug("doSchedule : put message in Q taskscheduler-" + taskId.toLowerCase());

                            calendar = Calendar.getInstance();
                            calendar.add(Calendar.SECOND, (int) taskScheduleEntity.getFrequency() * 60);
                            dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S z");
                            dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
                            nextScheduledStartTime = dateFormat.format(calendar.getTime());

                            taskScheduleEntity.setNextScheduledStartTime(dateFormat.parse(nextScheduledStartTime));
                            taskScheduleDao.updateTaskSchedule(taskScheduleEntity);

                            storageUtility.releaseLease(taskId, leaseId);
                            LOGGER.debug("doSchedule : lease released");
                        } catch (Exception e) {
                            LOGGER.error(e.getMessage(), e);
                        }
                    }
                }
            } catch (ParseException e) {
                LOGGER.error(e.getMessage(), e);
            }

        }
        LOGGER.debug("End schedule");
    }

    /**
     * Acquire lease on page blob if acquired then return leaseId 
     * else empty string.
     * 
     * @param id : task ID.
     * @return : leaseId if lease is acquired else empty.
     */
    private String acquireLock(String id) {
        String leaseId = "";

        try {
            leaseId = storageUtility.acquireLease(id.toLowerCase());
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
        return leaseId;
    }

    /**
     * Remove Tenant task.
     */
    @Scheduled(fixedDelay = SchedulerSettings.ProcessorInterval)
    public void removeTenant() {
        if (tenantDeletionTask.execute()) {
            try {
                ActivityWorkQueue activityWorkQueue = tenantDeletionTask.getWorkQueue();
                activityWorkQueue.complete();
            } catch (StorageException e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
    }

    /**
     * Register Tenant task.
     */
    @Scheduled(fixedDelay = SchedulerSettings.ProcessorInterval)
    public void registerTenant() {
        if (tenantCreationTask.execute()) {
            try {
                ActivityWorkQueue activityWorkQueue = tenantCreationTask.getWorkQueue();
                activityWorkQueue.complete();
            } catch (StorageException e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
    }

    /**
     * Monitor performance task.
     */
    @Scheduled(fixedDelay = SchedulerSettings.ProcessorInterval)
    public void monitorPerformance() {
        LOGGER.debug("SCH-monitorPerformance : enter");
        CloudQueueMessage message = null;
        try {
            message = storageUtility
                    .getMessage(TASK_SCHEDULER_PREFIX + SchedulerSettings.MonitorPerformanceTask.toLowerCase());
            if (message != null) {
                LOGGER.debug("SCH-monitorPerformance : msg is not null");
                if (performanceMonitor.execute()) {
                    storageUtility.deleteMessage(
                            TASK_SCHEDULER_PREFIX + SchedulerSettings.MonitorPerformanceTask.toLowerCase(),
                            message);
                    LOGGER.debug("SCH-monitorPerformance : msg deleted");
                }
            }
            LOGGER.debug("SCH-monitorPerformance : exit");
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * Monitor deployment task.
     */
    @Scheduled(fixedDelay = SchedulerSettings.ProcessorInterval)
    public void monitorDeployment() {
        LOGGER.debug("SCH-monitorDeployment : enter");
        CloudQueueMessage message = null;
        try {
            message = storageUtility
                    .getMessage(TASK_SCHEDULER_PREFIX + SchedulerSettings.MonitorDeploymentTask.toLowerCase());
            if (message != null) {
                LOGGER.debug("SCH-monitorDeployment : msg is not null");
                if (deploymentMonitor.execute()) {
                    storageUtility.deleteMessage(
                            TASK_SCHEDULER_PREFIX + SchedulerSettings.MonitorDeploymentTask.toLowerCase(), message);
                    LOGGER.debug("SCH-monitorDeployment : msg deleted");
                }
            }
            LOGGER.debug("SCH-monitorDeployment : exit");
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * Azure Cleanup task.
     */
    @Scheduled(fixedDelay = SchedulerSettings.ProcessorInterval)
    public void azureStorageCleanup() {
        LOGGER.debug("SCH-azureStorageCleanup : enter");
        CloudQueueMessage message = null;
        try {
            message = storageUtility
                    .getMessage(TASK_SCHEDULER_PREFIX + SchedulerSettings.AzureStorageCleanupTask.toLowerCase());
            if (message != null) {
                LOGGER.debug("SCH-azureStorageCleanup : msg is not null");
                if (azureStorageCleanupTask.execute()) {
                    storageUtility.deleteMessage(
                            TASK_SCHEDULER_PREFIX + SchedulerSettings.AzureStorageCleanupTask.toLowerCase(),
                            message);
                    LOGGER.debug("SCH-azureStorageCleanup : msg deleted");
                }
            }
            LOGGER.debug("SCH-azureStorageCleanup : exit");
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

}