/*
* Copyright (c) 2010-2013 Evolveum
*
* 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.evolveum.midpoint.task.quartzimpl.handlers;
import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismPropertyDefinition;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.*;
import com.evolveum.midpoint.task.api.TaskRunResult.TaskRunResultStatus;
import com.evolveum.midpoint.task.quartzimpl.TaskManagerQuartzImpl;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import java.util.List;
/**
* @author Pavol Mederly
*
*/
public class NoOpTaskHandler implements TaskHandler {
private static final transient Trace LOGGER = TraceManager.getTrace(NoOpTaskHandler.class);
public static final String HANDLER_URI = "http://midpoint.evolveum.com/xml/ns/public/task/noop/handler-3";
private static NoOpTaskHandler instance = null;
private TaskManagerQuartzImpl taskManagerImpl;
private NoOpTaskHandler() {}
public static void instantiateAndRegister(TaskManager taskManager) {
if (instance == null)
instance = new NoOpTaskHandler();
taskManager.registerHandler(HANDLER_URI, instance);
instance.taskManagerImpl = (TaskManagerQuartzImpl) taskManager;
}
@Override
public TaskRunResult run(Task task) {
long progress = task.getProgress();
OperationResult opResult = new OperationResult(NoOpTaskHandler.class.getName()+".run");
TaskRunResult runResult = new TaskRunResult();
runResult.setOperationResult(opResult);
runResult.setRunResultStatus(TaskRunResultStatus.FINISHED); // would be overwritten when problem is encountered
PrismContainer taskExtension = task.getExtension();
PrismProperty<Integer> delayProp = taskExtension != null ? taskExtension.findProperty(SchemaConstants.NOOP_DELAY_QNAME) : null;
PrismProperty<Integer> stepsProp = taskExtension != null ? taskExtension.findProperty(SchemaConstants.NOOP_STEPS_QNAME) : null;
PrismPropertyDefinition delayPropDef = taskManagerImpl.getPrismContext().getSchemaRegistry().findPropertyDefinitionByElementName(SchemaConstants.NOOP_DELAY_QNAME);
PrismPropertyDefinition stepsPropDef = taskManagerImpl.getPrismContext().getSchemaRegistry().findPropertyDefinitionByElementName(SchemaConstants.NOOP_STEPS_QNAME);
try {
if (delayProp != null)
delayProp.applyDefinition(delayPropDef);
if (stepsProp != null)
stepsProp.applyDefinition(stepsPropDef);
} catch (SchemaException se) {
LoggingUtils.logUnexpectedException(LOGGER, "Cannot apply Prism definition to delay and/or steps property, exiting immediately.", se);
opResult.recordFatalError("Cannot apply Prism definition to delay and/or steps property, exiting immediately.", se);
runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR);
return runResult;
}
long delay;
if (delayProp != null && !delayProp.getValues().isEmpty())
delay = delayProp.getValues().get(0).getValue();
else
delay = 0;
int steps;
if (stepsProp != null && !stepsProp.getValues().isEmpty())
steps = stepsProp.getValues().get(0).getValue();
else
steps = 1;
LOGGER.info("NoOpTaskHandler run starting; progress = " + progress + ", steps to be executed = " + steps + ", delay for one step = " + delay + " in task " + task.getName());
for (int i = 0; i < steps; i++) {
LOGGER.info("NoOpTaskHandler: executing step " + (i+1) + " of " + steps + " in task " + task.getName());
// this strange construction is used to simulate non-interruptible execution of the task
long sleepUntil = System.currentTimeMillis() + delay;
for (;;) {
long delta = sleepUntil - System.currentTimeMillis();
if (delta > 0) {
try {
Thread.sleep(delta);
} catch (InterruptedException e) {
}
} else {
break; // we have slept enough
}
}
progress++;
try {
task.setProgressImmediate(progress, opResult);
} catch (ObjectNotFoundException e) {
LoggingUtils.logException(LOGGER, "Cannot report progress for task {} because the task does not exist anymore.", e, task);
runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR);
break;
} catch (SchemaException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Cannot report progress for task {} because of schema exception.", e, task);
runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR);
break;
}
if (!task.canRun()) {
LOGGER.info("NoOpTaskHandler: got a shutdown request, finishing task " + task.getName());
break;
}
}
opResult.computeStatusIfUnknown();
runResult.setProgress(progress);
LOGGER.info("NoOpTaskHandler run finishing; progress = " + progress + " in task " + task.getName());
return runResult;
}
@Override
public Long heartbeat(Task task) {
return null; // not to overwrite progress information!
}
@Override
public void refreshStatus(Task task) {
}
@Override
public String getCategoryName(Task task) {
return TaskCategory.DEMO;
}
@Override
public List<String> getCategoryNames() {
return null;
}
}