Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Mar 30, 2020
2 parents a0a34d3 + 102869e commit 6edaec2
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 40 deletions.
Expand Up @@ -1116,7 +1116,11 @@ public static String getTranslatedPolyString(PolyString value, LocalizationServi
if (localizationService == null){
localizationService = MidPointApplication.get().getLocalizationService();
}
return localizationService.translate(value, getCurrentLocale(), true);
String translatedValue = localizationService.translate(value, getCurrentLocale(), true);
if (StringUtils.isNotEmpty(translatedValue)){
return translatedValue;
}
return value.getOrig();
}

public static <O extends ObjectType> String getName(ObjectReferenceType ref, PageBase pageBase, String operation) {
Expand Down
Expand Up @@ -19,6 +19,8 @@
import com.evolveum.midpoint.util.annotation.Experimental;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringTranslationType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;

import java.io.Serializable;
Expand Down Expand Up @@ -337,7 +339,20 @@ public String debugDump(int indent) {

@Override
public void shortDump(StringBuilder sb) {
sb.append(orig);
if (MapUtils.isNotEmpty(getLang()) || getTranslation() != null && StringUtils.isNotEmpty(getTranslation().getKey())){
sb.append("orig=" + orig);
} else {
sb.append(orig);
}
if (getTranslation() != null) {
sb.append("; translation.key=" + getTranslation().getKey());
}
if (MapUtils.isNotEmpty(getLang())) {
sb.append("; lang:");
getLang().keySet().forEach(langKey -> {
sb.append(" " + langKey + "=" + getLang().get(langKey) + ",");
});
}
}

public static String getOrig(PolyString s) {
Expand Down
Expand Up @@ -33,6 +33,8 @@
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
import com.evolveum.prism.xml.ns._public.types_3.RawType;
import com.evolveum.prism.xml.ns._public.types_3.SchemaDefinitionType;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -587,11 +589,15 @@ public String toHumanReadableString() {
// (displaying the aux information in user-visible context). But for e.g. deltas we need this information.
PolyString ps = (PolyString) this.value;
StringBuilder sb = new StringBuilder();
sb.append("orig=" + ps.getOrig());
if (MapUtils.isNotEmpty(ps.getLang()) || ps.getTranslation() != null && StringUtils.isNotEmpty(ps.getTranslation().getKey())){
sb.append("orig=" + ps.getOrig());
} else {
sb.append(ps.getOrig());
}
if (ps.getTranslation() != null) {
sb.append(", translation="+ps.getTranslation().getKey());
sb.append(", translation.key=" + ps.getTranslation().getKey());
}
if (ps.getLang() != null) {
if (MapUtils.isNotEmpty(ps.getLang())) {
sb.append("; lang:");
ps.getLang().keySet().forEach(langKey -> {
sb.append(" " + langKey + "=" + ps.getLang().get(langKey) + ",");
Expand Down
Expand Up @@ -32,6 +32,7 @@
import com.evolveum.midpoint.task.api.TaskExecutionStatus;
import com.evolveum.midpoint.task.api.TaskManager;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
Expand Down Expand Up @@ -204,8 +205,9 @@ public boolean isEmpty(PcpStartInstruction instruction,
}
// second pass: check the conditions
for (ApprovalStageDefinitionType stage : stages) {
if (!SchemaConstants.MODEL_APPROVAL_OUTCOME_SKIP.equals(
evaluateAutoCompleteExpression(instruction.getCase(), stage, instruction, stageComputeHelper, ctx, result))) {
String autoCompletionResult = evaluateAutoCompleteExpression(instruction.getCase(), stage, instruction,
stageComputeHelper, ctx, result);
if (!QNameUtil.matchUri(SchemaConstants.MODEL_APPROVAL_OUTCOME_SKIP, autoCompletionResult)) {
return false;
}
}
Expand Down
Expand Up @@ -73,6 +73,9 @@ public class TestAssignmentsAdvanced extends AbstractWfTestPolicy {
private static final File ROLE_ROLE27_FILE = new File(TEST_RESOURCE_DIR, "role-role27-modifications-and.xml");
private static final File ROLE_ROLE28_FILE = new File(TEST_RESOURCE_DIR, "role-role28-modifications-or.xml");
private static final File ROLE_ROLE29_FILE = new File(TEST_RESOURCE_DIR, "role-role29-modifications-no-items.xml");

private static final TestResource ROLE_SKIPPED_FILE = new TestResource(TEST_RESOURCE_DIR, "role-skipped.xml", "66134203-f023-4986-bb5c-a350941909eb");

private static final TestResource ROLE_IDEMPOTENT = new TestResource(TEST_RESOURCE_DIR, "role-idempotent.xml", "e2f2d977-887b-4ea1-99d8-a6a030a1a6c0");
private static final TestResource ROLE_WITH_IDEMPOTENT_METAROLE = new TestResource(TEST_RESOURCE_DIR, "role-with-idempotent-metarole.xml", "34855a80-3899-4ecf-bdb3-9fc008c4ff70");

Expand Down Expand Up @@ -127,6 +130,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
roleRole29Oid = repoAddObjectFromFile(ROLE_ROLE29_FILE, initResult).getOid();
repoAdd(ROLE_IDEMPOTENT, initResult);
repoAdd(ROLE_WITH_IDEMPOTENT_METAROLE, initResult);
repoAdd(ROLE_SKIPPED_FILE, initResult);

orgLeads2122Oid = repoAddObjectFromFile(ORG_LEADS2122_FILE, initResult).getOid();

Expand Down Expand Up @@ -1071,6 +1075,34 @@ public void test910AssignRoleWithIdempotentMetarole() throws Exception {
deleteCaseTree(rootCaseOid, result);
}

/**
* MID-5895
*/
@Test
public void test920AssignRoleWithComputedSkip() throws Exception {
given();
login(userAdministrator);
Task task = getTestTask();
OperationResult result = task.getResult();

when();
unassignAllRoles(userJackOid);

ObjectDelta<UserType> delta = prismContext.deltaFor(UserType.class)
.item(UserType.F_ASSIGNMENT)
.add(new AssignmentType(prismContext).targetRef(ROLE_SKIPPED_FILE.oid, RoleType.COMPLEX_TYPE))
.asObjectDeltaCast(userJackOid);

executeChanges(delta, null, task, result);

then();
String ref = result.findAsynchronousOperationReference();
assertNull("Present async operation reference", ref);

assertUser(userJackOid, "after")
.assertAssignments(1);
}

private void executeAssignRoles123ToJack(boolean immediate,
boolean approve1, boolean approve2, boolean approve3a, boolean approve3b, boolean securityDeputy) throws Exception {
Task task = getTestTask();
Expand Down
@@ -0,0 +1,31 @@
<!--
~ Copyright (c) 2020 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="66134203-f023-4986-bb5c-a350941909eb">
<name>skipped</name>
<assignment>
<policyRule>
<policyConstraints>
<assignment/>
</policyConstraints>
<policyActions>
<approval>
<approvalSchema>
<stage>
<approverRef oid="00000000-0000-0000-0000-000000000002" type="UserType" />
<automaticallyCompleted>
<script>
<code>'skip'</code> <!-- MID-5895 -->
</script>
</automaticallyCompleted>
</stage>
</approvalSchema>
</approval>
</policyActions>
</policyRule>
</assignment>
</role>
Expand Up @@ -7,6 +7,16 @@

package com.evolveum.midpoint.repo.sql.schemacheck;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.common.LocalizationService;
import com.evolveum.midpoint.repo.sql.SqlRepositoryConfiguration;
import com.evolveum.midpoint.repo.sql.SqlRepositoryConfiguration.MissingSchemaAction;
Expand All @@ -17,16 +27,6 @@
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Determines the action that should be done against the database (none, stop, warn, create, upgrade)
Expand All @@ -36,12 +36,8 @@
* - repository configuration (namely actions for missing/upgradeable/incompatible schemas)
*
* TODOs (issues to consider)
* 1) database schema version could differ from major midPoint version (e.g. 3.7.2 vs 3.7 - fortunately it's history)
* 2) check if db variant is applicable (e.g. upgrading "plain" mysql using "utf8mb4" variant and vice versa)
*
* @author mederly
* - check if db variant is applicable (e.g. upgrading "plain" mysql using "utf8mb4" variant and vice versa)
*/

@Component
class SchemaActionComputer {

Expand All @@ -56,10 +52,29 @@ class SchemaActionComputer {
@Autowired private BaseHelper baseHelper;

private static final Set<Pair<String, String>> AUTOMATICALLY_UPGRADEABLE = new HashSet<>(
Arrays.asList(new ImmutablePair<>("3.8", "3.9"),
Arrays.asList(
new ImmutablePair<>("3.8", "3.9"),
new ImmutablePair<>("3.9", "4.0"))
);

/**
* Exceptions from the general "db version = mP minor version" rule, based on full mP version.
*/
private static final Map<String, String> DATABASE_VERSION_FROM_MIDPOINT_VERSION;
static {
DATABASE_VERSION_FROM_MIDPOINT_VERSION = new HashMap<>();
DATABASE_VERSION_FROM_MIDPOINT_VERSION.put("3.7.2", "3.7.2");
}

/**
* Exceptions from the general "db version = mP minor version" rule, based on mP minor version.
*/
private static final Map<String, String> DATABASE_VERSION_FROM_MIDPOINT_MINOR_VERSION;
static {
DATABASE_VERSION_FROM_MIDPOINT_MINOR_VERSION = new HashMap<>();
DATABASE_VERSION_FROM_MIDPOINT_MINOR_VERSION.put("4.1", "4.0");
}

enum State {
COMPATIBLE, NO_TABLES, AUTOMATICALLY_UPGRADEABLE, MANUALLY_UPGRADEABLE, INCOMPATIBLE
}
Expand Down Expand Up @@ -191,7 +206,12 @@ private String getCurrentAndRequiredVersionInformation(SchemaState state) {
private State determineState(SchemaState schemaState) {
@NotNull String requiredVersion = getRequiredDatabaseSchemaVersion();
DataStructureCompliance.State dataComplianceState = schemaState.dataStructureCompliance.state;
DeclaredVersion.State versionState = schemaState.declaredVersion.state;
Exception dataComplianceException = schemaState.dataStructureCompliance.validationException;
DeclaredVersion.State declaredVersionState = schemaState.declaredVersion.state;
String declaredVersionNumber = schemaState.declaredVersion.version;
LOGGER.info("Required database schema version: {}, declared version: {} ({}), data structure compliance: {}{}",
requiredVersion, declaredVersionNumber, declaredVersionState, dataComplianceState,
dataComplianceException != null ? " (" + dataComplianceException.getMessage() + ")": "");
if (requiredVersion.equals(schemaState.declaredVersion.version)) {
switch (dataComplianceState) {
case COMPLIANT:
Expand All @@ -208,18 +228,18 @@ private State determineState(SchemaState schemaState) {
case NO_TABLES:
return State.NO_TABLES;
case COMPLIANT:
if (versionState == DeclaredVersion.State.METADATA_TABLE_MISSING) {
if (declaredVersionState == DeclaredVersion.State.METADATA_TABLE_MISSING) {
LOGGER.warn("Strange: Data structure is compliant but metadata table is missing or inaccessible. Please investigate this.");
return State.INCOMPATIBLE;
} else if (versionState == DeclaredVersion.State.VERSION_VALUE_MISSING) {
} else if (declaredVersionState == DeclaredVersion.State.VERSION_VALUE_MISSING) {
LOGGER.warn("Data structure is compliant but version information is missing from the global metadata table. Please investigate and fix this.");
return State.COMPATIBLE; // let's continue
}
return determineUpgradeability(schemaState.declaredVersion, requiredVersion);
case NOT_COMPLIANT:
if (versionState == DeclaredVersion.State.METADATA_TABLE_MISSING) {
if (declaredVersionState == DeclaredVersion.State.METADATA_TABLE_MISSING) {
return State.MANUALLY_UPGRADEABLE; // this is currently true (any version can be upgraded to 3.9)
} else if (versionState == DeclaredVersion.State.VERSION_VALUE_MISSING) {
} else if (declaredVersionState == DeclaredVersion.State.VERSION_VALUE_MISSING) {
return State.INCOMPATIBLE; // something strange happened; this does not seem to be an upgrade situation
}
return determineUpgradeability(schemaState.declaredVersion, requiredVersion);
Expand Down Expand Up @@ -267,26 +287,35 @@ private MissingSchemaAction getMissingSchemaAction() {
}

/**
* Currently this is equal to midPoint major version. But, in general, there might be differences, e.g.
* - no database change between major mP versions: e.g. if 5.7 would have the same db as 5.6, then req.schema version for 5.7 would be "5.6"
* - database change between minor versions: e.g. 3.7 and 3.7.1 have version of "3.7", but 3.7.2 has version of "3.7.2"
* (fortunately, at that time we didn't have repository versions!)
* For database schema versioning please see https://wiki.evolveum.com/display/midPoint/Database+schema+versioning.
*
* Normally, database schema version is the same as midPoint minor version (e.g. 3.9). Exceptions are stored in
* DATABASE_VERSION_FROM_MIDPOINT_VERSION and DATABASE_VERSION_FROM_MIDPOINT_MINOR_VERSION tables.
*
* TODO Think out how we will deal with snapshots. Now they are ignored, so e.g. 4.2-SNAPSHOT converted to 4.2.
*/
@NotNull
private String getRequiredDatabaseSchemaVersion() {
// TODO adapt if major mp version != database schema version
//return getMajorMidPointVersion();
return "4.0"; // Temporary measure, until better mechanism is devised (MID-5884)
String fullMidPointVersion = getMidPointVersion();
String exceptionFromFullVersion = DATABASE_VERSION_FROM_MIDPOINT_VERSION.get(fullMidPointVersion);
if (exceptionFromFullVersion != null) {
return exceptionFromFullVersion;
}
String minorMidPointVersion = getMinorMidPointVersion(fullMidPointVersion);
String exceptionFromMinorVersion = DATABASE_VERSION_FROM_MIDPOINT_MINOR_VERSION.get(minorMidPointVersion);
if (exceptionFromMinorVersion != null) {
return exceptionFromMinorVersion;
} else {
return minorMidPointVersion;
}
}

@NotNull
private String getMajorMidPointVersion() {
String version = localizationService
.translate(LocalizableMessageBuilder.buildKey("midPointVersion"), Locale.getDefault());
String noSnapshot = removeSuffix(version);
private String getMinorMidPointVersion(String fullMidPointVersion) {
String noSnapshot = removeSuffix(fullMidPointVersion);
int firstDot = noSnapshot.indexOf('.');
if (firstDot < 0) {
throw new SystemException("Couldn't determine midPoint version from '" + version + "'");
throw new SystemException("Couldn't determine midPoint version from '" + fullMidPointVersion + "'");
}
int secondDot = noSnapshot.indexOf('.', firstDot+1);
if (secondDot < 0) {
Expand All @@ -296,6 +325,11 @@ private String getMajorMidPointVersion() {
}
}

private String getMidPointVersion() {
return localizationService
.translate(LocalizableMessageBuilder.buildKey("midPointVersion"), Locale.getDefault());
}

private String removeSuffix(String version) {
Matcher matcher = VERSION_SUFFIX_PATTERN.matcher(version);
if (matcher.find()) {
Expand Down

0 comments on commit 6edaec2

Please sign in to comment.