Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Dec 2, 2016
2 parents 4aec6e5 + 6dacf06 commit ab75ee2
Show file tree
Hide file tree
Showing 13 changed files with 239 additions and 60 deletions.
Expand Up @@ -168,6 +168,7 @@ TaskType loadTaskType(String taskOid, Task operationTask, OperationResult result
TaskType.F_SUBTASK,
TaskType.F_NODE_AS_OBSERVED,
TaskType.F_NEXT_RUN_START_TIMESTAMP,
TaskType.F_NEXT_RETRY_TIMESTAMP,
new ItemPath(TaskType.F_WORKFLOW_CONTEXT, WfContextType.F_WORK_ITEM));
options.addAll(GetOperationOptions.resolveItemsNamed(
new ItemPath(TaskType.F_WORKFLOW_CONTEXT, WfContextType.F_REQUESTER_REF)
Expand Down
Expand Up @@ -22,12 +22,10 @@
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule;
import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer;
import com.evolveum.midpoint.prism.query.*;
import com.evolveum.midpoint.prism.query.builder.QueryBuilder;
import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry;
import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
Expand All @@ -39,7 +37,6 @@
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.application.AuthorizationAction;
Expand Down Expand Up @@ -658,26 +655,41 @@ private String createObjectRef(IModel<TaskDto> taskModel) {

private String createScheduledToRunAgain(IModel<TaskDto> taskModel) {
TaskDto task = taskModel.getObject();
Long time = task.getScheduledToStartAgain();
boolean runnable = task.getRawExecutionStatus() == TaskExecutionStatus.RUNNABLE;
Long scheduledAfter = task.getScheduledToStartAgain();
Long retryAfter = runnable ? task.getRetryAfter() : null;

boolean runnable = task.getRawExecutionStatus() == TaskExecutionStatus.RUNNABLE;

if (time == null) {
return "";
} else if (time == 0) {
if (scheduledAfter == null) {
if (retryAfter == null || retryAfter <= 0) {
return "";
}
} else if (scheduledAfter == TaskDto.NOW) { // TODO what about retryTime?
return getString(runnable ? "pageTasks.now" : "pageTasks.nowForNotRunningTasks");
} else if (time == -1) {
} else if (scheduledAfter == TaskDto.RUNS_CONTINUALLY) { // retryTime is probably null here
return getString("pageTasks.runsContinually");
} else if (time == -2) {
} else if (scheduledAfter == TaskDto.ALREADY_PASSED && retryAfter == null) {
return getString(runnable ? "pageTasks.alreadyPassed" : "pageTasks.alreadyPassedForNotRunningTasks");
}

String key = runnable ? "pageTasks.in" : "pageTasks.inForNotRunningTasks";
long displayTime;
boolean displayAsRetry;
if (retryAfter != null && retryAfter > 0 && (scheduledAfter == null || scheduledAfter < 0 || retryAfter < scheduledAfter)) {
displayTime = retryAfter;
displayAsRetry = true;
} else {
displayTime = scheduledAfter;
displayAsRetry = false;
}

String key;
if (runnable) {
key = displayAsRetry ? "pageTasks.retryIn" : "pageTasks.in";
} else {
key = "pageTasks.inForNotRunningTasks";
}

//todo i18n
return PageBase.createStringResourceStatic(this, key, DurationFormatUtils.formatDurationWords(time, true, true)).getString();
// return new StringResourceModel(key, this, null, null,
// DurationFormatUtils.formatDurationWords(time, true, true)).getString();
return PageBase.createStringResourceStatic(this, key, DurationFormatUtils.formatDurationWords(displayTime, true, true)).getString();
}

private String createProgress(IModel<TaskDto> taskModel) {
Expand Down
Expand Up @@ -35,6 +35,10 @@
<td><wicket:message key="pageTaskEdit.nextRun"/></td>
<td><span wicket:id="nextRun" /> <span class="small" wicket:id="nextRunIn" /></td>
</tr>
<tr wicket:id="nextRetryContainer">
<td><wicket:message key="pageTaskEdit.nextRetry"/></td>
<td><span wicket:id="nextRetry" /> <span class="small" wicket:id="nextRetryIn" /></td>
</tr>
</table>
</div>
</div>
Expand Down
Expand Up @@ -72,6 +72,9 @@ public class TaskSchedulingTabPanel extends AbstractObjectTabPanel<TaskType> imp
public static final String ID_NEXT_RUN_CONTAINER = "nextRunContainer";
public static final String ID_NEXT_RUN = "nextRun";
public static final String ID_NEXT_RUN_IN = "nextRunIn";
public static final String ID_NEXT_RETRY_CONTAINER = "nextRetryContainer";
public static final String ID_NEXT_RETRY = "nextRetry";
public static final String ID_NEXT_RETRY_IN = "nextRetryIn";

public static final String ID_SCHEDULING_TABLE = "schedulingTable";
public static final String ID_RECURRING_CONTAINER = "recurringContainer";
Expand Down Expand Up @@ -223,6 +226,46 @@ public String getObject() {
nextRunContainer.add(nextRunIn);
nextRunContainer.add(parentPage.createVisibleIfAccessible(TaskType.F_NEXT_RUN_START_TIMESTAMP));
add(nextRunContainer);

WebMarkupContainer nextRetryContainer = new WebMarkupContainer(ID_NEXT_RETRY_CONTAINER);
Label nextRetry = new Label(ID_NEXT_RETRY, new AbstractReadOnlyModel<String>() {
@Override
public String getObject() {
TaskDto dto = taskDtoModel.getObject();
if (dto.getNextRetryTimeLong() == null) {
return "-";
} else {
return WebComponentUtil.formatDate(new Date(dto.getNextRetryTimeLong()));
}
}
});
nextRetryContainer.add(nextRetry);

Label nextRetryIn = new Label(ID_NEXT_RETRY_IN, new AbstractReadOnlyModel<String>() {
@Override
public String getObject() {
TaskDto dto = taskDtoModel.getObject();
if (dto.getNextRetryTimeLong() == null /* || (dto.isRecurring() && dto.isBound() && dto.isRunning()) */ ) {
return "";
} else {
long currentTime = System.currentTimeMillis();
final long in = dto.getNextRetryTimeLong() - currentTime;
if (in >= 0) {
return getString("TaskStatePanel.message.in", DurationFormatUtils.formatDurationWords(in, true, true));
} else {
return "";
}
}
}
});
nextRetryContainer.add(nextRetryIn);
nextRetryContainer.add(new VisibleEnableBehaviour() {
@Override
public boolean isVisible() {
return taskDtoModel.getObject().getNextRetryTimeLong() != null;
}
});
add(nextRetryContainer);
}

private void initLayoutForSchedulingTable() {
Expand Down
Expand Up @@ -33,7 +33,8 @@ public boolean computeBasicVisible(PageTaskEdit parentPage) {
public boolean computeSchedulingVisible(PageTaskEdit parentPage) {
schedulingVisible = (parentPage.isShowAdvanced() || !parentPage.getTaskDto().isWorkflow())
&& parentPage.isReadableSomeOf(
TaskType.F_LAST_RUN_START_TIMESTAMP, TaskType.F_LAST_RUN_FINISH_TIMESTAMP, TaskType.F_NEXT_RUN_START_TIMESTAMP,
TaskType.F_LAST_RUN_START_TIMESTAMP, TaskType.F_LAST_RUN_FINISH_TIMESTAMP,
TaskType.F_NEXT_RUN_START_TIMESTAMP, TaskType.F_NEXT_RETRY_TIMESTAMP,
TaskType.F_RECURRENCE, TaskType.F_BINDING, TaskType.F_SCHEDULE, TaskType.F_THREAD_STOP_ACTION);

return schedulingVisible;
Expand Down
Expand Up @@ -84,7 +84,7 @@ public class TaskDto extends Selectable implements InlineMenuable {
public static final String CLASS_DOT = TaskDto.class.getName() + ".";
public static final String OPERATION_NEW = CLASS_DOT + "new";

private static final transient Trace LOGGER = TraceManager.getTrace(TaskDto.class);
private static final transient Trace LOGGER = TraceManager.getTrace(TaskDto.class);
public static final String F_MODEL_OPERATION_STATUS = "modelOperationStatus";
public static final String F_SUBTASKS = "subtasks";
public static final String F_NAME = "name";
Expand Down Expand Up @@ -121,6 +121,9 @@ public class TaskDto extends Selectable implements InlineMenuable {
public static final String F_EXECUTE_IN_RAW_MODE = "executeInRawMode";
public static final String F_PROCESS_INSTANCE_ID = "processInstanceId";
public static final String F_HANDLER_DTO = "handlerDto";
public static final long RUNS_CONTINUALLY = -1L;
public static final long ALREADY_PASSED = -2L;
public static final long NOW = 0L;

private TaskType taskType;

Expand Down Expand Up @@ -628,14 +631,23 @@ public Long getNextRunStartTimeLong() {
return xgc2long(taskType.getNextRunStartTimestamp());
}

public Long getNextRetryTimeLong() {
return xgc2long(taskType.getNextRetryTimestamp());
}

public Long getRetryAfter() {
Long retryAt = getNextRetryTimeLong();
return retryAt != null ? retryAt - System.currentTimeMillis() : null;
}

public Long getScheduledToStartAgain() {
long current = System.currentTimeMillis();

if (getExecution() == TaskDtoExecutionStatus.RUNNING) {
if (!currentEditableState.recurring) {
return null;
} else if (currentEditableState.bound) {
return -1L; // runs continually; todo provide some information also in this case
return RUNS_CONTINUALLY; // runs continually; todo provide some information also in this case
}
}

Expand All @@ -647,9 +659,9 @@ public Long getScheduledToStartAgain() {
if (nextRunStartTimeLong > current + 1000) {
return nextRunStartTimeLong - System.currentTimeMillis();
} else if (nextRunStartTimeLong < current - 60000) {
return -2L; // already passed
return ALREADY_PASSED;
} else {
return 0L; // now
return NOW;
}
}

Expand Down Expand Up @@ -1086,4 +1098,5 @@ public TaskEditableState getCurrentEditableState() {
public TaskEditableState getOriginalEditableState() {
return originalEditableState;
}

}
Expand Up @@ -81,6 +81,7 @@ public Iterator<? extends TaskDto> internalIterator(long first, long count) {
}
if (options.isGetNextRunStartTime()) {
propertiesToGet.add(TaskType.F_NEXT_RUN_START_TIMESTAMP);
propertiesToGet.add(TaskType.F_NEXT_RETRY_TIMESTAMP);
}
Collection<SelectorOptions<GetOperationOptions>> searchOptions =
GetOperationOptions.createRetrieveAttributesOptions(propertiesToGet.toArray(new QName[0]));
Expand Down
Expand Up @@ -718,6 +718,7 @@ operation.com.evolveum.midpoint.task.api.TaskManager.createTaskInstance=Create t
operation.com.evolveum.midpoint.task.api.TaskManager.deactivateServiceThreads=Deactivate local service threads (Task)
operation.com.evolveum.midpoint.task.api.TaskManager.deleteTask=Delete task (Task)
operation.com.evolveum.midpoint.task.api.TaskManager.getNextRunStartTime=Get next task run start time (Task)
operation.com.evolveum.midpoint.task.api.TaskManager.getNextStartTimes=Get next task start times (Task)
operation.com.evolveum.midpoint.task.api.TaskManager.getTask=Get task (Task)
operation.com.evolveum.midpoint.task.api.TaskManager.onTaskCreate=Task creation listener (Task)
operation.com.evolveum.midpoint.task.api.TaskManager.onTaskDelete=Task deletion listener (Task)
Expand Down Expand Up @@ -1917,6 +1918,7 @@ pageTaskEdit.misfire=Misfire action
pageTaskEdit.modelOperationStatusLabel=Model operation status
pageTaskEdit.name=Task name
pageTaskEdit.nextRun=Next scheduled task run
pageTaskEdit.nextRetry=Next retry
pageTaskEdit.notStartAfter=Do not start after
pageTaskEdit.notStartBefore=Do not start before
pageTaskEdit.objectClass=Object class
Expand Down Expand Up @@ -2021,6 +2023,7 @@ pageTask.scheduleValidation.noInterval='Schedule interval' must be specified.
pageTasks.dialog.title.confirmDelete=Confirm delete
pageTasks.inForNotRunningTasks=(in {0})
pageTasks.in=in {0}
pageTasks.retryIn=retry in {0}
pageTasks.message.alreadyResumed=Task '{0}' can't be resumed, it's already running or closed.
pageTasks.message.alreadySuspended=Task '{0}' is already suspended or closed.
pageTasks.message.couldntCreateQuery=Couldn't create query for task list.
Expand Down
Expand Up @@ -146,6 +146,7 @@ public static boolean hasToLoadPath(QName itemName, Collection<SelectorOptions<G
new ItemPath(TaskType.F_SUBTASK),
new ItemPath(TaskType.F_NODE_AS_OBSERVED),
new ItemPath(TaskType.F_NEXT_RUN_START_TIMESTAMP),
new ItemPath(TaskType.F_NEXT_RETRY_TIMESTAMP),
new ItemPath(TaskType.F_WORKFLOW_CONTEXT, WfContextType.F_WORK_ITEM),
new ItemPath(LookupTableType.F_ROW),
new ItemPath(AccessCertificationCampaignType.F_CASE)));
Expand Down
Expand Up @@ -1395,12 +1395,32 @@
<xsd:element name="nextRunStartTimestamp" type="xsd:dateTime" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
The time when the task should start again. (Null if no further execution is scheduled.)
The time when the task should start again, according to the task's defined schedule.
(Null if no further execution is scheduled.)
Ad-hoc (retry) run times, like those stemming from unsatisfied execution constraints, are NOT
considered here. They are covered by nextRetryTimestamp property.

TRANSIENT. This value is not stored in the repo, it is queried dynamically.
(It is currently not possible to use it for filtering or sorting.)
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="nextRetryTimestamp" type="xsd:dateTime" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
If the start of a task was delayed (typically because of unsatisfied execution constraints),
the planned retry time is reported here.

EXPERIMENTAL.

TRANSIENT. This value is not stored in the repo, it is queried dynamically.
(It is currently not possible to use it for filtering or sorting.)
</xsd:documentation>
<xsd:appinfo>
<a:since>3.5</a:since>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="progress" type="xsd:long" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expand Down

0 comments on commit ab75ee2

Please sign in to comment.