com.evolveum.midpoint.task.quartzimpl
Class TaskManagerQuartzImpl

java.lang.Object
  extended by com.evolveum.midpoint.task.quartzimpl.TaskManagerQuartzImpl
All Implemented Interfaces:
TaskManager, org.springframework.beans.factory.Aware, org.springframework.beans.factory.BeanFactoryAware

@Service(value="taskManager")
@DependsOn(value="repositoryService")
public class TaskManagerQuartzImpl
extends java.lang.Object
implements TaskManager, org.springframework.beans.factory.BeanFactoryAware

Task Manager implementation using Quartz scheduler. Main classes: - TaskManagerQuartzImpl - TaskQuartzImpl Helper classes: - ExecutionManager: node-related functions (start, stop, query status), task-related functions (stop, query status) - LocalNodeManager and RemoteExecutionManager (specific methods for local node and remote nodes) - TaskManagerConfiguration: access to config gathered from various places (midpoint config, sql repo config, system properties) - ClusterManager: keeps cluster nodes synchronized and verifies cluster configuration sanity - JmxClient: used to invoke remote JMX agents - JmxServer: provides a JMX agent for midPoint - TaskSynchronizer: synchronizes information about tasks between midPoint repo and Quartz Job Store - Initializer: contains TaskManager initialization code (quite complex)

Author:
Pavol Mederly

Constructor Summary
TaskManagerQuartzImpl()
           
 
Method Summary
 java.lang.String addTask(PrismObject<TaskType> taskPrism, OperationResult parentResult)
          Add new task.
 void closeTask(Task task, OperationResult parentResult)
           
 void closeTaskWithoutSavingState(Task task, OperationResult parentResult)
           
 int countNodes(ObjectQuery query, OperationResult result)
           
 int countTasks(ObjectQuery query, OperationResult result)
           
 Task createTaskInstance()
          Creates new transient, running, claimed task instance.
 Task createTaskInstance(PrismObject<TaskType> taskPrism, OperationResult parentResult)
          Creates task instance from the XML task representation.
 Task createTaskInstance(PrismObject<TaskType> taskPrism, java.lang.String operationName, OperationResult parentResult)
          Creates task instance from the XML task representation.
 Task createTaskInstance(java.lang.String operationName)
          Creates new transient, running, claimed task instance.
 boolean deactivateServiceThreads(long timeToWait, OperationResult parentResult)
          Deactivate service threads (temporarily).
 void deleteNode(java.lang.String nodeIdentifier, OperationResult result)
           
 void deleteTask(java.lang.String oid, OperationResult parentResult)
          Deletes task with provided OID.
 java.util.List<java.lang.String> getAllTaskCategories()
           
 org.springframework.beans.factory.BeanFactory getBeanFactory()
           
 ClusterManager getClusterManager()
           
 TaskManagerConfiguration getConfiguration()
           
 ExecutionManager getExecutionManager()
           
 TaskHandler getHandler(java.lang.String uri)
           
 java.lang.String getHandlerUriForCategory(java.lang.String category)
           
 NodeErrorStatus getLocalNodeErrorStatus()
           
 MidpointConfiguration getMidpointConfiguration()
           
 java.lang.Long getNextRunStartTime(java.lang.String oid, OperationResult parentResult)
           
 java.lang.String getNodeId()
           
 PrismContext getPrismContext()
           
 RepositoryService getRepositoryService()
           
 java.util.Set<Task> getRunningTasks()
          Deprecated. 
 ClusterStatusInformation getRunningTasksClusterwide(long allowedAge, OperationResult parentResult)
          Returns running tasks; fetches new information only if after last query elapsed at least 'allowedAge' milliseconds.
 ClusterStatusInformation getRunningTasksClusterwide(OperationResult parentResult)
           
 boolean getServiceThreadsActivationState()
          Returns true if the service threads are running.
 Task getTask(java.lang.String taskOid, OperationResult parentResult)
          Returns a task with specified OID.
 void init()
          Initialization.
 boolean isCurrentNode(PrismObject<NodeType> node)
           
 boolean isInErrorState()
           
 void modifyTask(java.lang.String oid, java.util.Collection<? extends ItemDelta> modifications, OperationResult parentResult)
          Deprecated. 
 void onTaskCreate(java.lang.String oid, OperationResult parentResult)
          This is a signal to task manager that a new task was created in the repository.
 void onTaskDelete(java.lang.String oid, OperationResult parentResult)
          This is a signal to task manager that a task was removed from the repository.
 void postInit(OperationResult parentResult)
          Post initialization, e.g.
 void reactivateServiceThreads(OperationResult parentResult)
          Re-activate the service threads after they have been deactivated.
 void registerHandler(java.lang.String uri, TaskHandler handler)
          Register a handler for a specified handler URI.
 void resumeTask(Task task, OperationResult parentResult)
          Resume suspended task.
 void scheduleTaskNow(Task task, OperationResult parentResult)
           
 java.util.List<Node> searchNodes(ObjectQuery query, ClusterStatusInformation clusterStatusInformation, OperationResult parentResult)
          Returns relevant nodes (w.r.t query and paging specification).
 java.util.List<Task> searchTasks(ObjectQuery query, ClusterStatusInformation clusterStatusInformation, OperationResult parentResult)
          Returns relevant tasks (w.r.t.
 void setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory)
           
 void setConfiguration(TaskManagerConfiguration configuration)
           
 void setNodeErrorStatus(NodeErrorStatus nodeErrorStatus)
           
 void shutdown()
          Make sure all processes are stopped properly.
 void startScheduler(java.lang.String nodeIdentifier, OperationResult parentResult)
          Starts the scheduler on a given node.
 void stopScheduler(java.lang.String nodeIdentifier, OperationResult parentResult)
          Stops the scheduler on a given node.
 boolean stopSchedulersAndTasks(java.util.List<java.lang.String> nodeList, long timeToWait, OperationResult result)
           
 boolean suspendTask(Task task, long waitTime, boolean doNotStop, OperationResult parentResult)
           
 boolean suspendTask(Task task, long waitTime, OperationResult parentResult)
          Suspend task.
 boolean suspendTasks(java.util.Collection<Task> tasks, long waitTime, boolean doNotStop, OperationResult parentResult)
           
 boolean suspendTasks(java.util.Collection<Task> tasks, long waitTime, OperationResult parentResult)
           
 void switchToBackground(Task task, OperationResult parentResult)
          Switches the provided task to background, making it asynchronous.
 void synchronizeTasks(OperationResult result)
           
 void unpauseTask(Task task, OperationResult parentResult)
           
 void unscheduleTask(Task task, OperationResult parentResult)
           
 java.text.ParseException validateCronExpression(java.lang.String cron)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

TaskManagerQuartzImpl

public TaskManagerQuartzImpl()
Method Detail

init

@PostConstruct
public void init()
Initialization. TaskManager can work in two modes: - "stop on initialization failure" - it means that if TaskManager initialization fails, the midPoint will not be started (implemented by throwing SystemException). This is a safe approach, however, midPoint could be used also without Task Manager, so it is perhaps too harsh to do it this way. - "continue on initialization failure" - after such a failure midPoint initialization simply continues; however, task manager is switched to "Error" state, in which the scheduler cannot be started; Moreover, actually almost none Task Manager methods can be invoked, to prevent a damage. This second mode is EXPERIMENTAL, should not be used in production for now. --- So, (A) Generally, when not initialized, we refuse to execute almost all operations (knowing for sure that the scheduler is not running). (B) When initialized, but in error state (typically because of cluster misconfiguration not related to this node), we refuse to start the scheduler on this node. Other methods are OK.


postInit

public void postInit(OperationResult parentResult)
Description copied from interface: TaskManager
Post initialization, e.g. starts the actual scheduling of tasks on this node.

Specified by:
postInit in interface TaskManager

shutdown

@PreDestroy
public void shutdown()
Description copied from interface: TaskManager
Make sure all processes are stopped properly. Will block until all processes are shut down.

Specified by:
shutdown in interface TaskManager

isInErrorState

public boolean isInErrorState()

deactivateServiceThreads

public boolean deactivateServiceThreads(long timeToWait,
                                        OperationResult parentResult)
Description copied from interface: TaskManager
Deactivate service threads (temporarily). This will suspend all background activity such as scanning threads, heartbeats and similar mechanisms. Note: The threads are normally activated after task manager implementation starts. This methods should not be used in a normal case. WARNING: this feature is intended for development-time diagnostics and should not be used on production environments. Suspending the threads may affect correct behavior of the system (such as timeouts on heartbeats). Use this feature only if you really know what you are doing. timeToWait is only for orientation = it may be so that the implementation would wait 2 or 3 times this value (if it waits separately for several threads completion)

Specified by:
deactivateServiceThreads in interface TaskManager

reactivateServiceThreads

public void reactivateServiceThreads(OperationResult parentResult)
Description copied from interface: TaskManager
Re-activate the service threads after they have been deactivated.

Specified by:
reactivateServiceThreads in interface TaskManager

getServiceThreadsActivationState

public boolean getServiceThreadsActivationState()
Description copied from interface: TaskManager
Returns true if the service threads are running. This method returns true in a normal case. It returns false is the threads were temporarily suspended.

Specified by:
getServiceThreadsActivationState in interface TaskManager
Returns:
true if the service threads are running.

suspendTask

public boolean suspendTask(Task task,
                           long waitTime,
                           OperationResult parentResult)
Description copied from interface: TaskManager
Suspend task. TODO This method does not throw exceptions; it records its result in OperationResult.

Specified by:
suspendTask in interface TaskManager
Parameters:
task - task instance to claim

suspendTask

public boolean suspendTask(Task task,
                           long waitTime,
                           boolean doNotStop,
                           OperationResult parentResult)

suspendTasks

public boolean suspendTasks(java.util.Collection<Task> tasks,
                            long waitTime,
                            OperationResult parentResult)
Specified by:
suspendTasks in interface TaskManager

suspendTasks

public boolean suspendTasks(java.util.Collection<Task> tasks,
                            long waitTime,
                            boolean doNotStop,
                            OperationResult parentResult)
Specified by:
suspendTasks in interface TaskManager

unpauseTask

public void unpauseTask(Task task,
                        OperationResult parentResult)
                 throws ObjectNotFoundException,
                        SchemaException
Specified by:
unpauseTask in interface TaskManager
Throws:
ObjectNotFoundException
SchemaException

resumeTask

public void resumeTask(Task task,
                       OperationResult parentResult)
                throws ObjectNotFoundException,
                       SchemaException
Description copied from interface: TaskManager
Resume suspended task. TODO TODO: EXCEPTIONS

Specified by:
resumeTask in interface TaskManager
Parameters:
task - task instance to claim
Throws:
ObjectNotFoundException
SchemaException

createTaskInstance

public Task createTaskInstance()
Description copied from interface: TaskManager
Creates new transient, running, claimed task instance. This is fact creates usual "synchronous" task. This is useful for normal day-to-day tasks that are either synchronous or start as a synchronous and are switched to asynchronous task later.

Specified by:
createTaskInstance in interface TaskManager
Returns:
transient, running, claimed task instance

createTaskInstance

public Task createTaskInstance(java.lang.String operationName)
Description copied from interface: TaskManager
Creates new transient, running, claimed task instance. This is fact creates usual "synchronous" task. This is useful for normal day-to-day tasks that are either synchronous or start as a synchronous and are switched to asynchronous task later. The result inside the task will be initialized with specified operation name.

Specified by:
createTaskInstance in interface TaskManager
Parameters:
operationName - operation name to use as a root for new result in task
Returns:
new Java representation of the task

createTaskInstance

public Task createTaskInstance(PrismObject<TaskType> taskPrism,
                               OperationResult parentResult)
                        throws SchemaException
Description copied from interface: TaskManager
Creates task instance from the XML task representation.

Specified by:
createTaskInstance in interface TaskManager
Parameters:
taskPrism - JAXB (XML) representation of the task
Returns:
new Java representation of the task
Throws:
SchemaException - The provided taskType is not compliant to schema

createTaskInstance

public Task createTaskInstance(PrismObject<TaskType> taskPrism,
                               java.lang.String operationName,
                               OperationResult parentResult)
                        throws SchemaException
Description copied from interface: TaskManager
Creates task instance from the XML task representation. If there is not a result inside the task, it will create the result with specified operation name.

Specified by:
createTaskInstance in interface TaskManager
Parameters:
taskPrism - Prism representation of the task
operationName - operation name to use as a root for new result in task
Returns:
new Java representation of the task
Throws:
SchemaException - The provided taskType is not compliant to schema

getTask

public Task getTask(java.lang.String taskOid,
                    OperationResult parentResult)
             throws ObjectNotFoundException,
                    SchemaException
Description copied from interface: TaskManager
Returns a task with specified OID. This operation will look up a task instance in the repository and return it in a form of Task object. Works only on persistent tasks.

Specified by:
getTask in interface TaskManager
Parameters:
taskOid - OID of the persistent task.
Returns:
Task instance
Throws:
ObjectNotFoundException - wrong OID format, etc.
SchemaException - error dealing with resource schema

switchToBackground

public void switchToBackground(Task task,
                               OperationResult parentResult)
Description copied from interface: TaskManager
Switches the provided task to background, making it asynchronous. The provided task will be "released" to other nodes to execute. If the task execution state is "running" the method also tries to make sure that the task will be immediately execute (e.g. by allocating a thread). However, the nodes may compete for the tasks or there may be explicit limitations. Therefore there is no guarantee that the task will execute on the same node that called the switchToBackground() method.

Specified by:
switchToBackground in interface TaskManager
Parameters:
task - task to switch to background.

addTask

public java.lang.String addTask(PrismObject<TaskType> taskPrism,
                                OperationResult parentResult)
                         throws ObjectAlreadyExistsException,
                                SchemaException
Description copied from interface: TaskManager
Add new task. The OID provided in the task may be empty. In that case the OID will be assigned by the implementation of this method and it will be provided as return value. This operation should fail if such object already exists (if object with the provided OID already exists). The operation may fail if provided OID is in an unusable format for the storage. Generating own OIDs and providing them to this method is not recommended for normal operation. Should be atomic. Should not allow creation of two objects with the same OID (even if created in parallel). The operation may fail if the object to be created does not conform to the underlying schema of the storage system or the schema enforced by the implementation.

Specified by:
addTask in interface TaskManager
Parameters:
taskPrism - object to create
parentResult - parent OperationResult (in/out)
Returns:
OID assigned to the created object
Throws:
ObjectAlreadyExistsException - object with specified identifiers already exists, cannot add
SchemaException - error dealing with storage schema, e.g. schema violation

modifyTask

@Deprecated
public void modifyTask(java.lang.String oid,
                                  java.util.Collection<? extends ItemDelta> modifications,
                                  OperationResult parentResult)
                throws ObjectNotFoundException,
                       SchemaException
Deprecated. 

Description copied from interface: TaskManager
Modifies task using relative change description. Must fail if object with provided OID does not exists. Must fail if any of the described changes cannot be applied. Should be atomic. If two or more modify operations are executed in parallel, the operations should be merged. In case that the operations are in conflict (e.g. one operation adding a value and the other removing the same value), the result is not deterministic. The operation may fail if the modified object does not conform to the underlying schema of the storage system or the schema enforced by the implementation. TODO: optimistic locking

Specified by:
modifyTask in interface TaskManager
Parameters:
oid - OID of the task to be changed
modifications - specification of object changes
parentResult - parent OperationResult (in/out)
Throws:
ObjectNotFoundException - specified object does not exist
SchemaException - resulting object would violate the schema

deleteTask

public void deleteTask(java.lang.String oid,
                       OperationResult parentResult)
                throws ObjectNotFoundException,
                       SchemaException
Description copied from interface: TaskManager
Deletes task with provided OID. Must fail if object with specified OID does not exists. Should be atomic. BEWARE: call this method only if you are pretty sure the task is not running. Otherwise the running thread will complain when it will try to store task result into repo. (I.e. it is a good practice to suspend the task before deleting.)

Specified by:
deleteTask in interface TaskManager
Parameters:
oid - OID of object to delete
parentResult - parent OperationResult (in/out)
Throws:
ObjectNotFoundException - specified object does not exist
SchemaException

getNextRunStartTime

public java.lang.Long getNextRunStartTime(java.lang.String oid,
                                          OperationResult parentResult)
Specified by:
getNextRunStartTime in interface TaskManager

countNodes

public int countNodes(ObjectQuery query,
                      OperationResult result)
               throws SchemaException
Specified by:
countNodes in interface TaskManager
Throws:
SchemaException

searchNodes

public java.util.List<Node> searchNodes(ObjectQuery query,
                                        ClusterStatusInformation clusterStatusInformation,
                                        OperationResult parentResult)
                                 throws SchemaException
Description copied from interface: TaskManager
Returns relevant nodes (w.r.t query and paging specification). Similar to searchTasks, this method adds some information to the one returned from repository. (Mainly concerned with Node status and error status.)

Specified by:
searchNodes in interface TaskManager
clusterStatusInformation - The same as in searchTasks.
Returns:
Throws:
SchemaException

searchTasks

public java.util.List<Task> searchTasks(ObjectQuery query,
                                        ClusterStatusInformation clusterStatusInformation,
                                        OperationResult parentResult)
                                 throws SchemaException
Description copied from interface: TaskManager
Returns relevant tasks (w.r.t. query and paging specification). Comparing to searchObjects(TaskType) in repo, there are the following differences: (1) This method combines information from the repository with run-time information obtained from cluster nodes (clusterStatusInformation), mainly to tell what tasks are really executing at this moment. The repository contains 'node' attribute (telling on which node task runs), which may be out-of-date for nodes which crashed recently. (2) this method returns Tasks, not TaskTypes - a Task provides some information (e.g. getNextRunStartTime()) that is not stored in repository; Task object can be directly used as an input to several methods, like suspendTask() or releaseTask(). However, the reason (2) is only of a technical character. So, if necessary, this method can be changed to return a list of TaskTypes instead of Tasks.

Specified by:
searchTasks in interface TaskManager
Parameters:
query - Search query
clusterStatusInformation - If null, the method will query cluster nodes to get up-to-date runtime information. If non-null, the method will use the provided information. Used to optimize network traffic in case of repeating calls to searchTasks/searchNodes (e.g. when displaying them on one page).
Returns:
Throws:
SchemaException

countTasks

public int countTasks(ObjectQuery query,
                      OperationResult result)
               throws SchemaException
Specified by:
countTasks in interface TaskManager
Throws:
SchemaException

registerHandler

public void registerHandler(java.lang.String uri,
                            TaskHandler handler)
Description copied from interface: TaskManager
Register a handler for a specified handler URI.

Specified by:
registerHandler in interface TaskManager

getHandler

public TaskHandler getHandler(java.lang.String uri)

getAllTaskCategories

public java.util.List<java.lang.String> getAllTaskCategories()
Specified by:
getAllTaskCategories in interface TaskManager

getHandlerUriForCategory

public java.lang.String getHandlerUriForCategory(java.lang.String category)
Specified by:
getHandlerUriForCategory in interface TaskManager

onTaskCreate

public void onTaskCreate(java.lang.String oid,
                         OperationResult parentResult)
Description copied from interface: TaskManager
This is a signal to task manager that a new task was created in the repository. Task manager can react to it e.g. by creating shadow quartz job and trigger.

Specified by:
onTaskCreate in interface TaskManager

onTaskDelete

public void onTaskDelete(java.lang.String oid,
                         OperationResult parentResult)
Description copied from interface: TaskManager
This is a signal to task manager that a task was removed from the repository. Task manager can react to it e.g. by removing shadow quartz job and trigger.

Specified by:
onTaskDelete in interface TaskManager

getConfiguration

public TaskManagerConfiguration getConfiguration()

getPrismContext

public PrismContext getPrismContext()

getLocalNodeErrorStatus

public NodeErrorStatus getLocalNodeErrorStatus()

setNodeErrorStatus

public void setNodeErrorStatus(NodeErrorStatus nodeErrorStatus)

setBeanFactory

public void setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory)
                    throws org.springframework.beans.BeansException
Specified by:
setBeanFactory in interface org.springframework.beans.factory.BeanFactoryAware
Throws:
org.springframework.beans.BeansException

getMidpointConfiguration

public MidpointConfiguration getMidpointConfiguration()

getBeanFactory

public org.springframework.beans.factory.BeanFactory getBeanFactory()

getClusterManager

public ClusterManager getClusterManager()

getRepositoryService

public RepositoryService getRepositoryService()

setConfiguration

public void setConfiguration(TaskManagerConfiguration configuration)

getExecutionManager

public ExecutionManager getExecutionManager()

synchronizeTasks

public void synchronizeTasks(OperationResult result)
Specified by:
synchronizeTasks in interface TaskManager

getNodeId

public java.lang.String getNodeId()
Specified by:
getNodeId in interface TaskManager

getRunningTasks

@Deprecated
public java.util.Set<Task> getRunningTasks()
                                    throws TaskManagerException
Deprecated. 

Description copied from interface: TaskManager
Returns tasks that currently run on this node. E.g. tasks that have allocated threads. It should be a different view than looking for a claimed tasks in the repository, although normally it should return the same data. This should look at the real situation (e.g. threads) and should be used to troubleshoot task management problems.

Specified by:
getRunningTasks in interface TaskManager
Returns:
tasks that currently run on this node.
Throws:
TaskManagerException

stopScheduler

public void stopScheduler(java.lang.String nodeIdentifier,
                          OperationResult parentResult)
Description copied from interface: TaskManager
Stops the scheduler on a given node. This means that at that node no tasks will be started.

Specified by:
stopScheduler in interface TaskManager
Parameters:
nodeIdentifier - Node on which the scheduler should be stopped. Null means current node.

startScheduler

public void startScheduler(java.lang.String nodeIdentifier,
                           OperationResult parentResult)
Description copied from interface: TaskManager
Starts the scheduler on a given node. A prerequisite is that the node is running and its TaskManager is not in an error state.

Specified by:
startScheduler in interface TaskManager
Parameters:
nodeIdentifier - Node on which the scheduler should be started. Null means current node.

stopSchedulersAndTasks

public boolean stopSchedulersAndTasks(java.util.List<java.lang.String> nodeList,
                                      long timeToWait,
                                      OperationResult result)
Specified by:
stopSchedulersAndTasks in interface TaskManager

getRunningTasksClusterwide

public ClusterStatusInformation getRunningTasksClusterwide(OperationResult parentResult)
Specified by:
getRunningTasksClusterwide in interface TaskManager

getRunningTasksClusterwide

public ClusterStatusInformation getRunningTasksClusterwide(long allowedAge,
                                                           OperationResult parentResult)
Description copied from interface: TaskManager
Returns running tasks; fetches new information only if after last query elapsed at least 'allowedAge' milliseconds.

Specified by:
getRunningTasksClusterwide in interface TaskManager
Returns:

isCurrentNode

public boolean isCurrentNode(PrismObject<NodeType> node)
Specified by:
isCurrentNode in interface TaskManager

deleteNode

public void deleteNode(java.lang.String nodeIdentifier,
                       OperationResult result)
Specified by:
deleteNode in interface TaskManager

scheduleTaskNow

public void scheduleTaskNow(Task task,
                            OperationResult parentResult)
Specified by:
scheduleTaskNow in interface TaskManager

unscheduleTask

public void unscheduleTask(Task task,
                           OperationResult parentResult)

closeTask

public void closeTask(Task task,
                      OperationResult parentResult)
               throws ObjectNotFoundException,
                      SchemaException
Throws:
ObjectNotFoundException
SchemaException

closeTaskWithoutSavingState

public void closeTaskWithoutSavingState(Task task,
                                        OperationResult parentResult)

validateCronExpression

public java.text.ParseException validateCronExpression(java.lang.String cron)
Specified by:
validateCronExpression in interface TaskManager


Copyright © 2012 evolveum. All Rights Reserved.