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 Nov 4, 2019
2 parents d79338d + 3c072a0 commit 7ccd9fc
Show file tree
Hide file tree
Showing 23 changed files with 336 additions and 110 deletions.
Expand Up @@ -64,6 +64,10 @@
<input wicket:id="fullProcessing" type="checkbox" name="optionsRadios" checked>
<wicket:message key="importOptionsPanel.fullProcessing"/>
</label>
<label class="col-lg-2 checkbox-inline">
<input wicket:id="compatMode" type="checkbox" name="optionsRadios" checked>
<wicket:message key="importOptionsPanel.compatMode"/>
</label>
</div>
</div>
</div>
Expand Down
Expand Up @@ -31,6 +31,7 @@ public class ImportOptionsPanel extends Panel {
private static final String ID_VALIDATE_DYNAMIC_SCHEMA = "validateDynamicSchema";
private static final String ID_VALIDATE_STATIC_SCHEMA = "validateStaticSchema";
private static final String ID_FULL_PROCESSING = "fullProcessing";
private static final String ID_COMPAT_MODE = "compatMode";
private static final String ID_ERRORS = "errors";

private IModel<ImportOptionsType> model;
Expand Down Expand Up @@ -58,5 +59,6 @@ private void initLayout() {
add(new CheckBox(ID_VALIDATE_STATIC_SCHEMA, new PropertyModel<>(model, "validateStaticSchema")));
add(new CheckBox(ID_FULL_PROCESSING, fullProcessingModel));
add(new TextField<Integer>(ID_ERRORS, new PropertyModel<>(model, "stopAfterErrors")));
add(new CheckBox(ID_COMPAT_MODE, new PropertyModel<>(model, "compatMode")));
}
}
Expand Up @@ -23,6 +23,7 @@
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;

import com.evolveum.midpoint.prism.PrismParserNoIO;
import com.evolveum.midpoint.util.QNameUtil;
import org.apache.commons.lang.StringUtils;
import org.codehaus.staxmate.dom.DOMConverter;
Expand Down Expand Up @@ -75,6 +76,7 @@ public class LegacyValidator {
private long progress = 0;
private long errors = 0;
private long stopAfterErrors = 0;
private boolean compatMode = false;

public LegacyValidator(PrismContext prismContext) {
this.prismContext = prismContext;
Expand Down Expand Up @@ -158,6 +160,14 @@ public long getErrors() {
return errors;
}

public boolean isCompatMode() {
return compatMode;
}

public void setCompatMode(boolean compatMode) {
this.compatMode = compatMode;
}

public void validate(String lexicalRepresentation, OperationResult validationResult, String objectResultOperationName) {
try {
try (ByteArrayInputStream is = new ByteArrayInputStream(lexicalRepresentation.getBytes(INPUT_STREAM_CHARSET))) {
Expand Down Expand Up @@ -373,7 +383,11 @@ private EventResult validateObjectInternal(Element objectElement, OperationResul
return EventResult.skipObject();
}

PrismObject<? extends Objectable> object = prismContext.parserFor(objectElement).parse();
PrismParserNoIO parser = prismContext.parserFor(objectElement);
if (compatMode) {
parser = parser.compat();
}
PrismObject<? extends Objectable> object = parser.parse();

try {
object.checkConsistence();
Expand Down
Expand Up @@ -12,6 +12,8 @@
import com.evolveum.midpoint.prism.impl.lex.LexicalProcessor;
import com.evolveum.midpoint.prism.impl.xnode.RootXNodeImpl;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand All @@ -26,6 +28,8 @@
*/
abstract class PrismParserImpl implements PrismParser {

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

@NotNull private final ParserSource source;
private final String language;
@NotNull private final ParsingContext context;
Expand Down
Expand Up @@ -273,7 +273,7 @@ private <C extends Containerable> PrismContainerValue<C> parseContainerValueFrom
ItemDefinition itemDef = locateItemDefinition(itemName, complexTypeDefinition, entry.getValue());
if (itemDef == null) {
SchemaMigration migration = determineSchemaMigration(complexTypeDefinition, itemName, pc);
if (migration != null && !pc.isStrict()) {
if (migration != null && pc.isCompat()) {
if (migration.getOperation() == SchemaMigrationOperation.REMOVED) {
LOGGER.warn("Item {} was removed from the schema, skipping", itemName);
continue;
Expand Down
Expand Up @@ -173,6 +173,14 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="compatMode" type="xsd:boolean" minOccurs="0" default="false">
<xsd:annotation>
<xsd:documentation>
Compatibility model. If selected then the data parsing will be less strict.
E.g. removed element will be ingnored.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>

Expand Down
Expand Up @@ -38,7 +38,6 @@
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBElement;
Expand Down Expand Up @@ -148,19 +147,29 @@ public void testParseModernRoleFromJaxb() throws SchemaException, SAXException,
@Test
public void testParseLegacyRoleFromJaxb() throws SchemaException, SAXException, IOException, JAXBException {
System.out.println("\n\n ===[ testParseLegacyRoleFromJaxb ]===\n");
testParseRoleFromJaxb(new File(TestConstants.COMMON_DIR, "role-legacy.xml"));

PrismParser parser = PrismTestUtil.getPrismContext()
.parserFor(new File(TestConstants.COMMON_DIR, "role-legacy.xml"))
.compat();

// WHEN
PrismObject<RoleType> role = parser.parse();

// THEN
System.out.println("Parsed role:");
System.out.println(role.debugDump(1));

role.checkConsistence();
assertPropertyValue(role, RoleType.F_NAME, PrismTestUtil.createPolyString("r3"));
}

public void testParseRoleFromJaxb(File file) throws SchemaException, SAXException, IOException, JAXBException {

PrismContext prismContext = PrismTestUtil.getPrismContext();

RoleType roleType = PrismTestUtil.parseObjectable(file, RoleType.class);
PrismParser parser = PrismTestUtil.getPrismContext().parserFor(file);

// WHEN

PrismObject<RoleType> role = roleType.asPrismObject();
role.revive(prismContext);
PrismObject<RoleType> role = parser.parse();

// THEN
System.out.println("Parsed role:");
Expand Down
Expand Up @@ -131,6 +131,8 @@ protected void process(String desc, ParsingFunction<T> parser, SerializingFuncti

System.out.println("================== Starting test for '" + desc + "' (serializer: " + serId + ") ==================");

try {

T value = parser.apply(prismContext.parserFor(getFile()));
assertResolvableRawValues(value); // should be right here, before any getValue is called (TODO reconsider)

Expand All @@ -157,6 +159,10 @@ protected void process(String desc, ParsingFunction<T> parser, SerializingFuncti

assertTrue("Values not equal", value.equals(reparsed, EquivalenceStrategy.NOT_LITERAL));
}

} catch (SchemaException e) {
throw new SchemaException("Error processing file "+getFile().getPath()+": " + e.getMessage(), e);
}
}

protected abstract void assertPrismValue(T value) throws SchemaException;
Expand Down
Expand Up @@ -85,7 +85,12 @@ public void testParseRoundTripAsPO() throws Exception{
@Test
public void testSkipItems() throws SchemaException, IOException {
PrismContext prismContext = getPrismContext();
PrismObject<UserType> jack = prismContext.parserFor(getFile()).language(language).parse();
PrismObject<UserType> jack;
try {
jack = prismContext.parserFor(getFile()).language(language).parse();
} catch (SchemaException e) {
throw new SchemaException("Error parsing file "+getFile().getPath()+": " + e.getMessage(), e);
}
String serialized = prismContext.serializerFor(language)
.itemsToSkip(Arrays.asList(UserType.F_ORGANIZATIONAL_UNIT, UserType.F_LINK_REF, UserType.F_ASSIGNMENT))
.serialize(jack);
Expand Down
Expand Up @@ -6,16 +6,13 @@
*/
package com.evolveum.midpoint.schema.validator;

import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;

import java.io.File;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.util.PrismAsserts;
import com.evolveum.midpoint.util.exception.SchemaException;
import org.testng.annotations.Test;

import com.evolveum.midpoint.prism.PrismObject;
Expand All @@ -24,6 +21,8 @@
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;

import static org.testng.AssertJUnit.*;

/**
* @author semancik
*
Expand All @@ -32,9 +31,14 @@ public class TestObjectValidator extends AbstractSchemaTest {

public static final File TEST_DIR = new File("src/test/resources/validator");

// Contains elements that are deprecated and planned for removal, but still valid.
protected static final File ROLE_ONE_FILE = new File(TEST_DIR, "role-one.xml");
protected static final String ROLE_ONE_OID = "0d70504c-d094-11e8-b0cc-675c492577e7";

// Contains elements that are already removed
protected static final File ROLE_ONE_LEGACY_FILE = new File(TEST_DIR, "role-one-legacy.xml");
protected static final String ROLE_ONE_LEGACY_OID = "50c00734-fee7-11e9-8f2f-4bf21a89fafb";

@Test
public void testValidateRoleOneDefault() throws Exception {
final String TEST_NAME = "testValidateRoleOneDefault";
Expand Down Expand Up @@ -82,6 +86,65 @@ public void testValidateRoleOneDeprecated() throws Exception {
assertWarnings(validationResult, RoleType.F_ROLE_TYPE);
}

/**
* ROLE_ONE_LEGACY_FILE contains removed elements. This is COMPAT parsing, therefore
* the parsing should go well.
*/
@Test
public void testValidateRoleOneLegacyCompat() throws Exception {
final String TEST_NAME = "testValidateRoleOneLegacyCompat";
displayTestTile(TEST_NAME);

// GIVEN

ObjectValidator validator = createValidator();
validator.setWarnDeprecated(true);

PrismObject<RoleType> object = PrismTestUtil.getPrismContext()
.parserFor(ROLE_ONE_LEGACY_FILE)
.compat()
.parse();
System.out.println("Object before validation:");
System.out.println(object.debugDump(1));

// WHEN
ValidationResult validationResult = validator.validate(object);

// THEN
System.out.println("Validation result:");
System.out.println(validationResult.debugDump(1));

assertWarnings(validationResult, RoleType.F_ROLE_TYPE);
}

/**
* ROLE_ONE_LEGACY_FILE contains removed elements. This is STRICT parsing, therefore
* the parsing should fail.
*/
@Test
public void testValidateRoleOneLegacyStrict() throws Exception {
final String TEST_NAME = "testValidateRoleOneLegacyStrict";
displayTestTile(TEST_NAME);

// GIVEN

ObjectValidator validator = createValidator();
validator.setWarnDeprecated(true);

try {
PrismObject<RoleType> object = PrismTestUtil.getPrismContext()
.parserFor(ROLE_ONE_LEGACY_FILE)
.strict()
.parse();
System.out.println("Unexpected parsed object:");
System.out.println(object.debugDump(1));
fail("Unexpected success");
} catch (SchemaException e) {
// this is expected
}

}

// We have no planned removal annotations in 4.0. Nothing to test.
// @Test
// public void testValidateRoleOnePlannedRemoval() throws Exception {
Expand Down
7 changes: 0 additions & 7 deletions infra/schema/src/test/resources/common/password-policy.xml
Expand Up @@ -10,13 +10,6 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<name>Testing Complex Password Policy</name>
<description>Testing complex password policy</description>
<lifetime>
<expiration>999</expiration>
<warnBeforeExpiration>9</warnBeforeExpiration>
<lockAfterExpiration>0</lockAfterExpiration>
<minPasswordAge>0</minPasswordAge>
<passwordHistoryLength>0</passwordHistoryLength>
</lifetime>
<stringPolicy>
<description>Testing string policy</description>
<limitations>
Expand Down
Expand Up @@ -66,16 +66,6 @@
<targetName>resource1</targetName>
</resourceRef>
</construction>
<trigger>
<assignmentPath>
<segment>
<sourceRef oid="123">
<targetName>source123</targetName>
</sourceRef>
</segment>
</assignmentPath>
<constraint></constraint>
</trigger>
</assignment>

<activation>
Expand Down
10 changes: 0 additions & 10 deletions infra/schema/src/test/resources/common/xml/ns/user-jack.xml
Expand Up @@ -55,16 +55,6 @@
<targetName>resource1</targetName>
</resourceRef>
</construction>
<trigger>
<assignmentPath>
<segment>
<sourceRef oid="123">
<targetName>source123</targetName>
</sourceRef>
</segment>
</assignmentPath>
<constraint></constraint>
</trigger>
</assignment>

<activation>
Expand Down
7 changes: 0 additions & 7 deletions infra/schema/src/test/resources/common/yaml/ns/user-jack.yaml
Expand Up @@ -36,13 +36,6 @@ object: !http://midpoint.evolveum.com/xml/ns/public/common/common-3/UserType
resourceRef:
oid: 2f9b9299-5555-5555-5555-000000001111
targetName: resource1
trigger:
assignmentPath:
segment:
sourceRef:
oid: 123
targetName: source123
constraint: {}
activation:
administrativeStatus: enabled
fullName: Jack Sparrow
Expand Down
38 changes: 38 additions & 0 deletions infra/schema/src/test/resources/validator/role-one-legacy.xml
@@ -0,0 +1,38 @@
<!--
~ Copyright (c) 2010-2019 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<!-- Contains elements that are already removed -->

<role oid="0d70504c-d094-11e8-b0cc-675c492577e7"
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3">

<name>One</name> <!-- OK -->
<description>First role</description> <!-- OK -->

<roleType>lab</roleType> <!-- deprecated, but not plannedRemoval -->

<approverExpression> <!-- removed in .0 -->
<script>
<code>midpoint.oid2ort(user.getOid())</code>
</script>
</approverExpression>

<policyConstraints> <!-- removed in .0 -->
<minAssignees>
<enforcement>report</enforcement>
<multiplicity>2</multiplicity>
</minAssignees>
<minAssignees>
<multiplicity>1</multiplicity>
</minAssignees>
<maxAssignees>
<multiplicity>unbounded</multiplicity>
</maxAssignees>
</policyConstraints>

</role>

0 comments on commit 7ccd9fc

Please sign in to comment.