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 + "]");
}
}
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); } }
* }
*/
}
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);
}
}
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();
}
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());
}
}
Aggregations