Skip to content

Commit

Permalink
Fix default setting for task binding
Browse files Browse the repository at this point in the history
The binding is now (correctly) determined from the task schedule:
recurring tasks with short interval are tightly bound, all the others
are bound loosely.
  • Loading branch information
mederly committed Sep 10, 2020
1 parent ce1abb4 commit 683ee1a
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 74 deletions.
Expand Up @@ -240,12 +240,12 @@ void modifyTask(String oid, Collection<? extends ItemDelta> modifications, Opera
* result with specified operation name.
*
* @param taskPrism Prism representation of the task
* @param operationName operation name to use as a root for new result in task
* @param operationName operation name to use as a root for new result in task -- IGNORED
* @return new Java representation of the task
* @throws SchemaException The provided taskType is not compliant to schema
*/
@NotNull
Task createTaskInstance(PrismObject<TaskType> taskPrism, String operationName, OperationResult parentResult) throws SchemaException;
Task createTaskInstance(PrismObject<TaskType> taskPrism, @Deprecated String operationName, OperationResult parentResult) throws SchemaException;

/**
* Returns a task with specified OID.
Expand Down
Expand Up @@ -94,8 +94,8 @@ public class RunningTaskQuartzImpl extends TaskQuartzImpl implements RunningTask

private Level originalProfilingLevel;

RunningTaskQuartzImpl(@NotNull TaskManagerQuartzImpl taskManager, PrismObject<TaskType> taskPrism, RepositoryService repositoryService) {
super(taskManager, taskPrism, repositoryService);
RunningTaskQuartzImpl(@NotNull TaskManagerQuartzImpl taskManager, PrismObject<TaskType> taskPrism) {
super(taskManager, taskPrism);
}

@Override
Expand Down
Expand Up @@ -826,11 +826,10 @@ public TaskQuartzImpl createTaskInstance() {

@Override
public TaskQuartzImpl createTaskInstance(String operationName) {
LightweightIdentifier taskIdentifier = generateTaskIdentifier();
return new TaskQuartzImpl(this, taskIdentifier, operationName);
return TaskQuartzImpl.createNew(this, operationName);
}

private LightweightIdentifier generateTaskIdentifier() {
LightweightIdentifier generateTaskIdentifier() {
return lightweightIdentifierGenerator.generate();
}

Expand All @@ -842,11 +841,11 @@ public TaskQuartzImpl createTaskInstance(PrismObject<TaskType> taskPrism, Operat

@Override
@NotNull
public TaskQuartzImpl createTaskInstance(PrismObject<TaskType> taskPrism, String operationName, OperationResult parentResult) throws SchemaException {
public TaskQuartzImpl createTaskInstance(PrismObject<TaskType> taskPrism, @Deprecated String operationName, OperationResult parentResult) throws SchemaException {
OperationResult result = parentResult.createMinorSubresult(DOT_INTERFACE + "createTaskInstance");
result.addParam("taskPrism", taskPrism);

TaskQuartzImpl task = new TaskQuartzImpl(this, taskPrism, repositoryService);
TaskQuartzImpl task = TaskQuartzImpl.createFromPrismObject(this, taskPrism);
task.resolveOwnerRef(result);
result.recordSuccessIfUnknown();
return task;
Expand Down Expand Up @@ -919,11 +918,6 @@ private void persist(Task task, OperationResult parentResult) {
taskImpl.setCategoryTransient(taskImpl.getCategoryFromHandler());
}

// Make sure that the task has repository service instance, so it can fully work as "persistent"
if (taskImpl.getRepositoryService() == null) {
taskImpl.setRepositoryService(repositoryService);
}

try {
CryptoUtil.encryptValues(protector, taskImpl.getLiveTaskObjectForNotRunningTasks());
addTaskToRepositoryAndQuartz(taskImpl, null, parentResult);
Expand Down Expand Up @@ -2621,7 +2615,7 @@ public RunningTaskQuartzImpl createRunningTask(Task task) {
return ((RunningTaskQuartzImpl) task);
} else {
PrismObject<TaskType> taskPrismObject = task.getUpdatedTaskObject();
return new RunningTaskQuartzImpl(this, taskPrismObject, repositoryService);
return new RunningTaskQuartzImpl(this, taskPrismObject);
}
}

Expand Down
Expand Up @@ -88,7 +88,6 @@
*/
public class TaskQuartzImpl implements InternalTaskInterface {

private static final TaskBinding DEFAULT_BINDING_TYPE = TaskBinding.TIGHT;
private static final int TIGHT_BINDING_INTERVAL_LIMIT = 10;

private final Object quartzAccess = new Object();
Expand All @@ -99,9 +98,9 @@ public class TaskQuartzImpl implements InternalTaskInterface {

private PrismObject<TaskType> taskPrism;

private PrismObject<UserType> requestee; // temporary information
private PrismObject<UserType> requestee; // temporary information

/*
/**
* Task result is stored here as well as in task prism.
*
* This one is the live value of this task's result. All operations working with this task
Expand All @@ -123,82 +122,79 @@ public class TaskQuartzImpl implements InternalTaskInterface {
protected OperationResult taskResult;

@NotNull protected final TaskManagerQuartzImpl taskManager;
protected RepositoryService repositoryService;
@NotNull protected final RepositoryService repositoryService;

private boolean recreateQuartzTrigger = false; // whether to recreate quartz trigger on next flushPendingModifications and/or synchronizeWithQuartz
/**
* Whether to recreate quartz trigger on next flushPendingModifications and/or synchronizeWithQuartz.
*/
private boolean recreateQuartzTrigger = false;

@NotNull // beware, we still have to synchronize on pendingModifications while iterating over it
@NotNull // beware, we still have to synchronize on pendingModifications while iterating over it
private final List<ItemDelta<?, ?>> pendingModifications = Collections.synchronizedList(new ArrayList<>());

/**
* Points where tracing is requested (for this task).
*/
private final Set<TracingRootType> tracingRequestedFor = new HashSet<>();
private TracingProfileType tracingProfile; // the profile to be used for tracing - it is copied into operation result at specified tracing point(s)

/**
* The profile to be used for tracing - it is copied into operation result at specified tracing point(s).
*/
private TracingProfileType tracingProfile;

private static final Trace LOGGER = TraceManager.getTrace(TaskQuartzImpl.class);

//region Constructors

private TaskQuartzImpl(@NotNull TaskManagerQuartzImpl taskManager) {
TaskQuartzImpl(@NotNull TaskManagerQuartzImpl taskManager, @NotNull PrismObject<TaskType> taskPrism) {
this.taskManager = taskManager;
this.repositoryService = taskManager.getRepositoryService();
this.taskPrism = taskPrism;
statistics = new Statistics(taskManager.getPrismContext());
setDefaults();
updateTaskResult();
}

/**
* Note: This constructor assumes that the task is transient.
* Creates a new task instance i.e. from scratch.
*
* @param operationName if null, default op. name will be used
*/
TaskQuartzImpl(@NotNull TaskManagerQuartzImpl taskManager, LightweightIdentifier taskIdentifier, String operationName) {
this(taskManager);
this.repositoryService = taskManager.getRepositoryService();
this.taskPrism = new TaskType(getPrismContext()).asPrismObject();

setTaskIdentifier(taskIdentifier.toString());
setExecutionStatusTransient(TaskExecutionStatus.RUNNABLE);
setRecurrenceStatusTransient(TaskRecurrence.SINGLE);
setBindingTransient(DEFAULT_BINDING_TYPE);
setProgressTransient(0L);
setObjectTransient(null);
createOrUpdateTaskResult(operationName, true);

setDefaults();
static TaskQuartzImpl createNew(@NotNull TaskManagerQuartzImpl taskManager, String operationName) {
TaskType taskBean = new TaskType(taskManager.getPrismContext())
.taskIdentifier(taskManager.generateTaskIdentifier().toString())
.executionStatus(TaskExecutionStatusType.RUNNABLE)
.recurrence(TaskRecurrenceType.SINGLE)
.progress(0L)
.result(createTaskResult(operationName));
return new TaskQuartzImpl(taskManager, taskBean.asPrismObject());
}

/**
* Assumes that the task is persistent
* <p>
* Creates a new task instance from provided task prism object.
*
* NOTE: if the result in prism is null, task result will be kept null as well (meaning it was not fetched from the repository).
*/
TaskQuartzImpl(@NotNull TaskManagerQuartzImpl taskManager, PrismObject<TaskType> taskPrism, RepositoryService repositoryService) {
this(taskManager);
this.repositoryService = repositoryService;
this.taskPrism = taskPrism;
createOrUpdateTaskResult(null, false);

setDefaults();
static TaskQuartzImpl createFromPrismObject(@NotNull TaskManagerQuartzImpl taskManager, PrismObject<TaskType> taskObject) {
return new TaskQuartzImpl(taskManager, taskObject);
}

private void setDefaults() {
if (getBinding() == null) {
setBindingTransient(DEFAULT_BINDING_TYPE);
setBindingTransient(bindingFromSchedule(getSchedule()));
}
}

//endregion

//region Result handling
private void createOrUpdateTaskResult(String operationName, boolean create) {
private void updateTaskResult() {
synchronized (prismAccess) {
OperationResultType resultInPrism = taskPrism.asObjectable().getResult();
if (resultInPrism == null && create) {
if (operationName == null) {
resultInPrism = createUnnamedTaskResult().createOperationResultType();
} else {
resultInPrism = new OperationResult(operationName).createOperationResultType();
}
taskPrism.asObjectable().setResult(resultInPrism);
}
if (resultInPrism != null) {
taskResult = OperationResult.createOperationResult(resultInPrism);
} else {
taskResult = null;
}
}
}
Expand All @@ -208,6 +204,9 @@ private void updateTaskPrismResult(PrismObject<TaskType> target) {
if (taskResult != null) {
target.asObjectable().setResult(taskResult.createOperationResultType());
target.asObjectable().setResultStatus(taskResult.getStatus().createStatusType());
} else {
target.asObjectable().setResult(null);
target.asObjectable().setResultStatus(null);
}
}
}
Expand Down Expand Up @@ -259,7 +258,7 @@ public PrismObject<TaskType> getUpdatedTaskObject() {
}

Task cloneAsStaticTask() {
return new TaskQuartzImpl(taskManager, getClonedTaskObject(), repositoryService);
return TaskQuartzImpl.createFromPrismObject(taskManager, getClonedTaskObject());
}

@NotNull
Expand All @@ -272,14 +271,10 @@ public PrismObject<TaskType> getClonedTaskObject() {
}
}

RepositoryService getRepositoryService() {
@NotNull RepositoryService getRepositoryService() {
return repositoryService;
}

void setRepositoryService(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
}

@Override
public boolean isRecreateQuartzTrigger() {
return recreateQuartzTrigger;
Expand Down Expand Up @@ -585,7 +580,6 @@ public OperationStatsType getStoredOperationStats() {
return getContainerableOrClone(TaskType.F_OPERATION_STATS);
}

@SuppressWarnings("WeakerAccess")
public void setOperationStats(OperationStatsType value) {
setContainerable(TaskType.F_OPERATION_STATS, value);
}
Expand All @@ -597,7 +591,6 @@ void setOperationStatsTransient(OperationStatsType value) {
/*
* expectedTotal
*/

@Override
@Nullable
public Long getExpectedTotal() {
Expand Down Expand Up @@ -814,14 +807,10 @@ private static void storeExtensionDeltas(List<ItemDeltaType> result, Collection<

// derives default binding form schedule
private static TaskBinding bindingFromSchedule(ScheduleType schedule) {
if (schedule == null) {
return DEFAULT_BINDING_TYPE;
} else if (schedule.getInterval() != null && schedule.getInterval() != 0) {
return schedule.getInterval() <= TIGHT_BINDING_INTERVAL_LIMIT ? TaskBinding.TIGHT : TaskBinding.LOOSE;
} else if (StringUtils.isNotEmpty(schedule.getCronLikePattern())) {
return TaskBinding.LOOSE;
if (schedule != null && schedule.getInterval() != null && schedule.getInterval() > 0 && schedule.getInterval() <= TIGHT_BINDING_INTERVAL_LIMIT) {
return TaskBinding.TIGHT;
} else {
return DEFAULT_BINDING_TYPE;
return TaskBinding.LOOSE;
}
}

Expand Down Expand Up @@ -2144,7 +2133,7 @@ public void refresh(OperationResult parentResult) throws ObjectNotFoundException
throw ex;
}
this.taskPrism = repoObj;
createOrUpdateTaskResult(null, false);
updateTaskResult();
setDefaults();
resolveOwnerRef(result);
result.recordSuccess();
Expand Down Expand Up @@ -2403,8 +2392,16 @@ public OperationStatsType getAggregatedLiveOperationStats() {
return statistics.getAggregatedLiveOperationStats(emptyList());
}

private static OperationResultType createTaskResult(String operationName) {
if (operationName == null) {
return createUnnamedTaskResult().createOperationResultType();
} else {
return new OperationResult(operationName).createOperationResultType();
}
}

@NotNull
public OperationResult createUnnamedTaskResult() {
public static OperationResult createUnnamedTaskResult() {
return new OperationResult(DOT_INTERFACE + "run");
}

Expand Down

0 comments on commit 683ee1a

Please sign in to comment.