Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feature/detaching
Browse files Browse the repository at this point in the history
  • Loading branch information
katkav committed Mar 15, 2022
2 parents 5f223be + ea7eb7b commit 91f3a88
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.evolveum.midpoint.security.api.SecurityContextManager;
import com.evolveum.midpoint.authentication.api.util.AuthUtil;
import com.evolveum.midpoint.cases.api.CaseManager;
import com.evolveum.midpoint.web.page.error.PageError404;
import com.evolveum.midpoint.wf.api.ApprovalsManager;

import org.apache.commons.collections4.CollectionUtils;
Expand Down Expand Up @@ -1537,6 +1538,13 @@ public Breadcrumb redirectBack() {
return redirectBack(DEFAULT_BREADCRUMB_STEP);
}

public void redirectToNotFoundPage() {
PageError404 notFound = new PageError404();
notFound.setBreadcrumbs(getBreadcrumbs());

throw new RestartResponseException(notFound);
}

/**
* @param backStep redirects back to page with backStep step
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,7 @@
*/
package com.evolveum.midpoint.gui.api.util;

import static com.evolveum.midpoint.schema.GetOperationOptions.createNoFetchCollection;

import java.util.*;
import java.util.Objects;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.authentication.api.util.AuthUtil;
import com.evolveum.midpoint.web.page.error.PageError;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.wicket.RestartResponseException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.evolveum.midpoint.common.LocalizationService;
import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.model.api.ModelExecuteOptions;
Expand Down Expand Up @@ -53,6 +38,18 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.EvaluationTimeType;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.wicket.RestartResponseException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.xml.namespace.QName;
import java.util.*;

import static com.evolveum.midpoint.schema.GetOperationOptions.createNoFetchCollection;

/**
* Utility class that contains methods that interact with ModelService and other
* midPoint components.
Expand Down Expand Up @@ -292,7 +289,7 @@ public static <T extends ObjectType> PrismObject<T> loadObject(Class<T> type, St
page.showResult(subResult);
}
if (object == null && !allowNotFound) {
throw new RestartResponseException(PageError.class);
page.redirectToNotFoundPage();
}
LOGGER.debug("Loaded {} with result {}", object, subResult);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ public Search<C> load() {

if (isCollectionViewPanel()) {
CompiledObjectCollectionView view = getObjectCollectionView();
if (view == null) {
getPageBase().redirectToNotFoundPage();
}
search.setCollectionSearchItem(new ObjectCollectionSearchItem(search, view));
search.setCollectionItemVisible(isCollectionViewPanelForWidget());
if (storage != null && view.getPaging() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import java.util.List;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.gui.api.model.ReadOnlyModel;

import org.apache.commons.lang3.StringUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
Expand Down Expand Up @@ -300,7 +302,19 @@ public String getObject() {

@Override
protected IModel<String> createTextModel(final IModel<QName> model) {
return new PropertyModel<>(model, "localPart");
return new IModel<>() {
@Override
public String getObject() {
return model.getObject() != null ? model.getObject().getLocalPart() : "";
}

@Override
public void setObject(String object) {
if (model.getObject() != null) {
model.setObject(new QName(object));
}
}
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,13 @@ <h3>
<a class="btn btn-primary" wicket:id="home" />
<a class="btn btn-primary" wicket:id="back" />

<!-- <wicket:enclosure>-->
<!-- <form method="post" action="logout" style="display: inline; margin-left: 20px;">-->
<!-- <div wicket:id="csrfField"/>-->
<!-- <input type="submit" class="btn btn-default btn-flat" wicket:message="value:PageError.logout"/>-->
<!-- </form>-->

<form method="post" style="display: inline; margin-left: 20px;" wicket:id="logoutForm">

<div wicket:id="csrfField"/>

<input type="submit" class="btn btn-default btn-flat" wicket:message="value:PageError.logout"/>
</form>
<!-- </wicket:enclosure>-->
</div>

</div>
</div>
</wicket:extend>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import com.evolveum.midpoint.authentication.api.config.ModuleAuthentication;
import com.evolveum.midpoint.authentication.api.authorization.Url;

import com.evolveum.midpoint.web.component.util.VisibleBehaviour;

import org.apache.commons.lang3.StringUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
Expand Down Expand Up @@ -136,6 +138,7 @@ public void onClick(AjaxRequestTarget target) {
backPerformed(target);
}
};
back.add(new VisibleBehaviour(() -> PageError.this.getBreadcrumbs().size() > 1));
add(back);

AjaxButton home = new AjaxButton(ID_HOME, createStringResource("PageError.button.home")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package com.evolveum.midpoint.schema.util;

import java.util.*;
import java.util.stream.Stream;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

Expand Down Expand Up @@ -457,6 +458,19 @@ public static void mergePaging(PagingType existPaging, PagingType newPaging) {
}
}

public static void mergeColumns(List<GuiObjectColumnType> existingColumns, List<GuiObjectColumnType> newColumns) {
newColumns.forEach(newColumn -> {
Optional<GuiObjectColumnType> matchesColumn = existingColumns.stream().filter(
existingColumn -> existingColumn.getName().equals(newColumn.getName())).findFirst();
if (matchesColumn.isPresent()){
existingColumns.remove(matchesColumn.get());
existingColumns.add(newColumn);
} else {
existingColumns.add(newColumn);
}
});
}

/*
the ordering algorithm is: the first level is occupied by
the column which previousColumn == null || "" || notExistingColumnNameValue.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ private void compileColumns(CompiledObjectCollectionView existingView, GuiObject
existingView.setIncludeDefaultColumns(objectListViewType.isIncludeDefaultColumns());
// Not very efficient algorithm. But must do for now.
List<GuiObjectColumnType> existingColumns = existingView.getColumns();
existingColumns.addAll(newColumns);
MiscSchemaUtil.mergeColumns(existingColumns, objectListViewType.getColumn());
List<GuiObjectColumnType> orderedList = MiscSchemaUtil.orderCustomColumns(existingColumns);
existingColumns.clear();
existingColumns.addAll(orderedList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import static com.evolveum.midpoint.prism.PrismObject.asObjectableList;
import static com.evolveum.midpoint.schema.constants.SchemaConstants.*;
import static com.evolveum.midpoint.util.MiscUtil.argCheck;
import static com.evolveum.midpoint.util.MiscUtil.or0;
import static com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType.F_TIMESTAMP;

import java.io.File;
Expand All @@ -23,7 +22,6 @@
import java.io.IOException;
import java.net.ConnectException;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -126,8 +124,6 @@
import com.evolveum.midpoint.security.enforcer.api.ItemSecurityConstraints;
import com.evolveum.midpoint.security.enforcer.api.SecurityEnforcer;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskDebugUtil;
import com.evolveum.midpoint.task.api.TaskUtil;
import com.evolveum.midpoint.test.*;
import com.evolveum.midpoint.test.asserter.*;
import com.evolveum.midpoint.test.asserter.prism.PrismContainerDefinitionAsserter;
Expand Down Expand Up @@ -3487,6 +3483,9 @@ protected void waitForRootActivityCompletion(@NotNull String rootTaskOid, int ti
/**
* Waits for the completion of the root activity realization. Useful for task trees.
*
* Stops also if there's a failed/suspended activity - see {@link #findSuspendedActivity(Task)}.
* This is to account for suspended multi-node tasks like `TestThresholdsStoryReconExecuteMultinode`.
*
* TODO reconcile with {@link #waitForTaskActivityCompleted(String, long, OperationResult, long)}
*
* @param lastKnownCompletionTimestamp The completion we know about - and are _not_ interested in. If null,
Expand All @@ -3508,9 +3507,25 @@ protected Task waitForRootActivityCompletion(
// Now do the real check now
freshRootTask.refresh(waitResult);
var rootState = freshRootTask.getActivityStateOrClone(ActivityPath.empty());
return rootState != null

if (verbose) {
displayValueAsXml("overview", freshRootTask.getActivityTreeStateOverviewOrClone());
}

if (rootState != null
&& rootState.getRealizationState() == ActivityRealizationStateType.COMPLETE
&& isDifferent(lastKnownCompletionTimestamp, rootState.getRealizationEndTimestamp());
&& isDifferent(lastKnownCompletionTimestamp, rootState.getRealizationEndTimestamp())) {
return true;
}

ActivityStateOverviewType suspended = findSuspendedActivity(freshRootTask);
if (suspended != null) {
displayValueAsXml("Suspended activity -> not waiting anymore", suspended);
return true;
}

// The task lives: let's continue waiting
return false;
};

IntegrationTestTools.waitFor("Waiting for task tree " + freshRootTask + " next finished run",
Expand All @@ -3522,6 +3537,67 @@ protected Task waitForRootActivityCompletion(
return freshRootTask;
}

/**
* Finds an activity that:
*
* - is in progress,
* - has at least one worker task,
* - all of the workers are marked as "not running", at least one of them is marked as failed, and is suspended.
*
* This is to avoid waiting for multi-node tasks that will never complete.
*
* It is ugly and not 100% reliable: in theory, the failure may be expected, and the current state may be transient.
* But it's probably the best we can do now.
*/
private @Nullable ActivityStateOverviewType findSuspendedActivity(Task task) throws SchemaException, ObjectNotFoundException {
ActivityStateOverviewType root = task.getActivityTreeStateOverviewOrClone();
return root != null ? findSuspendedActivity(root) : null;
}

private @Nullable ActivityStateOverviewType findSuspendedActivity(@NotNull ActivityStateOverviewType activityStateOverview)
throws SchemaException, ObjectNotFoundException {
if (activityStateOverview.getRealizationState() != ActivitySimplifiedRealizationStateType.IN_PROGRESS) {
return null; // Not started or complete
}
if (isSuspended(activityStateOverview)) {
return activityStateOverview;
}
for (ActivityStateOverviewType child : activityStateOverview.getActivity()) {
ActivityStateOverviewType suspendedInChild = findSuspendedActivity(child);
if (suspendedInChild != null) {
return suspendedInChild;
}
}
return null;
}

private boolean isSuspended(ActivityStateOverviewType activityStateOverview) throws SchemaException, ObjectNotFoundException {
List<ActivityTaskStateOverviewType> tasks = activityStateOverview.getTask();
if (tasks.isEmpty()) {
return false;
}
if (tasks.stream().anyMatch(task -> task.getExecutionState() != ActivityTaskExecutionStateType.NOT_RUNNING)) {
return false;
}
for (ActivityTaskStateOverviewType task : tasks) {
if (isSuspended(task)) {
return true;
}
}
return false;
}

private boolean isSuspended(ActivityTaskStateOverviewType taskInfo) throws SchemaException, ObjectNotFoundException {
if (taskInfo.getResultStatus() != OperationResultStatusType.FATAL_ERROR) {
return false;
}
if (taskInfo.getTaskRef() == null || taskInfo.getTaskRef().getOid() == null) {
return false; // shouldn't occur
}
Task task = taskManager.getTaskPlain(taskInfo.getTaskRef().getOid(), getTestOperationResult());
return task.getExecutionState() == TaskExecutionStateType.SUSPENDED;
}

private boolean isDifferent(@Nullable XMLGregorianCalendar lastKnownTimestamp, XMLGregorianCalendar realTimestamp) {
return lastKnownTimestamp == null
|| !lastKnownTimestamp.equals(realTimestamp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public SqaleRepositoryService repositoryService(
* No need to clean up the cache tables, only the main and audit tables are cleared.
*/
public void clearDatabase(SqaleRepoContext sqlRepoContext) {
LOGGER.info("Postprocessing session factory - removing everything from database if necessary.");
LOGGER.info("Clearing the testing database!");
try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) {
// Truncate cascades to sub-rows of the "object aggregate" - if FK points to m_object table hierarchy.
jdbcSession.executeStatement("TRUNCATE m_object CASCADE;");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class SchemaActionComputer {
* For database schema versioning please see
* <a href="https://docs.evolveum.com/midpoint/reference/repository/database-schema-versioning/">wiki page about DB versioning</a>.
*/
public static final String REQUIRED_DATABASE_SCHEMA_VERSION = "4.4";
public static final String REQUIRED_DATABASE_SCHEMA_VERSION = "4.5";

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

Expand All @@ -57,7 +57,8 @@ class SchemaActionComputer {
new ImmutablePair<>("3.9", "4.0"),
new ImmutablePair<>("4.0", "4.2"),
new ImmutablePair<>("4.2", "4.3"),
new ImmutablePair<>("4.3", "4.4")));
new ImmutablePair<>("4.3", "4.4"),
new ImmutablePair<>("4.4", "4.5")));

enum State {
COMPATIBLE, NO_TABLES, AUTOMATICALLY_UPGRADEABLE, MANUALLY_UPGRADEABLE, INCOMPATIBLE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2062,6 +2062,12 @@ public static void display(String title, List<Element> elements) {
IntegrationTestTools.display(title, elements);
}

public void displayValueAsXml(String title, Object value) throws SchemaException {
displayValue(title,
value != null ?
prismContext.xmlSerializer().serializeRealValue(value, SchemaConstants.C_VALUE) : null);
}

@Override
public void displayValue(String title, Object value) {
PrismTestUtil.display(title, value);
Expand Down

0 comments on commit 91f3a88

Please sign in to comment.