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 Apr 3, 2018
2 parents 15dd458 + 57c6a4f commit dccede1
Show file tree
Hide file tree
Showing 9 changed files with 543 additions and 218 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2017 Evolveum
* Copyright (c) 2010-2018 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -280,11 +280,6 @@ public String toHumanReadableDescription() {
return sb.toString();
}

@Override
public String debugDump() {
return debugDump(0);
}

@Override
public String debugDump(int indent) {
StringBuilder sb = new StringBuilder();
Expand Down
Expand Up @@ -59,6 +59,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceAttributeDefinitionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectTypeDependencyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ScheduleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationDescriptionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UnknownJavaObjectType;
Expand Down Expand Up @@ -322,6 +323,23 @@ public static String prettyPrint(ResourceAttributeDefinitionType vc) {
return sb.toString();
}

public static String prettyPrint(ResourceObjectTypeDependencyType depType) {
if (depType == null) {
return "null";
}
StringBuilder sb = new StringBuilder("ResourceObjectTypeDependencyType(");

if (depType.getResourceRef() != null) {
sb.append(depType.getResourceRef().getOid());
sb.append(":");
}
sb.append(depType.getKind());
sb.append("/");
sb.append(depType.getIntent());
sb.append(")");
return sb.toString();
}

public static String prettyPrint(ExpressionType expressionType) {
if (expressionType == null) {
return "null";
Expand Down
Expand Up @@ -35,6 +35,7 @@
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.schema.util.ResourceTypeUtil;
import com.evolveum.midpoint.util.PrettyPrinter;
import com.evolveum.midpoint.util.exception.PolicyViolationException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
Expand Down Expand Up @@ -104,10 +105,14 @@ private <F extends ObjectType> LensProjectionContext determineProjectionWave(Len
}
if (projectionContext.isDelete()) {
// When deprovisioning (deleting) the dependencies needs to be processed in reverse
LOGGER.trace("Determining wave for (deprovision): {}", projectionContext);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Determining wave for (deprovision): {}", projectionContext.getHumanReadableName());
}
return determineProjectionWaveDeprovision(context, projectionContext, inDependency, depPath);
} else {
LOGGER.trace("Determining wave for (provision): {}", projectionContext);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Determining wave for (provision): {}", projectionContext.getHumanReadableName());
}
return determineProjectionWaveProvision(context, projectionContext, inDependency, depPath);
}
}
Expand All @@ -120,40 +125,50 @@ private <F extends ObjectType> LensProjectionContext determineProjectionWaveProv
int determinedWave = 0;
int determinedOrder = 0;
for (ResourceObjectTypeDependencyType outDependency: projectionContext.getDependencies()) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("DEP: {}", outDependency);
}
if (inDependency != null && isHigerOrder(outDependency, inDependency)) {
// There is incomming dependency. Deal only with dependencies of this order and lower
// otherwise we can end up in endless loop even for legal dependencies.
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing dependency: {}: ignore (higher order)", PrettyPrinter.prettyPrint(outDependency));
}
continue;
}
checkForCircular(depPath, outDependency);
checkForCircular(depPath, outDependency, projectionContext);
depPath.add(outDependency);
ResourceShadowDiscriminator refDiscr = new ResourceShadowDiscriminator(outDependency,
projectionContext.getResource().getOid(), projectionContext.getKind());
LensProjectionContext dependencyProjectionContext = findDependencyTargetContext(context, projectionContext, outDependency);
// if (LOGGER.isTraceEnabled()) {
// LOGGER.trace("DEP: {} -> {}", refDiscr, dependencyProjectionContext);
// }
if (dependencyProjectionContext == null || dependencyProjectionContext.isDelete()) {
ResourceObjectTypeDependencyStrictnessType outDependencyStrictness = ResourceTypeUtil.getDependencyStrictness(outDependency);
if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.STRICT) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing dependency: {}: unsatisfied strict dependency", PrettyPrinter.prettyPrint(outDependency));
}
throw new PolicyViolationException("Unsatisfied strict dependency of account "+projectionContext.getResourceShadowDiscriminator()+
" dependent on "+refDiscr+": Account not provisioned");
} else if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.LAX) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing dependency: {}: unsatisfied lax dependency", PrettyPrinter.prettyPrint(outDependency));
}
// independent object not in the context, just ignore it
LOGGER.debug("Unsatisfied lax dependency of account "+projectionContext.getResourceShadowDiscriminator()+
" dependent on "+refDiscr+"; dependency skipped");
} else if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.RELAXED) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing dependency: {}: unsatisfied relaxed dependency", PrettyPrinter.prettyPrint(outDependency));
}
// independent object not in the context, just ignore it
LOGGER.debug("Unsatisfied relaxed dependency of account "+projectionContext.getResourceShadowDiscriminator()+
" dependent on "+refDiscr+"; dependency skipped");
} else {
throw new IllegalArgumentException("Unknown dependency strictness "+outDependency.getStrictness()+" in "+refDiscr);
}
} else {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing dependency: {}: satisfied dependency", PrettyPrinter.prettyPrint(outDependency));
}
dependencyProjectionContext = determineProjectionWave(context, dependencyProjectionContext, outDependency, depPath);
LOGGER.trace(" dependency projection wave: {}", dependencyProjectionContext.getWave());
if (dependencyProjectionContext.getWave() + 1 > determinedWave) {
determinedWave = dependencyProjectionContext.getWave() + 1;
if (outDependency.getOrder() == null) {
Expand All @@ -162,6 +177,7 @@ private <F extends ObjectType> LensProjectionContext determineProjectionWaveProv
determinedOrder = outDependency.getOrder();
}
}
LOGGER.trace(" determined dependency wave: {} (order={})", determinedWave, determinedOrder);
}
depPath.remove(outDependency);
}
Expand Down Expand Up @@ -194,28 +210,61 @@ private <F extends ObjectType> LensProjectionContext determineProjectionWaveDepr
for (DependencyAndSource ds: findReverseDependecies(context, projectionContext)) {
LensProjectionContext dependencySourceContext = ds.sourceProjectionContext;
ResourceObjectTypeDependencyType outDependency = ds.dependency;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("DEP(rev): {}", outDependency);
}
if (inDependency != null && isHigerOrder(outDependency, inDependency)) {
// There is incomming dependency. Deal only with dependencies of this order and lower
// otherwise we can end up in endless loop even for legal dependencies.
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing (reversed) dependency: {}: ignore (higher order)", PrettyPrinter.prettyPrint(outDependency));
}
continue;
}
checkForCircular(depPath, outDependency);
depPath.add(outDependency);
ResourceShadowDiscriminator refDiscr = new ResourceShadowDiscriminator(outDependency,
projectionContext.getResource().getOid(), projectionContext.getKind());
dependencySourceContext = determineProjectionWave(context, dependencySourceContext, outDependency, depPath);
if (dependencySourceContext.getWave() + 1 > determinedWave) {
determinedWave = dependencySourceContext.getWave() + 1;
if (outDependency.getOrder() == null) {
determinedOrder = 0;

if (!dependencySourceContext.isDelete()) {
ResourceObjectTypeDependencyStrictnessType outDependencyStrictness = ResourceTypeUtil.getDependencyStrictness(outDependency);
if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.STRICT) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing (reversed) dependency: {}: unsatisfied strict dependency", PrettyPrinter.prettyPrint(outDependency));
}
throw new PolicyViolationException("Unsatisfied strict reverse dependency of account " + dependencySourceContext.getResourceShadowDiscriminator()+
" dependent on " + projectionContext.getResourceShadowDiscriminator() + ": Account is provisioned, but the account that it depends on is going to be deprovisioned");
} else if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.LAX) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing (reversed) dependency: {}: unsatisfied lax dependency", PrettyPrinter.prettyPrint(outDependency));
}
// independent object not in the context, just ignore it
LOGGER.debug("Unsatisfied lax reversed dependency of account " + dependencySourceContext.getResourceShadowDiscriminator()+
" dependent on " + projectionContext.getResourceShadowDiscriminator() + "; dependency skipped");
} else if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.RELAXED) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing (reversed) dependency: {}: unsatisfied relaxed dependency", PrettyPrinter.prettyPrint(outDependency));
}
// independent object not in the context, just ignore it
LOGGER.debug("Unsatisfied relaxed dependency of account " + dependencySourceContext.getResourceShadowDiscriminator()+
" dependent on " + projectionContext.getResourceShadowDiscriminator() + "; dependency skipped");
} else {
determinedOrder = outDependency.getOrder();
throw new IllegalArgumentException("Unknown dependency strictness "+outDependency.getStrictness()+" in "+dependencySourceContext.getResourceShadowDiscriminator());
}
} else {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" processing (reversed) dependency: {}: satisfied", PrettyPrinter.prettyPrint(outDependency));
}
checkForCircular(depPath, outDependency, projectionContext);
depPath.add(outDependency);
ResourceShadowDiscriminator refDiscr = new ResourceShadowDiscriminator(outDependency,
projectionContext.getResource().getOid(), projectionContext.getKind());
dependencySourceContext = determineProjectionWave(context, dependencySourceContext, outDependency, depPath);
LOGGER.trace(" dependency projection wave: {}", dependencySourceContext.getWave());
if (dependencySourceContext.getWave() + 1 > determinedWave) {
determinedWave = dependencySourceContext.getWave() + 1;
if (outDependency.getOrder() == null) {
determinedOrder = 0;
} else {
determinedOrder = outDependency.getOrder();
}
}
LOGGER.trace(" determined dependency wave: {} (order={})", determinedWave, determinedOrder);
depPath.remove(outDependency);
}
depPath.remove(outDependency);
}

LensProjectionContext resultAccountContext = projectionContext;
Expand Down Expand Up @@ -250,7 +299,7 @@ private <F extends ObjectType> Collection<DependencyAndSource> findReverseDepend


private void checkForCircular(List<ResourceObjectTypeDependencyType> depPath,
ResourceObjectTypeDependencyType outDependency) throws PolicyViolationException {
ResourceObjectTypeDependencyType outDependency, LensProjectionContext projectionContext) throws PolicyViolationException {
for (ResourceObjectTypeDependencyType pathElement: depPath) {
if (pathElement.equals(outDependency)) {
StringBuilder sb = new StringBuilder();
Expand All @@ -267,7 +316,7 @@ private void checkForCircular(List<ResourceObjectTypeDependencyType> depPath,
sb.append("->");
}
}
throw new PolicyViolationException("Circular dependency, path: "+sb.toString());
throw new PolicyViolationException("Circular dependency in "+projectionContext.getHumanReadableName()+", path: "+sb.toString());
}
}
}
Expand Down

0 comments on commit dccede1

Please sign in to comment.