Skip to content

Commit

Permalink
MID-8215 repository factory reset now handled via task on background
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Mar 22, 2023
1 parent 0faf6d7 commit bfdeebc
Showing 1 changed file with 81 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.xml.namespace.QName;

Expand All @@ -28,22 +26,27 @@
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import com.evolveum.midpoint.authentication.api.authorization.AuthorizationAction;
import com.evolveum.midpoint.authentication.api.authorization.PageDescriptor;
import com.evolveum.midpoint.authentication.api.authorization.Url;
import com.evolveum.midpoint.authentication.api.util.AuthConstants;
import com.evolveum.midpoint.authentication.api.util.AuthUtil;
import com.evolveum.midpoint.common.configuration.api.MidpointConfiguration;
import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.gui.api.util.LocalizationUtil;
import com.evolveum.midpoint.gui.api.util.WebComponentUtil;
import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils;
import com.evolveum.midpoint.gui.impl.page.login.PageLogin;
import com.evolveum.midpoint.init.InitialDataImport;
import com.evolveum.midpoint.init.StartupConfiguration;
import com.evolveum.midpoint.model.api.ModelPublicConstants;
import com.evolveum.midpoint.model.api.ModelService;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.repo.api.CacheDispatcher;
import com.evolveum.midpoint.repo.cache.RepositoryCache;
import com.evolveum.midpoint.repo.common.SystemObjectCache;
import com.evolveum.midpoint.schema.LabeledString;
Expand All @@ -56,7 +59,6 @@
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskManager;
import com.evolveum.midpoint.util.Producer;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
Expand All @@ -65,6 +67,9 @@
import com.evolveum.midpoint.web.component.dialog.DeleteConfirmationPanel;
import com.evolveum.midpoint.web.component.dialog.Popupable;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ExecuteScriptActionExpressionType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ExecuteScriptType;
import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ObjectFactory;
import com.evolveum.prism.xml.ns._public.query_3.QueryType;

/**
Expand All @@ -91,8 +96,8 @@ public class PageAbout extends PageAdminConfiguration {
private static final String OPERATION_SUBMIT_REINDEX = DOT_CLASS + "submitReindex";
private static final String OPERATION_GET_PROVISIONING_DIAG = DOT_CLASS + "getProvisioningDiag";
private static final String OPERATION_DELETE_ALL_OBJECTS = DOT_CLASS + "deleteAllObjects";
private static final String OPERATION_DELETE_TASK = DOT_CLASS + "deleteTask";
private static final String OPERATION_LOAD_NODE = DOT_CLASS + "loadNode";
private static final String OPERATION_INITIAL_IMPORT = DOT_CLASS + "initialImport";

private static final String ID_BUILD_TIMESTAMP = "buildTimestamp";
private static final String ID_BUILD = "build";
Expand Down Expand Up @@ -544,9 +549,10 @@ public void yesPerformed(AjaxRequestTarget target) {
};
}

private ActivityDefinitionType createDeleteAllPerObjectType(QName type, QueryType query, Integer threads) {
private ActivityDefinitionType createDeleteActivityForType(QName type, QueryType query, int order, Integer threads) {
// @formatter:off
return new ActivityDefinitionType()
.order(order)
.identifier("Delete all " + type.getLocalPart())
.beginDistribution()
.workerThreads(threads)
Expand Down Expand Up @@ -622,11 +628,12 @@ private List<ObjectTypes> createSortedTypes() {
return types;
}

private String runDeleteAllTask(OperationResult result) throws SchemaException {
private String createAndRunDeleteAllTask(OperationResult result) throws SchemaException {
Task task = createSimpleTask(result.getOperation());

// @formatter:off
ActivityDefinitionType definition = new ActivityDefinitionType()
.identifier("Delete all")
.beginComposition()
.<ActivityDefinitionType>end()
.beginDistribution()
Expand All @@ -635,6 +642,7 @@ private String runDeleteAllTask(OperationResult result) throws SchemaException {
// @formatter:on

List<ActivityDefinitionType> activities = definition.getComposition().getActivity();
int order = 1;
for (ObjectTypes type : createSortedTypes()) {
QueryType query;
if (ObjectTypes.TASK == type) {
Expand All @@ -649,28 +657,55 @@ private String runDeleteAllTask(OperationResult result) throws SchemaException {
threads = 4;
}

activities.add(createDeleteAllPerObjectType(type.getTypeQName(), query, threads));
activities.add(createDeleteActivityForType(type.getTypeQName(), query, order, threads));
order++;
}

activities.add(createInitialImportActivity(order));

task.setName("Delete all objects");
task.setRootActivityDefinition(definition);
task.addArchetypeInformation(SystemObjectsType.ARCHETYPE_UTILITY_TASK.value());
task.addAuxiliaryArchetypeInformation(SystemObjectsType.ARCHETYPE_OBJECTS_DELETE_TASK.value());
task.setCleanupAfterCompletion(XmlTypeConverter.createDuration("P1D"));

getModelInteractionService().switchToBackground(task, result);
return task.getOid();
}

private ActivityDefinitionType createInitialImportActivity(int order) {
ExecuteScriptActionExpressionType execute = new ExecuteScriptActionExpressionType();
ScriptExpressionEvaluatorType script = new ScriptExpressionEvaluatorType();
script.setCode("\n"
+ PageAbout.class.getName() + ".runInitialDataImport(\n"
+ "\tcom.evolveum.midpoint.model.impl.expr.SpringApplicationContextHolder.getApplicationContext(),\n"
+ "\tmidpoint.getCurrentTask().getResult())\n"
+ "log.info(\"Repository factory reset finished\")\n"
);
execute.setScript(script);
execute.setForWholeInput(true);

ExecuteScriptType executeScript = new ExecuteScriptType()
.scriptingExpression(new ObjectFactory().createExecute(execute));

return new ActivityDefinitionType()
.identifier("Initial import")
.order(order)
.beginWork()
.beginNonIterativeScripting()
.scriptExecutionRequest(executeScript)
.<WorkDefinitionsType>end()
.end();
}

private void resetStateToInitialConfig(AjaxRequestTarget target) {
hideMainPopup(target);

OperationResult result = new OperationResult(OPERATION_DELETE_ALL_OBJECTS);
String taskOid = null;

try {
taskOid = runDeleteAllTask(result);
createAndRunDeleteAllTask(result);

info("PageAbout.factoryResetStarted");
info(getString("PageAbout.factoryResetStarted"));
} catch (Exception ex) {
String msg = getString("PageAbout.message.resetStateToInitialConfig.allObject.fatalError");
result.recomputeStatus();
Expand All @@ -681,77 +716,51 @@ private void resetStateToInitialConfig(AjaxRequestTarget target) {
}

target.add(getFeedbackPanel());
// scroll page up
target.appendJavaScript("$(function() { window.scrollTo(0, 0); });");
}

if (taskOid == null) {
return;
}

final String taskOidToRemoving = taskOid;

try {
while (true) {
Task task = getTaskManager().getTaskPlain(taskOid, result);
if (task.isClosed() || task.isSuspended()) {
break;
}

TimeUnit.SECONDS.sleep(5);
}

runPrivileged(new Producer<>() {

private static final long serialVersionUID = 1L;

@Override
public Object run() {
Task task = getTaskManager().createTaskInstance(OPERATION_DELETE_TASK);
task.setChannel(SchemaConstants.CHANNEL_USER_URI);

OperationResult result = task.getResult();
/**
* It's here only because of some IDEs - it's not properly filtering resources during maven build.
* "describe" variable is not replaced.
*
* @return "unknown" instead of "git describe" for current build.
*/
@Deprecated
public String getDescribe() {
return getString("PageAbout.unknownBuildNumber");
}

try {
getTaskService().suspendAndDeleteTasks(Arrays.asList(taskOidToRemoving), 2000L, true, task, result);
} catch (Exception ex) {
result.recomputeStatus();
result.recordFatalError(LocalizationUtil.translate("PageAbout.message.resetStateToInitialConfig.task.fatalError"), ex);
/**
* Used in delete all task as last activity. Do not remove!
*/
public static void runInitialDataImport(ApplicationContext context, OperationResult parent) {
OperationResult result = parent.createSubresult(OPERATION_INITIAL_IMPORT);

LoggingUtils.logUnexpectedException(LOGGER, "Couldn't delete task", ex);
}
result.computeStatus();
return null;
}
});
ModelService modelService = context.getBean(ModelService.class);
CacheDispatcher cacheDispatcher = context.getBean(CacheDispatcher.class);
TaskManager taskManager = context.getBean(TaskManager.class);
PrismContext prismContext = context.getBean(PrismContext.class);
MidpointConfiguration midpointConfiguration = context.getBean(MidpointConfiguration.class);

try {
InitialDataImport initialDataImport = new InitialDataImport();
initialDataImport.setModel(getModelService());
initialDataImport.setTaskManager(getTaskManager());
initialDataImport.setPrismContext(getPrismContext());
initialDataImport.setConfiguration(getMidpointConfiguration());
initialDataImport.setModel(modelService);
initialDataImport.setTaskManager(taskManager);
initialDataImport.setPrismContext(prismContext);
initialDataImport.setConfiguration(midpointConfiguration);
initialDataImport.init(true);

// TODO consider if we need to go clusterwide here
getCacheDispatcher().dispatchInvalidation(null, null, true, null);
cacheDispatcher.dispatchInvalidation(null, null, true, null);

getModelService().shutdown();
modelService.shutdown();

modelService.postInit(result);

getModelService().postInit(result);
} catch (Exception ex) {
result.recomputeStatus();
result.recordFatalError(getString("PageAbout.message.resetStateToInitialConfig.import.fatalError"), ex);
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't import initial objects", ex);
} catch (Exception ex) {
result.recordFatalError("Couldn't run initial data import", ex);
}
showResult(result);
target.add(getFeedbackPanel());
}

/**
* It's here only because of some IDEs - it's not properly filtering resources during maven build.
* "describe" variable is not replaced.
*
* @return "unknown" instead of "git describe" for current build.
*/
@Deprecated
public String getDescribe() {
return getString("PageAbout.unknownBuildNumber");
}
}

0 comments on commit bfdeebc

Please sign in to comment.