Skip to content

Commit

Permalink
"Delete all closed task" function.
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Feb 8, 2016
1 parent ce8cae4 commit 1133ebb
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 74 deletions.
Expand Up @@ -19,6 +19,7 @@
<body>
<wicket:extend>
<div wicket:id="deleteTasksPopup" />
<div wicket:id="deleteAllClosedTasksPopup" />

<form wicket:id="mainForm" class="form-inline">
<div wicket:id="taskTable"/>
Expand Down
Expand Up @@ -16,10 +16,14 @@

package com.evolveum.midpoint.web.page.admin.server;

import com.evolveum.midpoint.model.api.ModelPublicConstants;
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.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
Expand Down Expand Up @@ -52,6 +56,8 @@
import com.evolveum.midpoint.web.util.ObjectTypeGuiDescriptor;
import com.evolveum.midpoint.web.util.OnePageParameterEncoder;
import com.evolveum.midpoint.web.util.WebMiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupPoliciesType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupPolicyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType;
Expand All @@ -76,7 +82,6 @@
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.string.StringValue;

Expand All @@ -100,6 +105,7 @@ public class PageTasks extends PageAdminTasks {
private static final String OPERATION_RESUME_TASKS = DOT_CLASS + "resumeTasks";
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_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";
private static final String OPERATION_START_SCHEDULERS = DOT_CLASS + "startSchedulers";
Expand All @@ -122,6 +128,7 @@ public class PageTasks extends PageAdminTasks {
private static final String ID_NODE_TABLE = "nodeTable";
private static final String ID_SEARCH_CLEAR = "searchClear";
private static final String ID_DELETE_TASKS_POPUP = "deleteTasksPopup";
private static final String ID_DELETE_ALL_CLOSED_TASKS_POPUP = "deleteAllClosedTasksPopup";
private static final String ID_TABLE_HEADER = "tableHeader";

public static final String SELECTED_CATEGORY = "category";
Expand Down Expand Up @@ -243,6 +250,16 @@ public void yesPerformed(AjaxRequestTarget target) {
}
});

add(new ConfirmationDialog(ID_DELETE_ALL_CLOSED_TASKS_POPUP,
createStringResource("pageTasks.dialog.title.confirmDelete"),
createStringResource("pageTasks.message.deleteAllClosedTasksConfirm")) {

@Override
public void yesPerformed(AjaxRequestTarget target) {
close(target);
deleteAllClosedTasksConfirmedPerformed(target);
}
});

initDiagnosticButtons();
}
Expand Down Expand Up @@ -486,7 +503,14 @@ public void onClick(AjaxRequestTarget target) {
deleteTasksPerformed(target);
}
}));
items.add(new InlineMenuItem(createStringResource("pageTasks.button.deleteAllClosedTasks"), false,
new HeaderMenuAction(this) {

@Override
public void onClick(AjaxRequestTarget target) {
deleteAllClosedTasksPerformed(target);
}
}));
return items;
}

Expand Down Expand Up @@ -806,7 +830,11 @@ private void deleteTasksPerformed(AjaxRequestTarget target) {
}
ModalWindow dialog = (ModalWindow) get(ID_DELETE_TASKS_POPUP);
dialog.show(target);
}

private void deleteAllClosedTasksPerformed(AjaxRequestTarget target) {
ModalWindow dialog = (ModalWindow) get(ID_DELETE_ALL_CLOSED_TASKS_POPUP);
dialog.show(target);
}

private void scheduleTasksPerformed(AjaxRequestTarget target) {
Expand Down Expand Up @@ -1263,4 +1291,35 @@ private List<String> createCategoryList() {
return categories;
}
}

private void deleteAllClosedTasksConfirmedPerformed(AjaxRequestTarget target) {
OperationResult launchResult = new OperationResult(OPERATION_DELETE_ALL_CLOSED_TASKS);
Task task = createSimpleTask(OPERATION_DELETE_ALL_CLOSED_TASKS);

task.setHandlerUri(ModelPublicConstants.CLEANUP_TASK_HANDLER_URI);
task.setName("Closed tasks cleanup");

try {
CleanupPolicyType policy = new CleanupPolicyType();
policy.setMaxAge(XmlTypeConverter.createDuration(0));

CleanupPoliciesType policies = new CleanupPoliciesType();
policies.setClosedTasks(policy);

PrismProperty<CleanupPoliciesType> policiesProperty = getPrismContext().getSchemaRegistry()
.findPropertyDefinitionByElementName(SchemaConstants.MODEL_EXTENSION_CLEANUP_POLICIES).instantiate();
policiesProperty.setRealValue(policies);
task.setExtensionProperty(policiesProperty);
} catch (SchemaException e) {
LOGGER.error("Error dealing with schema (task {})", task, e);
launchResult.recordFatalError("Error dealing with schema", e);
throw new IllegalStateException("Error dealing with schema", e);
}

getTaskManager().switchToBackground(task, launchResult);

showResult(launchResult);
target.add(getFeedbackPanel());
}

}
Expand Up @@ -1425,8 +1425,8 @@ PageCert.now=now
StageEditorPanel.stageDefinitionLabelName = Stage Definition #
StageDefinitionPanel.stageName = Name
StageDefinitionPanel.stageDescription = Description
StageDefinitionPanel.stageDuration = Duration (in days)
StageDefinitionPanel.notifyBeforeDeadline = Notify before deadline (in hours)
StageDefinitionPanel.stageDuration = Duration
StageDefinitionPanel.notifyBeforeDeadline = Notify before deadline
StageDefinitionPanel.notifyWhenNoDecision = Notify only when no decision
StageDefinitionPanel.reviewerSpecification = Reviewer specification
StageDefinitionPanel.reviewerSpecificationName = Reviewer specification name (optional)
Expand Down Expand Up @@ -1990,6 +1990,7 @@ pageTasks.alreadyPassedForNotRunningTasks=(already passed)
pageTasks.button.deactivateServiceThreads=Stop all threads
pageTasks.button.deleteNode=Delete
pageTasks.button.deleteTask=Delete
pageTasks.button.deleteAllClosedTasks=Delete all closed tasks
pageTasks.button.reactivateServiceThreads=Start all threads
pageTasks.button.refreshTasks=Refresh tasks
pageTasks.button.resumeTask=Resume
Expand Down Expand Up @@ -2032,6 +2033,7 @@ pageTasks.message.alreadyResumed=Task '{0}' can't be resumed, it's already runni
pageTasks.message.alreadySuspended=Task '{0}' is already suspended or closed.
pageTasks.message.couldntCreateQuery=Couldn't create query for task list.
pageTasks.message.deleteTaskConfirm=Do you really want to delete task '{0}'?
pageTasks.message.deleteAllClosedTasksConfirm=Do you really want to delete all closed tasks?
pageTasks.message.deleteTasksConfirm=Do you really want to delete {0} tasks?
pageTasks.message.noNodeSelected=No node has been selected.
pageTasks.message.noTaskSelected=No task has been selected.
Expand Down
Expand Up @@ -1396,8 +1396,8 @@ PageCert.now=now
StageEditorPanel.stageDefinitionLabelName = Stage Definition #
StageDefinitionPanel.stageName = Name
StageDefinitionPanel.stageDescription = Description
StageDefinitionPanel.stageDuration = Duration (in days)
StageDefinitionPanel.notifyBeforeDeadline = Notify before deadline (in hours)
StageDefinitionPanel.stageDuration = Duration
StageDefinitionPanel.notifyBeforeDeadline = Notify before deadline
StageDefinitionPanel.notifyWhenNoDecision = Notify only when no decision
StageDefinitionPanel.reviewerSpecification = Reviewer specification
StageDefinitionPanel.reviewerSpecificationName = Reviewer specification name (optional)
Expand Down
Expand Up @@ -198,6 +198,8 @@ public abstract class SchemaConstants {
public static final QName MODEL_EXTENSION_DUPLICATE_SHADOWS_RESOLVER = new QName(NS_MODEL_EXTENSION, "duplicateShadowsResolver");
public static final QName MODEL_EXTENSION_CHECK_DUPLICATES_ON_PRIMARY_IDENTIFIERS_ONLY = new QName(NS_MODEL_EXTENSION, "checkDuplicatesOnPrimaryIdentifiersOnly");

public static final QName MODEL_EXTENSION_CLEANUP_POLICIES = new QName(NS_MODEL_EXTENSION, "cleanupPolicies");

public static final String NS_GUI = NS_MIDPOINT_PUBLIC + "/gui";
public static final String NS_GUI_CHANNEL = NS_GUI + "/channels-3";
public static final QName CHANNEL_GUI_INIT_QNAME = new QName(NS_GUI_CHANNEL, "init");
Expand Down
Expand Up @@ -271,6 +271,18 @@
</xsd:annotation>
</xsd:element>

<xsd:element name="cleanupPolicies" type="c:CleanupPoliciesType">
<xsd:annotation>
<xsd:documentation>
Overrides default system cleanup policy for CleanUpTaskHandler.
Used e.g. to cleanup all currently closed tasks.
</xsd:documentation>
<xsd:appinfo>
<a:maxOccurs>1</a:maxOccurs>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>

</xsd:schema>


Expand Up @@ -31,4 +31,5 @@ public class ModelPublicConstants {
public static final String NS_SYNCHRONIZATION_TASK_PREFIX = NS_SYNCHRONIZATION_PREFIX + "/task";
public static final String DELETE_TASK_HANDLER_URI = NS_SYNCHRONIZATION_TASK_PREFIX + "/delete/handler-3";

public static final String CLEANUP_TASK_HANDLER_URI = SchemaConstants.NS_MODEL + "/cleanup/handler-3";
}
Expand Up @@ -16,24 +16,13 @@

package com.evolveum.midpoint.model.impl.cleanup;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.xml.datatype.Duration;

import com.evolveum.midpoint.audit.api.AuditService;
import com.evolveum.midpoint.report.api.ReportManager;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.model.impl.lens.ChangeExecutor;
import com.evolveum.midpoint.model.impl.lens.Clockwork;
import com.evolveum.midpoint.model.impl.sync.RecomputeTaskHandler;
import com.evolveum.midpoint.model.api.ModelPublicConstants;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.report.api.ReportManager;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
Expand All @@ -50,11 +39,17 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.CleanupPolicyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;

@Component
public class CleanUpTaskHandler implements TaskHandler{

public static final String HANDLER_URI = "http://midpoint.evolveum.com/xml/ns/public/model/cleanup/handler-3";
public static final String HANDLER_URI = ModelPublicConstants.CLEANUP_TASK_HANDLER_URI;

@Autowired(required=true)
private TaskManager taskManager;
Expand All @@ -79,35 +74,48 @@ private void initialize() {
taskManager.registerHandler(HANDLER_URI, this);
}


@Override
public TaskRunResult run(Task task) {
task.startCollectingOperationStatsFromZero(true, false, false);
try {
return runInternal(task);
} finally {
task.storeOperationStats();
}
}

private TaskRunResult runInternal(Task task) {
LOGGER.trace("CleanUpTaskHandler.run starting");

long progress = task.getProgress();
OperationResult opResult = new OperationResult(OperationConstants.CLEANUP);
TaskRunResult runResult = new TaskRunResult();
runResult.setOperationResult(opResult);

PrismObject<SystemConfigurationType> systemConfig = null;
try {
systemConfig = repositoryService.getObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), null, opResult);
} catch (ObjectNotFoundException ex) {
LOGGER.error("Cleanup: Object does not exist: {}",ex.getMessage(),ex);
opResult.recordFatalError("Object does not exist: "+ex.getMessage(),ex);
runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR);
runResult.setProgress(progress);
return runResult;
} catch (SchemaException ex) {
LOGGER.error("Cleanup: Error dealing with schema: {}",ex.getMessage(),ex);
opResult.recordFatalError("Error dealing with schema: "+ex.getMessage(),ex);
runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR);
runResult.setProgress(progress);
return runResult;

CleanupPoliciesType cleanupPolicies = task.getExtensionPropertyRealValue(SchemaConstants.MODEL_EXTENSION_CLEANUP_POLICIES);

if (cleanupPolicies != null) {
LOGGER.info("Using task-specific cleanupPolicies: {}", cleanupPolicies);
} else {
PrismObject<SystemConfigurationType> systemConfig;
try {
systemConfig = repositoryService.getObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), null, opResult);
} catch (ObjectNotFoundException ex) {
LOGGER.error("Cleanup: Object does not exist: {}", ex.getMessage(), ex);
opResult.recordFatalError("Object does not exist: " + ex.getMessage(), ex);
runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR);
runResult.setProgress(progress);
return runResult;
} catch (SchemaException ex) {
LOGGER.error("Cleanup: Error dealing with schema: {}", ex.getMessage(), ex);
opResult.recordFatalError("Error dealing with schema: " + ex.getMessage(), ex);
runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR);
runResult.setProgress(progress);
return runResult;
}
SystemConfigurationType systemConfigType = systemConfig.asObjectable();
cleanupPolicies = systemConfigType.getCleanupPolicy();
}
SystemConfigurationType systemConfigType = systemConfig.asObjectable();

CleanupPoliciesType cleanupPolicies = systemConfigType.getCleanupPolicy();

if (cleanupPolicies == null){
LOGGER.trace("Cleanup: No clean up polices specified. Finishing clean up task.");
Expand Down Expand Up @@ -185,13 +193,16 @@ public void refreshStatus(Task task) {

@Override
public String getCategoryName(Task task) {
return TaskCategory.SYSTEM;
if (task.getExtensionPropertyRealValue(SchemaConstants.MODEL_EXTENSION_CLEANUP_POLICIES) != null) {
return TaskCategory.UTIL; // this is run on-demand just like other utility tasks (e.g. delete task handler)
} else {
return TaskCategory.SYSTEM; // this is the default instance, always running
}
}

@Override
public List<String> getCategoryNames() {
// TODO Auto-generated method stub
return null;
return Arrays.asList(TaskCategory.UTIL, TaskCategory.SYSTEM);
}

}
Expand Up @@ -311,6 +311,11 @@ public <T> PrismProperty<T> getExtensionProperty(QName propertyName) {
throw new UnsupportedOperationException("not implemented yet.");
}

@Override
public <T> T getExtensionPropertyRealValue(QName propertyName) {
throw new UnsupportedOperationException("not implemented yet.");
}

@Override
public <IV extends PrismValue,ID extends ItemDefinition> Item<IV,ID> getExtensionItem(QName propertyName) {
throw new UnsupportedOperationException("not implemented yet.");
Expand Down
Expand Up @@ -517,6 +517,13 @@ void setBindingImmediate(TaskBinding value, OperationResult parentResult)
*/
public <T> PrismProperty<T> getExtensionProperty(QName propertyName);

/**
* Returns specified single-valued property real value from the extension
* @param propertyName
* @return null if extension or property does not exist.
*/
<T> T getExtensionPropertyRealValue(QName propertyName);

/**
* Returns specified reference from the extension.
* @param name
Expand Down

0 comments on commit 1133ebb

Please sign in to comment.