diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java index 72b2a7cac81..8b163dfb3b1 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismPropertyValue.java @@ -413,7 +413,14 @@ public boolean equalsComplex(PrismPropertyValue other, boolean ignoreMetadata } if (matchingRule != null) { - return matchingRule.match(thisRealValue, otherRealValue); + try { + return matchingRule.match(thisRealValue, otherRealValue); + } catch (SchemaException e) { + // At least one of the values is invalid. But we do not want to throw exception from + // a comparison operation. That will make the system very fragile. Let's fall back to + // ordinary equality mechanism instead. + return thisRealValue.equals(otherRealValue); + } } else { if (thisRealValue instanceof Element && diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/match/DistinguishedNameMatchingRule.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/match/DistinguishedNameMatchingRule.java index 27b7265e6fd..92dc0ffb5ac 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/match/DistinguishedNameMatchingRule.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/match/DistinguishedNameMatchingRule.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.util.DOMUtil; +import com.evolveum.midpoint.util.exception.SchemaException; /** * Matching rule for LDAP distinguished name (DN). @@ -51,7 +52,7 @@ public boolean isSupported(QName xsdType) { * @see com.evolveum.midpoint.model.match.MatchingRule#match(java.lang.Object, java.lang.Object) */ @Override - public boolean match(String a, String b) { + public boolean match(String a, String b) throws SchemaException { if (StringUtils.isBlank(a) && StringUtils.isBlank(b)) { return true; } @@ -62,13 +63,13 @@ public boolean match(String a, String b) { try { dnA = new LdapName(a); } catch (InvalidNameException e) { - throw new IllegalArgumentException("String '"+a+"' is not a DN: "+e.getMessage(), e); + throw new SchemaException("String '"+a+"' is not a DN: "+e.getMessage(), e); } LdapName dnB; try { dnB = new LdapName(b); } catch (InvalidNameException e) { - throw new IllegalArgumentException("String '"+b+"' is not a DN: "+e.getMessage(), e); + throw new SchemaException("String '"+b+"' is not a DN: "+e.getMessage(), e); } return dnA.equals(dnB); } @@ -77,7 +78,7 @@ public boolean match(String a, String b) { * @see com.evolveum.midpoint.prism.match.MatchingRule#normalize(java.lang.Object) */ @Override - public String normalize(String original) { + public String normalize(String original) throws SchemaException { if (StringUtils.isBlank(original)) { return null; } @@ -85,13 +86,13 @@ public String normalize(String original) { try { dn = new LdapName(original); } catch (InvalidNameException e) { - throw new IllegalArgumentException("String '"+original+"' is not a DN: "+e.getMessage(), e); + throw new SchemaException("String '"+original+"' is not a DN: "+e.getMessage(), e); } return StringUtils.lowerCase(dn.toString()); } @Override - public boolean matchRegex(String a, String regex) { + public boolean matchRegex(String a, String regex) throws SchemaException { a = normalize(a); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/match/MatchingRule.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/match/MatchingRule.java index 62545bf3182..165b53eb7ad 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/match/MatchingRule.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/match/MatchingRule.java @@ -19,6 +19,8 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.util.exception.SchemaException; + /** * Interface for generic matching rules. The responsibility of a matching rule is to decide if * two objects of the same type match. This may seem a simple thing to do but the details may get @@ -43,17 +45,17 @@ public interface MatchingRule { /** * Matches two objects. */ - boolean match(T a, T b); + boolean match(T a, T b) throws SchemaException; /** * Matches value against given regex. */ - boolean matchRegex(T a, String regex); + boolean matchRegex(T a, String regex) throws SchemaException; /** * Returns a normalized version of the value. * For normalized version the following holds: * if A matches B then normalize(A) == normalize(B) */ - T normalize(T original); + T normalize(T original) throws SchemaException; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualFilter.java index 2ab201488f8..b15ebfde373 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/EqualFilter.java @@ -227,8 +227,17 @@ private boolean isInFilterItem(PrismPropertyValue v, Item filterItem, MatchingRu } PrismPropertyValue filterV = (PrismPropertyValue) filterValue; - if (matchingRule.match(filterV.getValue(), v.getValue())){ - return true; + try { + if (matchingRule.match(filterV.getValue(), v.getValue())){ + return true; + } + } catch (SchemaException e) { + // At least one of the values is invalid. But we do not want to throw exception from + // a comparison operation. That will make the system very fragile. Let's fall back to + // ordinary equality mechanism instead. + if (filterV.getValue().equals(v.getValue())) { + return true; + } } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismAsserts.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismAsserts.java index e8add882645..9af187711b5 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismAsserts.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/PrismAsserts.java @@ -735,10 +735,15 @@ public static void assertValues(String message, Collection void assertSets(String message, Collection actualValues, T... expectedValues) { - assertSets(message, null, actualValues, expectedValues); + try { + assertSets(message, null, actualValues, expectedValues); + } catch (SchemaException e) { + // no matching rule. should not happen + throw new IllegalStateException(e.getMessage(), e); + } } - public static void assertSets(String message, MatchingRule matchingRule, Collection actualValues, T... expectedValues) { + public static void assertSets(String message, MatchingRule matchingRule, Collection actualValues, T... expectedValues) throws SchemaException { assertNotNull("Null set in " + message, actualValues); assertEquals("Wrong number of values in " + message+ "; expected (real values) " +PrettyPrinter.prettyPrint(expectedValues)+"; has (pvalues) "+actualValues, @@ -901,7 +906,7 @@ public static void assertEquals(String message, Object expected, Object actual) + ", was " + MiscUtil.getValueWithClass(actual); } - public static void assertEquals(String message, MatchingRule matchingRule, T expected, T actual) { + public static void assertEquals(String message, MatchingRule matchingRule, T expected, T actual) throws SchemaException { assert equals(matchingRule, expected, actual) : message + ": expected " + MiscUtil.getValueWithClass(expected) + ", was " + MiscUtil.getValueWithClass(actual); @@ -917,7 +922,7 @@ static void fail(String message) { assert false: message; } - private static boolean equals(MatchingRule matchingRule, T a, T b) { + private static boolean equals(MatchingRule matchingRule, T a, T b) throws SchemaException { if (a == null && b == null) { return true; } diff --git a/infra/prism/src/test/java/com/evolveum/midpoint/prism/match/TestMatchingRule.java b/infra/prism/src/test/java/com/evolveum/midpoint/prism/match/TestMatchingRule.java index 71ec1d3515f..e252c31bad1 100644 --- a/infra/prism/src/test/java/com/evolveum/midpoint/prism/match/TestMatchingRule.java +++ b/infra/prism/src/test/java/com/evolveum/midpoint/prism/match/TestMatchingRule.java @@ -118,15 +118,15 @@ public void testPolyStringNorm() throws Exception { assertNoMatch(rule, new PolyString("Bar", "bar"), new PolyString("Bar", "barbar")); } - private void assertMatch(MatchingRule rule, T a, T b) { + private void assertMatch(MatchingRule rule, T a, T b) throws SchemaException { assertTrue("Values '"+a+"' and '"+b+"' does not match; rule: "+rule, rule.match(a, b)); } - private void assertNoMatch(MatchingRule rule, T a, T b) { + private void assertNoMatch(MatchingRule rule, T a, T b) throws SchemaException { assertFalse("Values '"+a+"' and '"+b+"' DOES match but they should not; rule: "+rule, rule.match(a, b)); } - private void assertNormalized(MatchingRule rule, String expected, String original) { + private void assertNormalized(MatchingRule rule, String expected, String original) throws SchemaException { assertEquals("Normalized value does not match", expected, rule.normalize(original)); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java index 1c6afa3269a..838b55b4c03 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/integrity/ShadowIntegrityCheckResultHandler.java @@ -287,7 +287,7 @@ protected boolean handleObject(PrismObject shadow, Task workerTask, return true; } - private void checkShadow(ShadowCheckResult checkResult, PrismObject shadow, Task workerTask, OperationResult result) { + private void checkShadow(ShadowCheckResult checkResult, PrismObject shadow, Task workerTask, OperationResult result) throws SchemaException { ShadowType shadowType = shadow.asObjectable(); ObjectReferenceType resourceRef = shadowType.getResourceRef(); if (LOGGER.isTraceEnabled()) { @@ -521,7 +521,7 @@ private String skippedForDryRun() { } } - private void doCheckNormalization(ShadowCheckResult checkResult, RefinedAttributeDefinition identifier, String value, ObjectTypeContext context) { + private void doCheckNormalization(ShadowCheckResult checkResult, RefinedAttributeDefinition identifier, String value, ObjectTypeContext context) throws SchemaException { QName matchingRuleQName = identifier.getMatchingRuleQName(); if (matchingRuleQName == null) { return; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java index 824b27a277a..c1242d80bab 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java @@ -582,21 +582,6 @@ private void decideIfTolerateAssociation(LensProjectionContext accCtx, } } - private boolean matchPattern(List patterns, - PrismPropertyValue isPValue, ValueMatcher valueMatcher) { - if (patterns == null || patterns.isEmpty()) { - return false; - } - for (String toleratePattern : patterns) { - if (valueMatcher.matches(isPValue.getValue(), toleratePattern)) { - return true; - } - - } - return false; - } - - private void recordDelta(ValueMatcher valueMatcher, LensProjectionContext accCtx, ResourceAttributeDefinition attrDef, ModificationType changeType, T value, ObjectType originObject) throws SchemaException { @@ -677,7 +662,7 @@ private boolean isToBeDeleted(ItemDelta existingDelta, ValueMatcher valueMat for (Object isInDeltaValue : existingDelta.getValuesToDelete()) { if (isInDeltaValue instanceof PrismPropertyValue){ PrismPropertyValue isInRealValue = (PrismPropertyValue) isInDeltaValue; - if (valueMatcher.match(isInRealValue.getValue(), value)) { + if (matchValue(isInRealValue.getValue(), value, valueMatcher)) { return true; } } @@ -693,7 +678,7 @@ private boolean isInValues(ValueMatcher valueMatcher, Object shouldBeValue, return false; } for (PrismPropertyValue isPValue : arePValues) { - if (valueMatcher.match(isPValue.getValue(), shouldBeValue)) { + if (matchValue(isPValue.getValue(), shouldBeValue, valueMatcher)) { return true; } } @@ -707,7 +692,7 @@ private boolean isInAssociationValues(ValueMatcher valueMatcher, ShadowAssociati return false; } for (PrismContainerValue isPValue : arePValues) { - if (valueMatcher.match(isPValue.getValue(), shouldBeValue)) { + if (matchValue(isPValue.getValue(), shouldBeValue, valueMatcher)) { return true; } } @@ -739,7 +724,7 @@ private boolean isInPvwoValues(ValueMatcher valueMatcher, Object value, } PrismPropertyValue shouldBePPValue = shouldBePvwo.getPropertyValue(); Object shouldBeValue = shouldBePPValue.getValue(); - if (valueMatcher.match(value, shouldBeValue)) { + if (matchValue(value, shouldBeValue, valueMatcher)) { return true; } } @@ -759,11 +744,40 @@ private boolean isInCvwoAssociationValues(ValueMatcher valueMatcher, ShadowAssoc } PrismContainerValue shouldBePCValue = shouldBeCvwo.getItemValue(); ShadowAssociationType shouldBeValue = shouldBePCValue.getValue(); - if (valueMatcher.match(value, shouldBeValue)) { + if (matchValue(value, shouldBeValue, valueMatcher)) { return true; } } return false; } + + + private boolean matchValue(T realA, T realB, ValueMatcher valueMatcher) { + try { + return valueMatcher.match(realA, realB); + } catch (SchemaException e) { + LOGGER.warn("Value '{}' or '{}' is invalid: {}", realA, realB, e.getMessage(), e); + return false; + } + } + + private boolean matchPattern(List patterns, + PrismPropertyValue isPValue, ValueMatcher valueMatcher) { + if (patterns == null || patterns.isEmpty()) { + return false; + } + for (String toleratePattern : patterns) { + try { + if (valueMatcher.matches(isPValue.getValue(), toleratePattern)) { + return true; + } + } catch (SchemaException e) { + LOGGER.warn("Value '{}' is invalid: {}", isPValue.getValue(), e.getMessage(), e); + return false; + } + + } + return false; + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ValueMatcher.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ValueMatcher.java index ce3ff58d60f..11dc3b88938 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ValueMatcher.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ValueMatcher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2015 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,18 +49,27 @@ public static ValueMatcher createMatcher(RefinedAttributeDefinition rAttr return new ValueMatcher((MatchingRule) matchingRule); } - public boolean match(T realA, T realB) { + public boolean match(T realA, T realB) throws SchemaException { return matchingRule.match(realA, realB); } - public boolean matches(T realValue, String regex){ + public boolean matches(T realValue, String regex) throws SchemaException{ return matchingRule.matchRegex(realValue, regex); } public boolean hasRealValue(PrismProperty property, PrismPropertyValue pValue) { for (T existingRealValue: property.getRealValues()) { - if (matchingRule.match(existingRealValue, pValue.getValue())) { - return true; + try { + if (matchingRule.match(existingRealValue, pValue.getValue())) { + return true; + } + } catch (SchemaException e) { + // At least one of the values is invalid. But we do not want to throw exception from + // a comparison operation. That will make the system very fragile. Let's fall back to + // ordinary equality mechanism instead. + if (existingRealValue.equals(pValue.getValue())) { + return true; + } } } return false; @@ -71,8 +80,17 @@ public boolean isRealValueToAdd(PropertyDelta delta, PrismPropertyValue pV return false; } for (PrismPropertyValue existingPValue: delta.getValuesToAdd()) { - if (matchingRule.match(existingPValue.getValue(), pValue.getValue())) { - return true; + try { + if (matchingRule.match(existingPValue.getValue(), pValue.getValue())) { + return true; + } + } catch (SchemaException e) { + // At least one of the values is invalid. But we do not want to throw exception from + // a comparison operation. That will make the system very fragile. Let's fall back to + // ordinary equality mechanism instead. + if (existingPValue.getValue().equals(pValue.getValue())) { + return true; + } } } return false; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index e3717a0e25d..783f81d31d5 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -1658,10 +1658,26 @@ private PrismObject completeShadow(ProvisioningContext ctx, PrismObj PrismObject entitlementRepoShadow; PrismObject entitlementShadow = (PrismObject) identifierContainer.getUserData(ResourceObjectConverter.FULL_SHADOW_KEY); if (entitlementShadow == null) { - entitlementRepoShadow = shadowManager.lookupShadowInRepository(ctxEntitlement, identifierContainer, parentResult); - if (entitlementRepoShadow == null) { - entitlementShadow = resouceObjectConverter.locateResourceObject(ctxEntitlement, entitlementIdentifiers, parentResult); - entitlementRepoShadow = createShadowInRepository(ctxEntitlement, entitlementShadow, parentResult); + try { + entitlementRepoShadow = shadowManager.lookupShadowInRepository(ctxEntitlement, identifierContainer, parentResult); + if (entitlementRepoShadow == null) { + entitlementShadow = resouceObjectConverter.locateResourceObject(ctxEntitlement, entitlementIdentifiers, parentResult); + entitlementRepoShadow = createShadowInRepository(ctxEntitlement, entitlementShadow, parentResult); + } + } catch (ObjectNotFoundException e) { + // The entitlement to which we point is not there. + // Simply ignore this association value. + parentResult.muteLastSubresultError(); + LOGGER.warn("The entitlement identified by {} referenced from {} does not exist. Skipping.", + new Object[]{associationCVal, resourceShadow}); + continue; + } catch (SchemaException e) { + // The entitlement to which we point is not bad. + // Simply ignore this association value. + parentResult.muteLastSubresultError(); + LOGGER.warn("The entitlement identified by {} referenced from {} violates the schema. Skipping. Original error: {}", + new Object[]{associationCVal, resourceShadow, e.getMessage(), e}); + continue; } } else { entitlementRepoShadow = lookupOrCreateShadowInRepository(ctxEntitlement, entitlementShadow, parentResult); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index 8ff7fd270db..ce9ca468b1f 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -803,7 +803,7 @@ private void normalizeDelta(ItemDelta,PrismPropertyDef } } - private void normalizeValues(Collection> values, MatchingRule matchingRule){ + private void normalizeValues(Collection> values, MatchingRule matchingRule) throws SchemaException { for (PrismPropertyValue pval: values) { T normalizedRealValue = matchingRule.normalize(pval.getValue()); pval.setValue(normalizedRealValue); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java index 716cd469f8f..5e96b73d7dc 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java @@ -174,12 +174,19 @@ public PrismObject fetchObject(Class type, * * The call to this method will return only after all the callbacks were * called, therefore it is not asynchronous in a strict sense. + * + * If nothing is found the method should behave as if there is an empty result set + * (handler is never called) and the call should result in a success. + * The ObjectNotFoundException should be throws only if there is an error in search + * parameters, e.g. if search base points to an non-existent object. * * @param objectClass * @param handler * @return * @throws CommunicationException * @throws SchemaException error converting object from the native (connector) format + * @throws ObjectNotFoundException if something from the search parameters refers non-existent object. + * e.g. if search base points to an non-existent object. */ public SearchResultMetadata search(ObjectClassComplexTypeDefinition objectClassDefinition, ObjectQuery query, @@ -188,7 +195,8 @@ public SearchResultMetadata search(ObjectClassComplexType PagedSearchCapabilityType pagedSearchConfigurationType, SearchHierarchyConstraints searchHierarchyConstraints, OperationResult parentResult) - throws CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException; + throws CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException, + ObjectNotFoundException; /** * Counts objects on resource. diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java index 47529810a8b..c3317fd42e8 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java @@ -65,6 +65,7 @@ import org.identityconnectors.framework.api.operations.TestApiOp; import org.identityconnectors.framework.api.operations.UpdateApiOp; import org.identityconnectors.framework.common.exceptions.AlreadyExistsException; +import org.identityconnectors.framework.common.exceptions.UnknownUidException; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.AttributeInfo; @@ -2117,7 +2118,8 @@ public SearchResultMetadata search(ObjectClassComplexType PagedSearchCapabilityType pagedSearchCapabilityType, SearchHierarchyConstraints searchHierarchyConstraints, OperationResult parentResult) - throws CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException { + throws CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException, + ObjectNotFoundException { // Result type for this operation final OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() @@ -2258,6 +2260,8 @@ public boolean handle(ConnectorObject connectorObject) { // exception if (midpointEx instanceof CommunicationException) { throw (CommunicationException) midpointEx; + } else if (midpointEx instanceof ObjectNotFoundException) { + throw (ObjectNotFoundException) midpointEx; } else if (midpointEx instanceof GenericFrameworkException) { throw (GenericFrameworkException) midpointEx; } else if (midpointEx instanceof SchemaException) { diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/ProvisioningTestUtil.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/ProvisioningTestUtil.java index 5a6fef2e6fc..c41dbc99b80 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/ProvisioningTestUtil.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/ProvisioningTestUtil.java @@ -172,7 +172,7 @@ public static void assertAttribute(PrismObject resource, Shado } public static void assertAttribute(PrismObject resource, ShadowType shadow, MatchingRule matchingRule, - QName attrQname, T... expectedValues) { + QName attrQname, T... expectedValues) throws SchemaException { List actualValues = ShadowUtil.getAttributeValues(shadow, attrQname); PrismAsserts.assertSets("attribute "+attrQname+" in " + shadow, matchingRule, actualValues, expectedValues); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/AbstractDummyTest.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/AbstractDummyTest.java index eef0a010bbc..60857010e54 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/AbstractDummyTest.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/AbstractDummyTest.java @@ -141,6 +141,8 @@ public abstract class AbstractDummyTest extends AbstractIntegrationTest { protected static final String PRIVILEGE_BARGAIN_FILENAME = TEST_DIR + "privilege-bargain.xml"; protected static final String PRIVILEGE_BARGAIN_OID = "c0c010c0-d34d-b44f-f11d-3332eeff0001"; protected static final String PRIVILEGE_BARGAIN_NAME = "bargain"; + + protected static final String PRIVILEGE_NONSENSE_NAME = "NoNsEnSe"; protected static final String FILENAME_ACCOUNT_SCRIPT = TEST_DIR + "account-script.xml"; protected static final String ACCOUNT_NEW_SCRIPT_OID = "c0c010c0-d34d-b44f-f11d-33322212abcd"; @@ -301,7 +303,7 @@ protected void assertAttribute(ShadowType shadow, QName attrName, T... expec ProvisioningTestUtil.assertAttribute(resource, shadow, attrName, expectedValues); } - protected void assertAttribute(ShadowType shadow, MatchingRule matchingRule, QName attrName, T... expectedValues) { + protected void assertAttribute(ShadowType shadow, MatchingRule matchingRule, QName attrName, T... expectedValues) throws SchemaException { ProvisioningTestUtil.assertAttribute(resource, shadow, matchingRule, attrName, expectedValues); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java index 5cffd77231f..a0ba6feeeba 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java @@ -3238,8 +3238,8 @@ public void test222EntitleAccountWillPillage() throws Exception { } @Test - public void test222bEntitleAccountWillBargain() throws Exception { - final String TEST_NAME = "test222bEntitleAccountWillBargain"; + public void test223EntitleAccountWillBargain() throws Exception { + final String TEST_NAME = "test223EntitleAccountWillBargain"; TestUtil.displayTestTile(TEST_NAME); Task task = taskManager.createTaskInstance(TestDummy.class.getName() @@ -3289,8 +3289,8 @@ public void test222bEntitleAccountWillBargain() throws Exception { * Reads the will accounts, checks that both entitlements are there. */ @Test - public void test223GetPillagingPirateWill() throws Exception { - final String TEST_NAME = "test223GetPillagingPirateWill"; + public void test224GetPillagingPirateWill() throws Exception { + final String TEST_NAME = "test224GetPillagingPirateWill"; TestUtil.displayTestTile(TEST_NAME); Task task = taskManager.createTaskInstance(TestDummy.class.getName() @@ -3343,8 +3343,8 @@ public void test223GetPillagingPirateWill() throws Exception { * in the associations. */ @Test - public void test224GetFoolishPirateWill() throws Exception { - final String TEST_NAME = "test224GetFoolishPirateWill"; + public void test225GetFoolishPirateWill() throws Exception { + final String TEST_NAME = "test225GetFoolishPirateWill"; TestUtil.displayTestTile(TEST_NAME); // GIVEN @@ -3409,10 +3409,79 @@ public void test224GetFoolishPirateWill() throws Exception { assertDummyResourceGroupMembersReadCountIncrement(null, 0); assertSteadyResource(); } + + /** + * Make the account point to a privilege that does not exist. + * MidPoint should ignore such privilege. + */ + @Test + public void test226WillNonsensePrivilege() throws Exception { + final String TEST_NAME = "test226WillNonsensePrivilege"; + TestUtil.displayTestTile(TEST_NAME); + + Task task = taskManager.createTaskInstance(TestDummy.class.getName() + + "." + TEST_NAME); + OperationResult result = task.getResult(); + + DummyAccount dummyAccount = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); + dummyAccount.addAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, PRIVILEGE_NONSENSE_NAME); + + syncServiceMock.reset(); + + // WHEN + PrismObject shadow = provisioningService.getObject(ShadowType.class, ACCOUNT_WILL_OID, null, task, result); + + // THEN + result.computeStatus(); + display("Account", shadow); + + display(result); + TestUtil.assertSuccess(result); + assertConnectorOperationIncrement(3); + + assertDummyResourceGroupMembersReadCountIncrement(null, 0); + + PrismObject foolsShadow = findShadowByName(new QName(RESOURCE_DUMMY_NS, OBJECTCLAS_GROUP_LOCAL_NAME), "fools", resource, result); + assertNotNull("No shadow for group fools", foolsShadow); + + assertDummyResourceGroupMembersReadCountIncrement(null, 0); + + assertEntitlementGroup(shadow, GROUP_PIRATES_OID); + assertEntitlementGroup(shadow, foolsShadow.getOid()); + assertEntitlementPriv(shadow, PRIVILEGE_PILLAGE_OID); + assertEntitlementPriv(shadow, PRIVILEGE_BARGAIN_OID); + + assertDummyResourceGroupMembersReadCountIncrement(null, 0); + + // Just make sure nothing has changed + dummyAccount = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); + assertNotNull("Account will is gone!", dummyAccount); + Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); + PrismAsserts.assertSets("Wrong account privileges", accountProvileges, + PRIVILEGE_PILLAGE_NAME, PRIVILEGE_BARGAIN_NAME, PRIVILEGE_NONSENSE_NAME); + + // Make sure that privilege object is still there + DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); + assertNotNull("Privilege object is gone!", priv); + DummyPrivilege priv2 = getDummyPrivilegeAssert(PRIVILEGE_BARGAIN_NAME, bargainIcfUid); + assertNotNull("Privilege object (bargain) is gone!", priv2); + + assertDummyResourceGroupMembersReadCountIncrement(null, 0); + + DummyGroup group = getDummyGroupAssert(GROUP_PIRATES_NAME, piratesIcfUid); + assertMember(group, transformNameFromResource(getWillRepoIcfName())); + + String foolsIcfUid = getIcfUid(foolsShadow); + DummyGroup groupFools = getDummyGroupAssert("fools", foolsIcfUid); + assertMember(group, transformNameFromResource(getWillRepoIcfName())); + + assertDummyResourceGroupMembersReadCountIncrement(null, 0); + assertSteadyResource(); + } @Test - public void test228DetitleAccountWillPirates() throws Exception { - final String TEST_NAME = "test228DetitleAccountWillPirates"; + public void test230DetitleAccountWillPirates() throws Exception { + final String TEST_NAME = "test230DetitleAccountWillPirates"; TestUtil.displayTestTile(TEST_NAME); Task task = taskManager.createTaskInstance(TestDummy.class.getName() @@ -3451,7 +3520,8 @@ public void test228DetitleAccountWillPirates() throws Exception { DummyAccount dummyAccount = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); assertNotNull("Account will is gone!", dummyAccount); Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); - PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_PILLAGE_NAME, PRIVILEGE_BARGAIN_NAME); + PrismAsserts.assertSets("Wrong account privileges", accountProvileges, + PRIVILEGE_PILLAGE_NAME, PRIVILEGE_BARGAIN_NAME, PRIVILEGE_NONSENSE_NAME); assertDummyResourceGroupMembersReadCountIncrement(null, 0); @@ -3473,8 +3543,8 @@ public void test228DetitleAccountWillPirates() throws Exception { } @Test - public void test229DetitleAccountWillPillage() throws Exception { - final String TEST_NAME = "test229DetitleAccountWillPillage"; + public void test232DetitleAccountWillPillage() throws Exception { + final String TEST_NAME = "test232DetitleAccountWillPillage"; TestUtil.displayTestTile(TEST_NAME); Task task = taskManager.createTaskInstance(TestDummy.class.getName() @@ -3506,7 +3576,8 @@ public void test229DetitleAccountWillPillage() throws Exception { DummyAccount dummyAccount = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); assertNotNull("Account will is gone!", dummyAccount); Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); - PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_BARGAIN_NAME); + PrismAsserts.assertSets("Wrong account privileges", accountProvileges, + PRIVILEGE_BARGAIN_NAME, PRIVILEGE_NONSENSE_NAME); // Make sure that privilege object is still there DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); @@ -3523,8 +3594,8 @@ public void test229DetitleAccountWillPillage() throws Exception { } @Test - public void test229bDetitleAccountWillBargain() throws Exception { - final String TEST_NAME = "test229bDetitleAccountWillBargain"; + public void test234DetitleAccountWillBargain() throws Exception { + final String TEST_NAME = "test234DetitleAccountWillBargain"; TestUtil.displayTestTile(TEST_NAME); Task task = taskManager.createTaskInstance(TestDummy.class.getName() @@ -3556,7 +3627,7 @@ public void test229bDetitleAccountWillBargain() throws Exception { DummyAccount dummyAccount = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); assertNotNull("Account will is gone!", dummyAccount); Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); - assertTrue("There are still some privileges", accountProvileges == null || accountProvileges.isEmpty()); + PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_NONSENSE_NAME); // Make sure that privilege object is still there DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); @@ -3572,8 +3643,8 @@ public void test229bDetitleAccountWillBargain() throws Exception { * LeChuck has both group and priv entitlement. Let's add him together with these entitlements. */ @Test - public void test230AddAccountLeChuck() throws Exception { - final String TEST_NAME = "test230AddAccountLeChuck"; + public void test260AddAccountLeChuck() throws Exception { + final String TEST_NAME = "test260AddAccountLeChuck"; TestUtil.displayTestTile(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummy.class.getName() + "." + TEST_NAME); @@ -3659,8 +3730,8 @@ public void test230AddAccountLeChuck() throws Exception { * the entitlements. */ @Test - public void test235DeleteAccountLeChuck() throws Exception { - final String TEST_NAME = "test235DeleteAccountLeChuck"; + public void test265DeleteAccountLeChuck() throws Exception { + final String TEST_NAME = "test265DeleteAccountLeChuck"; TestUtil.displayTestTile(TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestDummy.class.getName() + "." + TEST_NAME); @@ -3707,6 +3778,8 @@ public void test235DeleteAccountLeChuck() throws Exception { assertSteadyResource(); } + // test28x in TestDummyCaseIgnore + @Test public void test298DeletePrivPillage() throws Exception { final String TEST_NAME = "test298DeletePrivPillage"; diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java index cc18e0ea6e3..ad98a2920ea 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java @@ -506,7 +506,7 @@ public static void display(String title, Throwable e) { stackTrace}); } - public static void assertSearchResultNames(SearchResultList> resultList, MatchingRule matchingRule, String... expectedNames) { + public static void assertSearchResultNames(SearchResultList> resultList, MatchingRule matchingRule, String... expectedNames) throws SchemaException { List names = new ArrayList<>(expectedNames.length); for(PrismObject obj: resultList) { names.add(obj.asObjectable().getName().getOrig()); diff --git a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java index 2e039a498f6..bed60ee2244 100644 --- a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java +++ b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanity.java @@ -1288,8 +1288,7 @@ public void test015AccountOwner() throws FaultMessage, ObjectNotFoundException, } @Test - public void test016ProvisioningSearchAccountsIterative() throws SchemaException, ObjectNotFoundException, - CommunicationException, ConfigurationException, SecurityViolationException { + public void test016ProvisioningSearchAccountsIterative() throws Exception { TestUtil.displayTestTile("test016ProvisioningSearchAccountsIterative"); // GIVEN @@ -1323,7 +1322,11 @@ public boolean handle(PrismObject prismObject, OperationResult paren assertNotNull("No ICF UID", icfUid); String icfName = getNormalizedAttributeValue(shadow, refinedAccountDefinition, getOpenDjSecondaryIdentifierQName()); assertNotNull("No ICF NAME", icfName); - PrismAsserts.assertEquals("Wrong shadow name", caseIgnoreMatchingRule, shadow.getName().getOrig(), icfName); + try { + PrismAsserts.assertEquals("Wrong shadow name", caseIgnoreMatchingRule, shadow.getName().getOrig(), icfName); + } catch (SchemaException e) { + throw new IllegalArgumentException(e.getMessage(),e); + } assertNotNull("Missing LDAP uid", getAttributeValue(shadow, new QName(ResourceTypeUtil.getResourceNamespace(resourceTypeOpenDjrepo), "uid"))); assertNotNull("Missing LDAP cn", getAttributeValue(shadow, new QName(ResourceTypeUtil.getResourceNamespace(resourceTypeOpenDjrepo), "cn"))); assertNotNull("Missing LDAP sn", getAttributeValue(shadow, new QName(ResourceTypeUtil.getResourceNamespace(resourceTypeOpenDjrepo), "sn"))); diff --git a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanityLegacy.java b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanityLegacy.java index 148c4342578..b294e14ea92 100644 --- a/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanityLegacy.java +++ b/testing/sanity/src/test/java/com/evolveum/midpoint/testing/sanity/TestSanityLegacy.java @@ -1057,8 +1057,7 @@ public void test015AccountOwner() throws FaultMessage, ObjectNotFoundException, } @Test - public void test016ProvisioningSearchAccountsIterative() throws SchemaException, ObjectNotFoundException, - CommunicationException, ConfigurationException, SecurityViolationException { + public void test016ProvisioningSearchAccountsIterative() throws Exception { TestUtil.displayTestTile("test016ProvisioningSearchAccountsIterative"); // GIVEN @@ -1092,7 +1091,11 @@ public boolean handle(PrismObject prismObject, OperationResult paren assertNotNull("No ICF UID", icfUid); String icfName = getNormalizedAttributeValue(shadow, refinedAccountDefinition, SchemaConstants.ICFS_NAME); assertNotNull("No ICF NAME", icfName); - PrismAsserts.assertEquals("Wrong shadow name", caseIgnoreMatchingRule, shadow.getName().getOrig(), icfName); + try { + PrismAsserts.assertEquals("Wrong shadow name", caseIgnoreMatchingRule, shadow.getName().getOrig(), icfName); + } catch (SchemaException e) { + throw new IllegalArgumentException(e.getMessage(),e); + } assertNotNull("Missing LDAP uid", getAttributeValue(shadow, new QName(ResourceTypeUtil.getResourceNamespace(resourceTypeOpenDjrepo), "uid"))); assertNotNull("Missing LDAP cn", getAttributeValue(shadow, new QName(ResourceTypeUtil.getResourceNamespace(resourceTypeOpenDjrepo), "cn"))); assertNotNull("Missing LDAP sn", getAttributeValue(shadow, new QName(ResourceTypeUtil.getResourceNamespace(resourceTypeOpenDjrepo), "sn")));