Interface TaskManager


  • public interface TaskManager

    Task Manager Interface.

    Status: public Stability: DRAFT

    Version:
    0.1
    Author:
    Radovan Semancik, Pavol Mederly

    Task manager provides controls task execution, coordination, distribution and failover between nodes, etc.

    This interface is just a basic framework for task management now. Although we hope that this is roughly almost final shape of the interface, the implementation is not complete and some changes may happen.

    This definition specifies interface of Task Manager - a component that controls (asynchronous) task execution.

    The task manager can store the task for later execution, switch them to background resume execution of a task from a different node, etc. Generally speaking, task manager provides operation to manage tasks in the whole midPoint cluster of IDM nodes.

    This interface partially adheres to [Common Interface Concepts], but the goals are slightly different. This interface should be conveniently used also for tasks that are not persistent (synchronous short tasks). Therefore some methods are made much more user-friendly while tolerating some redundancy in the interface.

    • Method Detail

      • addTask

        default String addTask​(PrismObject<TaskType> taskPrism,
                               OperationResult parentResult)
                        throws ObjectAlreadyExistsException,
                               SchemaException
        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.
        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
        IllegalArgumentException - wrong OID format, etc.
      • modifyTask

        void modifyTask​(String oid,
                        Collection<? extends ItemDelta<?,​?>> modifications,
                        OperationResult parentResult)
                 throws ObjectNotFoundException,
                        SchemaException,
                        ObjectAlreadyExistsException
        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. HOWEVER, the preferred way of modifying tasks is to use methods in Task interface.
        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
        IllegalArgumentException - wrong OID format, described change is not applicable
        ObjectAlreadyExistsException
      • deleteTask

        void deleteTask​(String oid,
                        OperationResult parentResult)
                 throws ObjectNotFoundException,
                        SchemaException
        Deletes task with provided OID. Must fail if object with specified OID does not exist. 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.)
        Parameters:
        oid - OID of object to delete
        parentResult - parent OperationResult (in/out)
        Throws:
        ObjectNotFoundException - specified object does not exist
        IllegalArgumentException - wrong OID format, described change is not applicable
        SchemaException
      • createTaskInstance

        default Task createTaskInstance()
        Creates new transient, running 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.
        Returns:
        transient, running task instance
      • createTaskInstance

        @NotNull
        @NotNull Task createTaskInstance​(PrismObject<TaskType> taskPrism,
                                         OperationResult parentResult)
                                  throws SchemaException
        Creates task instance from the XML task representation.
        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

        Task createTaskInstance​(String operationName)
        Creates new transient, running task instance. This in 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.
        Parameters:
        operationName - operation name to use as a root for new result in task
        Returns:
        new Java representation of the task
      • createTaskInstance

        @NotNull
        @NotNull Task createTaskInstance​(PrismObject<TaskType> taskPrism,
                                         @Deprecated
                                         String operationName,
                                         OperationResult parentResult)
                                  throws SchemaException
        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.
        Parameters:
        taskPrism - Prism representation of the task
        operationName - operation name to use as a root for new result in task -- IGNORED
        Returns:
        new Java representation of the task
        Throws:
        SchemaException - The provided taskType is not compliant to schema
      • getTaskPlain

        @NotNull
        @NotNull Task getTaskPlain​(String taskOid,
                                   OperationResult parentResult)
                            throws ObjectNotFoundException,
                                   SchemaException
        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. Gets the task simply by fetching it from repository. No attempts to augment it with the live data nor Quartz scheduling information nor subtasks is done. TODO can we use options (noFetch? raw?) to achieve this?
        Parameters:
        taskOid - OID of the persistent task.
        Returns:
        Task instance
        Throws:
        SchemaException - error dealing with resource schema
        ObjectNotFoundException - wrong OID format, etc.
      • cleanupTasks

        void cleanupTasks​(@NotNull
                          @NotNull CleanupPolicyType closedTasksPolicy,
                          @NotNull
                          @NotNull Predicate<TaskType> selector,
                          @NotNull
                          @NotNull RunningTask task,
                          @NotNull
                          @NotNull OperationResult opResult)
                   throws SchemaException,
                          ObjectNotFoundException
        Deletes obsolete tasks, as specified in the policy. This method removes whole task trees, i.e. not single tasks. A task tree is deleted if the root task is closed (assuming all tasks in the tree are closed) and was closed before at least specified time.
        Parameters:
        closedTasksPolicy - specifies which tasks are to be deleted, e.g. how old they have to be
        selector - If returns false, the respective task will not be removed. In a task tree, the selector must return true for every task for the tree to be deleted.
        task - task, within which context the cleanup executes (used to test for interruptions)
        Throws:
        SchemaException
        ObjectNotFoundException
      • getLocalSchedulerInformation

        SchedulerInformationType getLocalSchedulerInformation​(OperationResult parentResult)
        Returns the local scheduler information. To be called from the task manager on other nodes.
      • stopLocalScheduler

        void stopLocalScheduler​(OperationResult parentResult)
        Stops the local scheduler. To be called from the task manager on other nodes.
      • startLocalScheduler

        void startLocalScheduler​(OperationResult parentResult)
        Starts the local scheduler. To be called from the task manager on other nodes.
      • stopLocalTaskRunInStandardWay

        void stopLocalTaskRunInStandardWay​(String oid,
                                           OperationResult result)
        Stops the local task. To be called from the task manager on other nodes.
      • suspendTasks

        boolean suspendTasks​(Collection<String> taskOids,
                             long waitForStop,
                             OperationResult parentResult)
        Suspends a set of tasks. Sets their execution status to SUSPENDED. Stops their execution (unless doNotStop is set).
        Parameters:
        taskOids - a collection of OIDs of tasks that have to be suspended
        waitForStop - how long (in milliseconds) to wait for stopping the execution of tasks; WAIT_INDEFINITELY means wait indefinitely, DO_NOT_WAIT means stop the tasks, but do not wait for finishing their execution, DO_NOT_STOP means do not try to stop the task execution. Tasks will only be put into SUSPENDED state, and their executions (if any) will be left as they are. Use this option only when you know what you're doing.
        Returns:
        true if all the tasks were stopped, false if some tasks continue to run or if stopping was not requested (DO_NOT_STOP option) On error conditions does NOT throw an exception.
      • suspendAndDeleteTasks

        void suspendAndDeleteTasks​(Collection<String> taskOidList,
                                   long suspendTimeout,
                                   boolean alsoSubtasks,
                                   OperationResult parentResult)
        Suspends tasks and deletes them.
        Parameters:
        taskOidList - List of task OIDs to be suspended and deleted.
        suspendTimeout - How long (in milliseconds) to wait for task suspension before proceeding with deletion.
        alsoSubtasks - Should also subtasks be deleted?
      • suspendAndCloseTaskNoException

        void suspendAndCloseTaskNoException​(Task task,
                                            long suspendTimeout,
                                            OperationResult parentResult)
        TODO
      • resumeTasks

        void resumeTasks​(Collection<String> taskOids,
                         OperationResult parentResult)
        Resume suspended tasks.
        Parameters:
        taskOids - a collection of OIDs of tasks that have to be resumed
      • switchToBackground

        void switchToBackground​(Task task,
                                OperationResult parentResult)
        Switches the provided task to background, making it asynchronous. The provided task will be "released" to other nodes to execute. There is no guarantee that the task will execute on the same node that called the switchToBackground() method.
        Parameters:
        task - task to switch to background.
      • scheduleTasksNow

        void scheduleTasksNow​(Collection<String> taskOids,
                              OperationResult parentResult)
        Schedules RUNNABLE/CLOSED tasks to be run immediately. (If a task will really start immediately, depends e.g. on whether a scheduler is started, whether there are available threads, and so on.)
        Parameters:
        taskOids - a collection of OIDs of tasks that have to be scheduled Proceeds quietly - i.e. on exception it simply logs it.
      • getNodeId

        @NotNull
        @NotNull String getNodeId()
        Returns identifier for current node.
      • isCurrentNode

        boolean isCurrentNode​(PrismObject<NodeType> node)
        Checks whether supplied node is the current node.
        Returns:
        true if node is the current node
      • registerNodeUp

        void registerNodeUp​(OperationResult result)
        Registers current node as "up". Normally this is done after midPoint starting up; but should be done explicitly in tests.
      • deactivateServiceThreads

        boolean deactivateServiceThreads​(long timeToWait,
                                         OperationResult parentResult)
                                  throws SchemaException
        Deactivates 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)
        Throws:
        SchemaException
      • reactivateServiceThreads

        void reactivateServiceThreads​(OperationResult parentResult)
        Re-activates the service threads after they have been deactivated.
      • getServiceThreadsActivationState

        boolean getServiceThreadsActivationState()
        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.
        Returns:
        true if the service threads are running.
      • stopScheduler

        void stopScheduler​(String nodeIdentifier,
                           OperationResult parentResult)
        Stops the scheduler on a given node. This means that at that node no tasks will be started.
        Parameters:
        nodeIdentifier - Node on which the scheduler should be stopped. Null means current node.
      • stopSchedulersAndTasks

        boolean stopSchedulersAndTasks​(Collection<String> nodeIdentifiers,
                                       long waitTime,
                                       OperationResult parentResult)
                                throws SchemaException
        Stops a set of schedulers (on their nodes) and tasks that are executing on these nodes.
        Parameters:
        nodeIdentifiers - collection of node identifiers
        waitTime - how long to wait for task shutdown, in milliseconds; WAIT_INDEFINITELY means wait indefinitely, DO_NOT_WAIT means stop the tasks, but do not wait for finishing their execution.
        Throws:
        SchemaException
      • startScheduler

        void startScheduler​(String nodeIdentifier,
                            OperationResult parentResult)
        Starts the scheduler on a given node. A prerequisite is that the node is running and its TaskManager is not in an error state.
        Parameters:
        nodeIdentifier - Node on which the scheduler should be started. Null means current node.
      • registerTaskListener

        void registerTaskListener​(TaskListener taskListener)
        Registers a task listener that will be notified on task-related events.
        Parameters:
        taskListener - listener to be registered
      • unregisterTaskListener

        void unregisterTaskListener​(TaskListener taskListener)
        Unregisters a task listener.
        Parameters:
        taskListener - listener to be unregistered
      • registerTaskUpdatedListener

        void registerTaskUpdatedListener​(TaskUpdatedListener taskListener)
      • unregisterTaskUpdatedListener

        void unregisterTaskUpdatedListener​(TaskUpdatedListener taskListener)
      • onSystemStarted

        @EventListener(org.springframework.boot.context.event.ApplicationReadyEvent.class)
        void onSystemStarted()
        Called when the whole application is initialized. Here we make this node a real cluster member: We set the operational state to UP, enabling receiving cache invalidation events (among other effects). We also invalidate local caches - to begin with a clean slate - and start the scheduler. The postInit mechanism cannot be used for this purpose. The reason is that it is invoked shortly before the application is completely up. REST endpoints are not yet functional at that time. This means that some of the cache invalidation messages could be lost, and the other nodes could get error messages in the meanwhile. Unfortunately, REST endpoints are not initialized even when this event is emitted. There's a few seconds before they are really available. So the real action can be delayed by setting "nodeStartupDelay" configuration parameter. (This is a temporary solution until something better is found.)
      • synchronizeTasks

        void synchronizeTasks​(OperationResult parentResult)
        Synchronizes information in midPoint repository and task scheduling database.
      • getNextRunStartTime

        Long getNextRunStartTime​(String oid,
                                 OperationResult result)
        Gets next scheduled execution time for a given task.
        Parameters:
        oid - OID of the task
        Returns:
        null if there's no next scheduled execution for a given task or if a task with given OID does not exist
      • getAllHandlerUris

        Collection<String> getAllHandlerUris​(boolean nonDeprecatedOnly)
        Returns all registered handler URIs.
        Parameters:
        nonDeprecatedOnly - If true, only non-deprecated handler URIs are returned.
      • getHandlerUrisForArchetype

        Collection<String> getHandlerUrisForArchetype​(String archetypeOid,
                                                      boolean nonDeprecatedOnly)
        Returns all registered handler URIs for given archetype.
      • registerHandler

        void registerHandler​(@NotNull
                             @NotNull String uri,
                             @NotNull
                             @NotNull TaskHandler handler)
        Registers a handler for a specified handler URI.
        Parameters:
        uri - URI of the handler, e.g. http://midpoint.evolveum.com/xml/ns/public/model/cleanup/handler-3
        handler - instance of the handler
      • unregisterHandler

        void unregisterHandler​(String uri)
        Unregisters a handler URI (registered either as "standard", additional or deprecated handler URI).
      • registerTaskDeletionListener

        void registerTaskDeletionListener​(TaskDeletionListener listener)
      • setDefaultHandlerUri

        void setDefaultHandlerUri​(String uri)
      • isLocalNodeClusteringEnabled

        boolean isLocalNodeClusteringEnabled()
        EXPERIMENTAL. Relaxes some assumptions on cluster structure e.g. that IP addresses of cluster members must be different. To be used for demonstration/testing only. Avoid using in production environments.
      • setWebContextPath

        void setWebContextPath​(String path)
        EXPERIMENTAL. Used to provide midPoint URL path (typically "/midpoint") when determined by the web layer.
      • createFakeRunningTask

        RunningTask createFakeRunningTask​(Task task)
        Use only for tests. (Even in that case it is an ugly hack.)
      • isDynamicProfilingEnabled

        boolean isDynamicProfilingEnabled()
      • isClustered

        boolean isClustered()
      • isTracingOverridden

        boolean isTracingOverridden()
      • unsetGlobalTracingOverride

        void unsetGlobalTracingOverride()
      • isUpAndAlive

        boolean isUpAndAlive​(NodeType node)
        Returns:
        true if we consider this node to be "up" (alive). This is determined by looking at operational state (should be UP) and last check-in information (should not be more than nodeTimeout ago).
      • isCheckingIn

        boolean isCheckingIn​(NodeType node)
        Returns:
        true if this node has recently checked in. It might be starting or up.
      • getLocalNodeGroups

        Collection<ObjectReferenceType> getLocalNodeGroups()
        Returns:
        Collection of node groups that the current cluster node belongs to. The collection is unmodifiable. Groups are represented by abstract roles. (Current implementation uses node archetypes to keep this information.)
      • getLocallyRunningTaskByIdentifier

        RunningTask getLocallyRunningTaskByIdentifier​(String lightweightIdentifier)
        Returns locally-run task by identifier. Returned instance is the same as is being used to carrying out operations. SO USE WITH CARE. EXPERIMENTAL. Should be replaced by something like "get operational information".
      • waitForTransientChildrenAndCloseThem

        void waitForTransientChildrenAndCloseThem​(RunningTask task,
                                                  OperationResult result)
        Should be called only from the thread that created the children - to avoid race conditions.
      • getDBPoolStats

        Number[] getDBPoolStats()
        Returns hikari pool statistics (active, idle, waiting, total, max number of DB connections) Return null if pool is unavailable. TODO move to more appropriate place