Search in sources :

Example 21 with Task

use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.

the class EventParserImpl method parseEvent.

@Override
public Task parseEvent(String event) throws InvalidEventMessageException, ServiceNotExistsException, InternalErrorException, PrivilegeException {
    log.info("I am going to process event:" + event);
    /**
		 * Expected string format as on:
		 * https://projekty.ics.muni.cz/perunv3/trac
		 * /wiki/PerunEngineDispatcherController event|x|[timestamp][Event
		 * header][Event data] New format:
		 * "task|[engine_id]|[task_id][is_forced]|[exec_service]|[facility]|[destination_list]|[dependency_list]"
		 * 
		 */
    // String eventParsingPattern =
    // "^event\\|([0-9]{1,6})\\|\\[([a-zA-Z0-9: ]+)\\]\\[([^\\]]+)\\]\\[(.*)\\]$";
    String eventParsingPattern = "^task\\|([0-9]{1,6})\\|\\[([0-9]+)\\]\\[([^\\]]+)\\]\\|\\[([^\\|]+)\\]\\|\\[([^\\|]+)\\]\\|\\[([^\\|]+)\\]\\|\\[(.*)\\]$";
    Pattern pattern = Pattern.compile(eventParsingPattern);
    Matcher matcher = pattern.matcher(event);
    boolean matchFound = matcher.find();
    if (matchFound) {
        log.debug("Message format matched ok...");
        String thisEngineID = matcher.group(1);
        // compare it...
        try {
            if (Integer.parseInt(thisEngineID) != Integer.parseInt((String) propertiesBean.get("engine.unique.id"))) {
                throw new InvalidEventMessageException("Wrong Engine ID. Was:" + thisEngineID + ", Expected:" + propertiesBean.get("engine.unique.id"));
            }
        } catch (Exception e) {
            throw new InvalidEventMessageException("Wrong Engine ID: parse exception", e);
        }
        // Data should provide information regarding the target ExecService
        // (Processing rule).
        String eventTaskId = matcher.group(2);
        String eventIsForced = matcher.group(3);
        String eventExecService = matcher.group(4);
        String eventFacility = matcher.group(5);
        String eventDestinationList = matcher.group(6);
        String eventDependencyList = matcher.group(7);
        // check possible enconding
        if (!eventExecService.startsWith("ExecService")) {
            eventExecService = new String(Base64.decodeBase64(eventExecService));
        }
        if (!eventExecService.startsWith("ExecService")) {
            throw new InvalidEventMessageException("Wrong exec service: parse exception");
        }
        if (!eventFacility.startsWith("Facility")) {
            eventFacility = new String(Base64.decodeBase64(eventFacility));
        }
        if (!eventFacility.startsWith("Facility")) {
            throw new InvalidEventMessageException("Wrong facility: parse exception");
        }
        if (!eventDestinationList.startsWith("Destinations")) {
            eventDestinationList = new String(Base64.decodeBase64(eventDestinationList));
        }
        if (!eventDestinationList.startsWith("Destinations")) {
            throw new InvalidEventMessageException("Wrong destination list: parse exception");
        }
        log.debug("Event data to be parsed: task id " + eventTaskId + ", forced " + eventIsForced + ", facility " + eventFacility + ", exec service " + eventExecService + ", destination list " + eventDestinationList + ", dependency list " + eventDependencyList);
        // Prepare variables
        Facility facility;
        ExecService execService;
        List<Destination> destinationList = new ArrayList<Destination>();
        // resolve facility
        // deserialize event data
        List<PerunBean> listOfBeans = AuditParser.parseLog(eventFacility);
        try {
            facility = (Facility) listOfBeans.get(0);
        } catch (Exception e) {
            throw new InvalidEventMessageException("Could not resolve facility from event [" + eventFacility + "]", e);
        }
        // resolve exec service
        // deserialize event data
        listOfBeans = AuditParser.parseLog(eventExecService);
        try {
            execService = (ExecService) listOfBeans.get(0);
        } catch (Exception e) {
            throw new InvalidEventMessageException("Could not resolve exec service from event [" + eventExecService + "]", e);
        }
        // resolve list of destinations
        listOfBeans = AuditParser.parseLog(eventDestinationList);
        log.debug("Found list of destination beans: " + listOfBeans);
        // return new Pair<ExecService, Facility>(execService, facility);
        try {
            for (PerunBean bean : listOfBeans) {
                destinationList.add((Destination) bean);
            }
        } catch (Exception e) {
            throw new InvalidEventMessageException("Could not resolve list of destinations from event.", e);
        }
        Task task = new Task();
        task.setId(Integer.parseInt(eventTaskId));
        task.setFacility(facility);
        task.setExecService(execService);
        task.setDestinations(destinationList);
        task.setDelay(execService.getDefaultDelay());
        task.setRecurrence(execService.getDefaultRecurrence());
        task.setPropagationForced(Boolean.parseBoolean(eventIsForced));
        // resolve list of dependencies
        if (eventDependencyList != null) {
            for (String token : eventDependencyList.split("[\t ]*,[\t ]*")) {
                if (token.length() > 0) {
                    try {
                        dependenciesResolver.addDependency(task, Integer.parseInt(token));
                    } catch (Exception e) {
                        throw new InvalidEventMessageException("Invalid dependency in event: " + token);
                    }
                }
            }
        }
        return task;
    } else {
        throw new InvalidEventMessageException("Invalid message format: Message[" + event + "]");
    }
}
Also used : Pattern(java.util.regex.Pattern) Destination(cz.metacentrum.perun.core.api.Destination) Task(cz.metacentrum.perun.taskslib.model.Task) Matcher(java.util.regex.Matcher) ExecService(cz.metacentrum.perun.taskslib.model.ExecService) ArrayList(java.util.ArrayList) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) ServiceNotExistsException(cz.metacentrum.perun.core.api.exceptions.ServiceNotExistsException) InvalidEventMessageException(cz.metacentrum.perun.engine.exceptions.InvalidEventMessageException) PrivilegeException(cz.metacentrum.perun.core.api.exceptions.PrivilegeException) PerunBean(cz.metacentrum.perun.core.api.PerunBean) Facility(cz.metacentrum.perun.core.api.Facility) InvalidEventMessageException(cz.metacentrum.perun.engine.exceptions.InvalidEventMessageException)

Example 22 with Task

use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.

the class PropagationMaintainerImpl method rescheduleErrorTasks.

@Deprecated
private void rescheduleErrorTasks() {
    for (Task task : schedulingPool.getErrorTasks()) {
        log.debug("TASK " + task.toString() + " finished in error");
        if (task.getEndTime() == null) {
            log.error("RECOVERY FROM INCONSISTENT STATE: ERROR task does not have end_time! Setting end_time to task.getDelay + 1.");
            // getDelay is in minutes, therefore we multiply it with 60*1000
            Date endTime = new Date(System.currentTimeMillis() - ((task.getDelay() + 1) * 60000));
            task.setEndTime(endTime);
        }
        int howManyMinutesAgo = (int) (System.currentTimeMillis() - task.getEndTime().getTime()) / 1000 / 60;
        log.info("TASK [" + task + "] in ERROR state completed " + howManyMinutesAgo + " minutes ago.");
        // check and set recurrence
        int recurrence = task.getRecurrence() - 1;
        if (recurrence < 0) {
            // no more retries, sorry
            log.info("TASK [ " + task + "] in ERROR state has no more retries, bailing out.");
            schedulingPool.removeTask(task);
            log.debug("TASK {} removed from database.", task.getId());
            continue;
        }
        // If DELAY time has passed, we reschedule...
        if (howManyMinutesAgo >= task.getDelay()) {
            try {
                task.setRecurrence(recurrence);
                ExecService execService = task.getExecService();
                Facility facility = task.getFacility();
                log.info("TASK [	" + task + "] in ERROR state is going to be rescheduled: taskScheduler.propagateService(execService:ID " + execService.getId() + ", new Date(System.currentTimeMillis()), facility:ID " + facility.getId() + ");");
                taskScheduler.propagateService(task, new Date(System.currentTimeMillis()));
                log.info("TASK [" + task + "] in ERROR state has been rescheduled.");
                // Also (to be sure) reschedule all Tasks that depend on
                // this Task
                //
                // While engine starts in state GEN = ERROR, SEND = DONE
                // => GEN will be rescheduled but without this SEND will
                // never be propagated
                List<Task> dependentTasks = dependenciesResolver.getDependants(task);
                if (dependentTasks != null) {
                    for (Task dependantTask : dependentTasks) {
                        taskScheduler.propagateService(dependantTask, new Date(System.currentTimeMillis()));
                        log.info("{} was rescheduled because it depends on {}", dependantTask, task);
                    }
                }
            } catch (InternalErrorException e) {
                log.error("{}", e);
            }
        }
    }
/*
		 * Original implementation:
		 *
		 * //TODO: Take into account Recurrence! for (Task task :
		 * taskManager.listAllTasksInState(TaskStatus.ERROR,
		 * Integer.parseInt(propertiesBean.getProperty("engine.unique.id")))) {
		 * if (task.getEndTime() == null) { log.error(
		 * "RECOVERY FROM INCONSISTATE STATE: ERROR task does not have end_time! Setting end_time to task.getDelay + 1."
		 * ); // getDelay is in minutes, therefore we multiply it with 60*1000
		 * Date endTime = new Date(System.currentTimeMillis() -
		 * ((task.getDelay() + 1) * 60000)); task.setEndTime(endTime);
		 * taskManager.updateTask(task,
		 * Integer.parseInt(propertiesBean.getProperty("engine.unique.id"))); }
		 * int howManyMinutesAgo = (int) (System.currentTimeMillis() -
		 * task.getEndTime().getTime()) / 1000 / 60; log.info("TASK [" + task +
		 * "] in ERROR state completed " + howManyMinutesAgo + " minutes ago.");
		 * //If DELAY time has passed, we reschedule... if (howManyMinutesAgo >=
		 * task.getDelay()) { //check if service is still assigned on facility
		 * try { List<Service> assignedServices =
		 * Rpc.ServicesManager.getAssignedServices(engineManager.getRpcCaller(),
		 * task.getFacility());
		 * if(assignedServices.contains(task.getExecService().getService())) {
		 * try { taskManager.updateTask(task,
		 * Integer.parseInt(propertiesBean.getProperty("engine.unique.id")));
		 * ExecService execService = task.getExecService(); Facility facility =
		 * task.getFacility(); log.info("TASK [" + task +
		 * "] in ERROR state is going to be rescheduled: taskScheduler.propagateService(execService:ID "
		 * + execService.getId() +
		 * ", new Date(System.currentTimeMillis()), facility:ID " +
		 * facility.getId() + ");"); taskScheduler.propagateService(execService,
		 * new Date(System.currentTimeMillis()), facility); log.info("TASK [" +
		 * task + "] in ERROR state has been rescheduled.");
		 *
		 * //Also (to be sure) reschedule all execServices which depends on this
		 * exec service // //While engine starts in state GEN = ERROR, SEND =
		 * DONE => GEN will be rescheduled but without this SEND will never be
		 * propagated List<ExecService> dependentExecServices =
		 * Rpc.GeneralServiceManager
		 * .listExecServicesDependingOn(engineManager.getRpcCaller(),
		 * execService); if(dependentExecServices != null) { for(ExecService
		 * dependantExecService : dependentExecServices) {
		 * taskScheduler.propagateService(dependantExecService, new
		 * Date(System.currentTimeMillis()), facility);
		 * log.info("{} was rescheduled because it depends on {}",
		 * dependantExecService, execService); } }
		 *
		 * } catch (InternalErrorException e) { log.error(e.toString(), e); } }
		 * else { //delete this tasks (SEND and GEN) because service is no
		 * longer assigned to facility List<ExecService> execServicesGenAndSend
		 * =
		 * Rpc.GeneralServiceManager.listExecServices(engineManager.getRpcCaller
		 * (), task.getExecService().getService().getId()); for(ExecService
		 * execService : execServicesGenAndSend) { Task taskToDelete =
		 * taskManager.getTask(execService, task.getFacility(),
		 * Integer.parseInt(propertiesBean.getProperty("engine.unique.id")));
		 * if(taskToDelete!= null) {
		 * resultManager.clearByTask(taskToDelete.getId(),
		 * Integer.parseInt(propertiesBean.getProperty("engine.unique.id")));
		 * taskManager.removeTask(taskToDelete.getId(),
		 * Integer.parseInt(propertiesBean.getProperty("engine.unique.id"))); }
		 * } } } catch(PrivilegeException ex) {
		 * log.error("Consistency error. {}", ex); }
		 * catch(FacilityNotExistsException ex) {
		 * log.error("Consistency error - found task for non-existing facility. {}"
		 * , ex); } catch(ServiceNotExistsException ex) {
		 * log.error("Consistency error - found task for non-existing service. {}"
		 * , ex); } catch(InternalErrorException ex) { log.error("{}", ex); } }
		 * }
		 */
}
Also used : Task(cz.metacentrum.perun.taskslib.model.Task) ExecService(cz.metacentrum.perun.taskslib.model.ExecService) Facility(cz.metacentrum.perun.core.api.Facility) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) Date(java.util.Date)

Example 23 with Task

use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.

the class TaskExecutorEngineImpl method runTask.

/**
	 * Put the task into PROCESSING state and create workers for all
	 * destinations that have satisfied dependencies (or no dependencies at
	 * all).
	 * 
	 * @param task
	 *            Task to start.
	 * 
	 */
public void runTask(Task task) {
    schedulingPool.setTaskStatus(task, TaskStatus.PROCESSING);
    task.setStartTime(new Date(System.currentTimeMillis()));
    List<Task> dependencies = dependencyResolver.getDependencies(task);
    // TODO: handle GEN tasks with no destinations
    boolean started = false;
    for (Destination destination : taskStatusManager.getTaskStatus(task).getWaitingDestinations()) {
        // check if all the dependency destinations are done
        boolean proceed = true;
        try {
            for (Task dependency : dependencies) {
                if (taskStatusManager.getTaskStatus(dependency).getDestinationStatus(destination) != TaskDestinationStatus.DONE) {
                    log.debug("TASK " + task.toString() + " has unmet dependencies");
                    proceed = false;
                }
            }
        } catch (InternalErrorException e) {
            log.error("Error getting dependency status for task {}", task.toString());
        }
        if (proceed) {
            try {
                if (task.getExecService().getExecServiceType().equals(ExecServiceType.SEND)) {
                    taskStatusManager.getTaskStatus(task).setDestinationStatus(destination, TaskDestinationStatus.PROCESSING);
                }
            } catch (InternalErrorException e) {
                log.error("Error setting status for destination {} of task {}", destination, task.toString());
            }
            try {
                startWorker(task, destination);
                started = true;
            } catch (Exception e) {
                log.error("Error queuing worker for execution: " + e.toString());
            }
        }
    }
    if (!started) {
        log.warn("No worker started for task {}, setting to ERROR", task.getId());
        task.setEndTime(new Date(System.currentTimeMillis()));
        schedulingPool.setTaskStatus(task, TaskStatus.ERROR);
    }
}
Also used : Destination(cz.metacentrum.perun.core.api.Destination) Task(cz.metacentrum.perun.taskslib.model.Task) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) Date(java.util.Date) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException)

Example 24 with Task

use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.

the class SchedulingPoolImpl method addToPool.

@Override
public int addToPool(Task task, DispatcherQueue dispatcherQueue) throws InternalErrorException {
    int engineId = (dispatcherQueue == null) ? -1 : dispatcherQueue.getClientID();
    if (task.getId() == 0) {
        // ExecService,Facility pair
        synchronized (tasksByServiceAndFacility) {
            if (!tasksByServiceAndFacility.containsKey(new Pair<Integer, Integer>(task.getExecServiceId(), task.getFacilityId()))) {
                log.debug("Adding new task to pool " + task);
                if (null == task.getStatus()) {
                    task.setStatus(TaskStatus.NONE);
                }
                try {
                    int id = taskManager.scheduleNewTask(task, engineId);
                    task.setId(id);
                } catch (InternalErrorException e) {
                    log.error("Error storing task " + task + " into database: " + e.getMessage());
                    throw new InternalErrorException("Could not assign id to newly created task", e);
                }
                tasksByServiceAndFacility.put(new Pair<Integer, Integer>(task.getExecServiceId(), task.getFacilityId()), task);
                tasksById.put(task.getId(), new Pair<Task, DispatcherQueue>(task, dispatcherQueue));
                List<Task> list = pool.get(task.getStatus());
                if (list == null) {
                    log.info("Making new list for task status " + task.getStatus().toString());
                    list = new ArrayList<Task>();
                    pool.put(task.getStatus(), list);
                }
                list.add(task);
            } else {
                log.debug("There already is task for given ExecService and Facility pair");
            }
        }
    } else {
        // weird - we should not be adding tasks with id present...
        synchronized (tasksById) {
            if (!tasksById.containsKey(task.getId())) {
                log.debug("Adding task to pool " + task);
                if (null == task.getStatus()) {
                    task.setStatus(TaskStatus.NONE);
                }
                tasksById.put(task.getId(), new Pair<Task, DispatcherQueue>(task, dispatcherQueue));
                tasksByServiceAndFacility.put(new Pair<Integer, Integer>(task.getExecServiceId(), task.getFacilityId()), task);
                List<Task> list = pool.get(task.getStatus());
                if (list == null) {
                    log.info("Making new list for task status " + task.getStatus().toString());
                    list = new ArrayList<Task>();
                    pool.put(task.getStatus(), list);
                }
                list.add(task);
            // pool.get(task.getStatus()).add(task);
            }
        }
        try {
            Task existingTask = taskManager.getTaskById(task.getId());
            if (existingTask == null) {
                taskManager.scheduleNewTask(task, engineId);
            } else {
                taskManager.updateTask(task);
            }
        } catch (InternalErrorException e) {
            log.error("Error storing task " + task + " into database: " + e.getMessage());
        }
    }
    return getSize();
}
Also used : Task(cz.metacentrum.perun.taskslib.model.Task) DispatcherQueue(cz.metacentrum.perun.dispatcher.jms.DispatcherQueue) InternalErrorException(cz.metacentrum.perun.core.api.exceptions.InternalErrorException) Pair(cz.metacentrum.perun.core.api.Pair)

Example 25 with Task

use of cz.metacentrum.perun.taskslib.model.Task in project perun by CESNET.

the class SchedulingPoolImpl method reloadTasks.

@Override
public void reloadTasks() {
    log.debug("Going to reload tasks from database...");
    this.clear();
    for (Pair<Task, Integer> pair : taskManager.listAllTasksAndClients()) {
        Task task = pair.getLeft();
        TaskStatus status = task.getStatus();
        if (status == null) {
            task.setStatus(TaskStatus.NONE);
        }
        /*
			if(task.getFacility().getName().equals("alcor.ics.muni.cz") ||
               task.getFacility().getName().equals("aldor.ics.muni.cz") ||
               task.getFacility().getName().equals("ascor.ics.muni.cz") ||
               task.getFacility().getName().equals("torque.ics.muni.cz") ||
               task.getFacility().getName().equals("nympha-cloud.zcu.cz")) {
            } else {
                    log.debug("Skipping task for facility {} not meant for testing.", task.getFacility().getName());
                    continue;
            }
            */
        if (!pool.get(task.getStatus()).contains(task)) {
            pool.get(task.getStatus()).add(task);
        }
        DispatcherQueue queue = dispatcherQueuePool.getDispatcherQueueByClient(pair.getRight());
        // XXX should this be synchronized too?
        tasksById.put(task.getId(), new Pair<Task, DispatcherQueue>(task, queue));
        tasksByServiceAndFacility.put(new Pair<Integer, Integer>(task.getExecServiceId(), task.getFacilityId()), task);
        // TODO: what about possible duplicates?
        log.debug("Added task " + task.toString() + " belonging to queue " + pair.getRight());
    }
    log.info("Pool contains: ");
    for (TaskStatus status : TaskStatus.class.getEnumConstants()) {
        log.info("  - {} tasks in state {}", pool.get(status).size(), status.toString());
    }
}
Also used : Task(cz.metacentrum.perun.taskslib.model.Task) DispatcherQueue(cz.metacentrum.perun.dispatcher.jms.DispatcherQueue) TaskStatus(cz.metacentrum.perun.taskslib.model.Task.TaskStatus)

Aggregations

Task (cz.metacentrum.perun.taskslib.model.Task)34 Date (java.util.Date)17 InternalErrorException (cz.metacentrum.perun.core.api.exceptions.InternalErrorException)13 ExecService (cz.metacentrum.perun.taskslib.model.ExecService)11 Test (org.junit.Test)7 DispatcherQueue (cz.metacentrum.perun.dispatcher.jms.DispatcherQueue)5 TaskStatus (cz.metacentrum.perun.taskslib.model.Task.TaskStatus)5 Destination (cz.metacentrum.perun.core.api.Destination)4 Facility (cz.metacentrum.perun.core.api.Facility)4 PrivilegeException (cz.metacentrum.perun.core.api.exceptions.PrivilegeException)4 AbstractEngineTest (cz.metacentrum.perun.engine.AbstractEngineTest)4 ArrayList (java.util.ArrayList)4 Pair (cz.metacentrum.perun.core.api.Pair)3 ServiceNotExistsException (cz.metacentrum.perun.core.api.exceptions.ServiceNotExistsException)3 PerunBean (cz.metacentrum.perun.core.api.PerunBean)2 FacilityNotExistsException (cz.metacentrum.perun.core.api.exceptions.FacilityNotExistsException)2 AbstractDispatcherTest (cz.metacentrum.perun.dispatcher.AbstractDispatcherTest)2 InvalidEventMessageException (cz.metacentrum.perun.engine.exceptions.InvalidEventMessageException)2 ExecutorEngineWorker (cz.metacentrum.perun.engine.scheduling.ExecutorEngineWorker)2 ExecutorEngineWorkerImpl (cz.metacentrum.perun.engine.scheduling.impl.ExecutorEngineWorkerImpl)2