Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
KaterynaHonchar committed May 3, 2018
2 parents 24598c4 + d8a9de2 commit 75de199
Show file tree
Hide file tree
Showing 18 changed files with 241 additions and 42 deletions.
Expand Up @@ -31,6 +31,7 @@
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils;
import com.evolveum.midpoint.model.api.*;
import com.evolveum.midpoint.model.api.expr.MidpointFunctions;
import com.evolveum.midpoint.model.api.validator.ResourceValidator;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.*;
Expand Down Expand Up @@ -291,6 +292,9 @@ public abstract class PageBase extends WebPage implements ModelServiceLocator {
@SpringBean
private CacheDispatcher cacheDispatcher;

@SpringBean
private MidpointFunctions midpointFunctions;

private List<Breadcrumb> breadcrumbs;

private boolean initialized = false;
Expand Down Expand Up @@ -451,6 +455,10 @@ public LocalizationService getLocalizationService() {
return localizationService;
}

public MidpointFunctions getMidpointFunctions() {
return midpointFunctions;
}

public PrismContext getPrismContext() {
return getMidpointApplication().getPrismContext();
}
Expand Down
Expand Up @@ -120,6 +120,7 @@ public class PageTasks extends PageAdminTasks implements Refreshable {
private static final String OPERATION_RESUME_TASK = DOT_CLASS + "resumeTask";
private static final String OPERATION_DELETE_TASKS = DOT_CLASS + "deleteTasks";
private static final String OPERATION_RECONCILE_WORKERS = DOT_CLASS + "reconcileWorkers";
private static final String OPERATION_DELETE_WORKERS_AND_WORK_STATE = DOT_CLASS + "deleteWorkersAndWorkState";
private static final String OPERATION_DELETE_ALL_CLOSED_TASKS = DOT_CLASS + "deleteAllClosedTasks";
private static final String OPERATION_SCHEDULE_TASKS = DOT_CLASS + "scheduleTasks";
private static final String OPERATION_DELETE_NODES = DOT_CLASS + "deleteNodes";
Expand Down Expand Up @@ -956,6 +957,33 @@ public IModel<String> getConfirmationMessageModel() {
return PageTasks.this.getTaskConfirmationMessageModel((ColumnMenuAction) getAction(), actionName);
}
});
items.add(new InlineMenuItem(createStringResource("pageTasks.button.deleteWorkersAndWorkState"), false,
new ColumnMenuAction<TaskDto>() {

@Override
public void onClick(AjaxRequestTarget target) {
if (getRowModel() == null) {
throw new UnsupportedOperationException();
} else {
TaskDto rowDto = getRowModel().getObject();
deleteWorkersAndWorkState(target, rowDto);
}
}
}) {

private static final long serialVersionUID = 1L;

@Override
public boolean isShowConfirmationDialog() {
return PageTasks.this.isTaskShowConfirmationDialog((ColumnMenuAction) getAction());
}

@Override
public IModel<String> getConfirmationMessageModel() {
String actionName = createStringResource("pageTasks.message.deleteWorkersAndWorkState").getString();
return PageTasks.this.getTaskConfirmationMessageModel((ColumnMenuAction) getAction(), actionName);
}
});
}
}
if (isHeader) {
Expand Down Expand Up @@ -1794,6 +1822,22 @@ private void resumeCoordinatorOnly(AjaxRequestTarget target, @NotNull TaskDto ta
refreshTables(target);
}

private void deleteWorkersAndWorkState(AjaxRequestTarget target, @NotNull TaskDto task) {
Task opTask = createSimpleTask(OPERATION_DELETE_WORKERS_AND_WORK_STATE);
OperationResult result = opTask.getResult();
try {
getTaskService().deleteWorkersAndWorkState(task.getOid(), WAIT_FOR_TASK_STOP, opTask, result);
result.computeStatus();
} catch (ObjectNotFoundException | SchemaException | SecurityViolationException | ExpressionEvaluationException | RuntimeException | CommunicationException | ConfigurationException e) {
result.recordFatalError("Couldn't delete workers and the work state of the coordinator", e); // todo i18n
}
showResult(result);

TaskDtoProvider provider = (TaskDtoProvider) getTaskTable().getDataTable().getDataProvider();
provider.clearCache();
refreshTables(target);
}

private static class SearchFragment extends Fragment {

public SearchFragment(String id, String markupId, MarkupContainer markupProvider,
Expand Down
Expand Up @@ -881,6 +881,8 @@ operation.com.evolveum.midpoint.web.page.admin.server.PageTasks.stopSchedulersAn
operation.com.evolveum.midpoint.web.page.admin.server.PageTasks.stopSchedulers=Stop schedulers (Gui)
operation.com.evolveum.midpoint.web.page.admin.server.PageTasks.suspendTasks=Suspend tasks (Gui)
operation.com.evolveum.midpoint.web.page.admin.server.PageTasks.synchronizeTasks=Synchronize tasks (Gui)
operation.com.evolveum.midpoint.web.page.admin.server.PageTasks.deleteWorkersAndWorkState=Delete workers and work state (Gui)
operation.com.evolveum.midpoint.web.page.admin.server.PageTasks.reconcileWorkers=Reconcile workers (Gui)
operation.com.evolveum.midpoint.web.page.admin.users.component.TreeTablePanel.deleteObject=Delete object (Gui)
operation.com.evolveum.midpoint.web.page.admin.users.component.TreeTablePanel.deleteObjects=Delete objects (Gui)
operation.com.evolveum.midpoint.web.page.admin.users.component.TreeTablePanel.moveObject=Move object (Gui)
Expand Down Expand Up @@ -2139,6 +2141,7 @@ pageTasks.button.deactivateServiceThreads=Stop all threads
pageTasks.button.deleteNode=Delete
pageTasks.button.deleteTask=Delete
pageTasks.button.reconcileWorkers=Reconcile workers
pageTasks.button.deleteWorkersAndWorkState=Delete workers and work state
pageTasks.button.suspendCoordinatorOnly=Suspend (coordinator only)
pageTasks.button.resumeCoordinatorOnly=Resume (coordinator only)
pageTasks.button.deleteAllClosedTasks=Delete all closed tasks
Expand Down Expand Up @@ -2176,6 +2179,7 @@ pageTasks.message.resumeAction=resume
pageTasks.message.runNowAction=run now
pageTasks.message.deleteAction=delete
pageTasks.message.reconcileWorkersAction=reconcile workers of
pageTasks.message.deleteWorkersAndWorkState=delete workers and work state of
pageTasks.message.deleteAllClosedTasksAction=delete all closed tasks
pageTasks.message.startAction=start
pageTasks.message.scheduleTaskAction=schedule task
Expand Down
Expand Up @@ -198,5 +198,11 @@ public interface TaskService {
void reconcileWorkers(String oid, Task opTask, OperationResult result)
throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException,
ConfigurationException, ExpressionEvaluationException, ObjectAlreadyExistsException;


void deleteWorkersAndWorkState(String coordinatorOid, long subtasksWaitTime, Task operationTask, OperationResult parentResult)
throws SecurityViolationException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException,
CommunicationException, ConfigurationException;

//endregion
}
Expand Up @@ -1903,6 +1903,14 @@ public void reconcileWorkers(String oid, Task opTask, OperationResult result)
taskManager.reconcileWorkers(oid, null, result);
}

@Override
public void deleteWorkersAndWorkState(String coordinatorOid, long subtasksWaitTime, Task operationTask, OperationResult parentResult)
throws SecurityViolationException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException,
CommunicationException, ConfigurationException {
securityEnforcer.authorize(AuthorizationConstants.AUTZ_ALL_URL, null, AuthorizationParameters.EMPTY, null, operationTask, parentResult);
taskManager.deleteWorkersAndWorkState(coordinatorOid, subtasksWaitTime, parentResult);
}

@Override
public List<String> getAllTaskCategories() {
return taskManager.getAllTaskCategories();
Expand Down
Expand Up @@ -77,8 +77,8 @@ protected AbstractSearchIterativeResultHandler<ObjectType> createHandler(TaskRun
executeScriptProperty.getValue().getValue().getScriptingExpression() == null) {
throw new IllegalStateException("There's no script to be run in task " + coordinatorTask + " (property " + SchemaConstants.SE_EXECUTE_SCRIPT + ")");
}
ExecuteScriptType executeScriptRequest = executeScriptProperty.getRealValue();
if (executeScriptRequest.getInput() != null && !executeScriptRequest.getInput().getValue().isEmpty()) {
ExecuteScriptType executeScriptRequestTemplate = executeScriptProperty.getRealValue();
if (executeScriptRequestTemplate.getInput() != null && !executeScriptRequestTemplate.getInput().getValue().isEmpty()) {
LOGGER.warn("Ignoring input values in executeScript data in task {}", coordinatorTask);
}

Expand All @@ -87,6 +87,7 @@ protected AbstractSearchIterativeResultHandler<ObjectType> createHandler(TaskRun
@Override
protected boolean handleObject(PrismObject<ObjectType> object, Task workerTask, OperationResult result) {
try {
ExecuteScriptType executeScriptRequest = executeScriptRequestTemplate.clone();
executeScriptRequest.setInput(new ValueListType().value(object.asObjectable()));
ScriptExecutionResult executionResult = scriptingService.evaluateExpression(executeScriptRequest, emptyMap(), workerTask, result);
LOGGER.debug("Execution output: {} item(s)", executionResult.getDataOutput().size());
Expand All @@ -96,7 +97,6 @@ protected boolean handleObject(PrismObject<ObjectType> object, Task workerTask,
result.recordFatalError("Couldn't execute script: " + e.getMessage(), e);
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't execute script", e);
}
executeScriptRequest.setInput(null); // to avoid warnings above (during next bucket processing)
return true;
}
};
Expand Down
Expand Up @@ -789,6 +789,9 @@ public void handlePropesedShadowError(ProvisioningContext ctx, PrismObject<Shado
// e.g. recording the error in the shadow.
// Anyway, if this is alreadyExistsException we need to remove the shadow otherwise it will
// lead to duplicities.
if (proposedShadowOid == null) {
return;
}
try {
repositoryService.deleteObject(ShadowType.class, proposedShadowOid, parentResult);
} catch (ObjectNotFoundException e) {
Expand Down
Expand Up @@ -563,7 +563,7 @@ public void finishHandler(OperationResult parentResult) throws ObjectNotFoundExc

@NotNull
@Override
public List<Task> listSubtasks(OperationResult parentResult) throws SchemaException {
public List<Task> listSubtasks(boolean persistentOnly, OperationResult parentResult) throws SchemaException {
throw new UnsupportedOperationException("not implemented yet.");
}

Expand Down Expand Up @@ -649,7 +649,7 @@ public void addExtensionReference(PrismReference reference) throws SchemaExcepti
}

@Override
public List<Task> listSubtasksDeeply(OperationResult result) throws SchemaException {
public List<Task> listSubtasksDeeply(boolean persistentOnly, OperationResult result) throws SchemaException {
throw new UnsupportedOperationException("not implemented yet.");
}

Expand Down
Expand Up @@ -838,7 +838,12 @@ void setResultImmediate(OperationResult result, OperationResult parentResult)
* @throws SchemaException
*/
@NotNull
List<Task> listSubtasks(OperationResult parentResult) throws SchemaException;
default List<Task> listSubtasks(OperationResult parentResult) throws SchemaException {
return listSubtasks(false, parentResult);
}

@NotNull
List<Task> listSubtasks(boolean persistentOnly, OperationResult parentResult) throws SchemaException;

/**
* List all the subtasks of a given task, i.e. whole task tree rooted at the current task.
Expand All @@ -848,7 +853,11 @@ void setResultImmediate(OperationResult result, OperationResult parentResult)
* @return
* @throws SchemaException
*/
List<Task> listSubtasksDeeply(OperationResult result) throws SchemaException;
default List<Task> listSubtasksDeeply(OperationResult result) throws SchemaException {
return listSubtasksDeeply(false, result);
}

List<Task> listSubtasksDeeply(boolean persistentOnly, OperationResult result) throws SchemaException;

/**
* Lists all explicit dependents, i.e. tasks that wait for the completion of this tasks (that depend on it).
Expand Down
Expand Up @@ -418,6 +418,9 @@ void resumeTaskTree(String coordinatorOid, OperationResult parentResult)
void reconcileWorkers(String coordinatorOid, WorkersReconciliationOptions options, OperationResult parentResult)
throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException;

void deleteWorkersAndWorkState(String coordinatorOid, long subtasksWaitTime, OperationResult parentResult)
throws SchemaException, ObjectNotFoundException;

/**
* TODO is this method really necessary?
*/
Expand Down
Expand Up @@ -375,7 +375,7 @@ public boolean suspendTaskTree(String rootTaskOid, long waitTime, OperationResul

try {
TaskQuartzImpl root = getTask(rootTaskOid, result);
List<Task> subtasks = root.listSubtasksDeeply(parentResult);
List<Task> subtasks = root.listSubtasksDeeply(true, parentResult);
List<String> oidsToSuspend = new ArrayList<>(subtasks.size() + 1);
oidsToSuspend.add(rootTaskOid);
for (Task subtask : subtasks) {
Expand All @@ -397,7 +397,7 @@ public void resumeTaskTree(String rootTaskOid, OperationResult parentResult) thr

try {
TaskQuartzImpl root = getTask(rootTaskOid, result);
List<Task> subtasks = root.listSubtasks(parentResult);
List<Task> subtasks = root.listSubtasks(true, parentResult);
List<String> oidsToResume = new ArrayList<>(subtasks.size() + 1);
if (root.getExecutionStatus() == TaskExecutionStatus.SUSPENDED) {
oidsToResume.add(rootTaskOid);
Expand Down Expand Up @@ -432,6 +432,22 @@ public void reconcileWorkers(String coordinatorTaskOid, WorkersReconciliationOpt
}
}

@Override
public void deleteWorkersAndWorkState(String coordinatorTaskOid, long subtasksWaitTime, OperationResult parentResult)
throws SchemaException, ObjectNotFoundException {
OperationResult result = parentResult.createSubresult(DOT_INTERFACE + "deleteWorkersAndWorkState");
result.addParam("coordinatorTaskOid", coordinatorTaskOid);
result.addParam("subtasksWaitTime", subtasksWaitTime);
try {
workersManager.deleteWorkersAndWorkState(coordinatorTaskOid, subtasksWaitTime, result);
} catch (Throwable t) {
result.recordFatalError("Couldn't delete workers and work state", t);
throw t;
} finally {
result.computeStatusIfUnknown();
}
}

@Override
public void scheduleCoordinatorAndWorkersNow(String coordinatorOid, OperationResult parentResult) throws SchemaException, ObjectNotFoundException {
OperationResult result = parentResult.createSubresult(DOT_INTERFACE + "scheduleCoordinatorAndWorkersNow");
Expand Down Expand Up @@ -921,7 +937,7 @@ public void suspendAndDeleteTasks(Collection<String> taskOids, long suspendTimeo
Task task = getTask(oid, result);
tasksToBeDeleted.add(task);
if (alsoSubtasks) {
tasksToBeDeleted.addAll(task.listSubtasksDeeply(result));
tasksToBeDeleted.addAll(task.listSubtasksDeeply(true, result));
}
} catch (ObjectNotFoundException e) {
// just skip suspending/deleting this task. As for the error, it should be already put into result.
Expand Down Expand Up @@ -1231,7 +1247,7 @@ private void fillInSubtasks(TaskType task, ClusterStatusInformation clusterStatu
boolean retrieveRetryTime = SelectorOptions.hasToLoadPath(new ItemPath(TaskType.F_NEXT_RETRY_TIMESTAMP), options);
boolean retrieveNodeAsObserved = SelectorOptions.hasToLoadPath(new ItemPath(TaskType.F_NODE_AS_OBSERVED), options);

List<PrismObject<TaskType>> subtasks = listSubtasksForTask(task.getTaskIdentifier(), result);
List<PrismObject<TaskType>> subtasks = listPersistentSubtasksForTask(task.getTaskIdentifier(), result);

for (PrismObject<TaskType> subtask : subtasks) {

Expand All @@ -1249,7 +1265,7 @@ private void fillInSubtasks(TaskType task, ClusterStatusInformation clusterStatu
}
}

public List<PrismObject<TaskType>> listSubtasksForTask(String taskIdentifier, OperationResult result) throws SchemaException {
public List<PrismObject<TaskType>> listPersistentSubtasksForTask(String taskIdentifier, OperationResult result) throws SchemaException {

if (StringUtils.isEmpty(taskIdentifier)) {
return new ArrayList<>();
Expand Down Expand Up @@ -2007,7 +2023,7 @@ public void cleanupTasks(CleanupPolicyType policy, Task executionTask, Operation
try {
// get whole tree
Task rootTask = createTaskInstance(rootTaskPrism, result);
List<Task> taskTreeMembers = rootTask.listSubtasksDeeply(result);
List<Task> taskTreeMembers = rootTask.listSubtasksDeeply(true, result);
taskTreeMembers.add(rootTask);

LOGGER.trace("Removing task {} along with its {} children.", rootTask, taskTreeMembers.size() - 1);
Expand Down

0 comments on commit 75de199

Please sign in to comment.