Skip to content

Commit

Permalink
Storing policy situations (new version). No optimizations yet.
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Sep 23, 2017
1 parent d625c74 commit 8c03cff
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 237 deletions.
Expand Up @@ -32,6 +32,7 @@
import java.lang.reflect.Constructor;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* Item is a common abstraction of Property and PropertyContainer.
Expand Down Expand Up @@ -312,6 +313,12 @@ public PrismValue findValue(PrismValue value, boolean ignoreMetadata) {
return null;
}

public List<? extends PrismValue> findValuesIgnoreMetadata(PrismValue value) {
return getValues().stream()
.filter(v -> v.equalsComplex(value, true, false))
.collect(Collectors.toList());
}

/**
* Returns value that is previous to the specified value.
* Note that the order is semantically insignificant and this is used only
Expand Down
Expand Up @@ -27,6 +27,8 @@
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import org.apache.commons.collections4.CollectionUtils;

public class ContainerDelta<V extends Containerable> extends ItemDelta<PrismContainerValue<V>,PrismContainerDefinition<V>> implements PrismContainerable<V> {

Expand Down Expand Up @@ -183,19 +185,21 @@ private Collection findItemValues(Long id, ItemPath path, Collection<PrismContai
* Post processing of delta to expand missing values from the object. E.g. a delete deltas may
* be "id-only" so they contain only id of the value to delete. In such case locate the full value
* in the object and fill it into the delta.
* This method may even delete in-only values that are no longer present in the object.
* This method may even delete id-only values that are no longer present in the object.
*
* It also fills-in IDs for values to be added/replaced/deleted.
*/
public <O extends Objectable> void expand(PrismObject<O> object) throws SchemaException {
public <O extends Objectable> void expand(PrismObject<O> object, Trace logger) throws SchemaException {
PrismContainer<Containerable> container = null;
ItemPath path = this.getPath();
if (object != null) {
container = object.findContainer(path);
}
if (valuesToDelete != null) {
ItemPath path = this.getPath();
PrismContainer<Containerable> container = null;
if (object != null) {
container = object.findContainer(path);
}
Iterator<PrismContainerValue<V>> iterator = valuesToDelete.iterator();
while (iterator.hasNext()) {
PrismContainerValue<V> deltaCVal = iterator.next();
if ((deltaCVal.getItems() == null || deltaCVal.getItems().isEmpty())) {
if (CollectionUtils.isEmpty(deltaCVal.getItems())) {
Long id = deltaCVal.getId();
if (id == null) {
throw new IllegalArgumentException("No id and no items in value "+deltaCVal+" in delete set in "+this);
Expand All @@ -206,17 +210,65 @@ public <O extends Objectable> void expand(PrismObject<O> object) throws SchemaEx
for (Item<?,?> containerItem: containerCVal.getItems()) {
deltaCVal.add(containerItem.clone());
}
continue;
}
}
// id-only value with ID that is not in the object any more: delete the value from delta
iterator.remove();
} else if (deltaCVal.getId() == null) {
if (container != null) {
@SuppressWarnings("unchecked")
List<PrismContainerValue<Containerable>> containerCVals =
(List<PrismContainerValue<Containerable>>)
container.findValuesIgnoreMetadata(deltaCVal);
if (containerCVals.size() > 1) {
logger.warn("More values to be deleted are matched by a single value in delete delta: values={}, delta value={}",
containerCVals, deltaCVal);
} else if (containerCVals.size() == 1) {
deltaCVal.setId(containerCVals.get(0).getId());
}
// for the time being let's keep non-existent values in the delta
}
}
}
}
if (valuesToAdd != null) {
assert valuesToReplace == null;
long maxId = getMaxId(container);
processIdentifiers(maxId, valuesToAdd);
}
if (valuesToReplace != null) {
assert valuesToAdd == null;
processIdentifiers(0, valuesToReplace);
}
}

@Override
private void processIdentifiers(long maxId, Collection<PrismContainerValue<V>> values) {
for (PrismContainerValue<V> value : values) {
if (value.getId() != null && value.getId() > maxId) {
maxId = value.getId();
}
}
for (PrismContainerValue<V> value : values) {
if (value.getId() == null) {
value.setId(++maxId);
}
}
}

private long getMaxId(PrismContainer<?> container) {
if (container == null) {
return 0;
}
long max = 0;
for (PrismContainerValue<?> value : container.getValues()) {
if (value.getId() != null && value.getId() > max) {
max = value.getId();
}
}
return max;
}

@Override
protected boolean isValueEquivalent(PrismContainerValue<V> a, PrismContainerValue<V> b) {
if (!super.isValueEquivalent(a, b)) {
return false;
Expand Down
Expand Up @@ -185,6 +185,41 @@ public S_MaybeDelete add(Collection<? extends PrismValue> values) {
return this;
}

@Override
public S_ValuesEntry old(Object... realValues) {
return oldRealValues(Arrays.asList(realValues));
}

@Override
public S_ValuesEntry oldRealValues(Collection<?> realValues) {
for (Object v : realValues) {
if (v != null) {
currentDelta.addEstimatedOldValue(toPrismValue(currentDelta, v));
}
}
return this;
}

@Override
public S_ValuesEntry old(PrismValue... values) {
for (PrismValue v : values) {
if (v != null) {
currentDelta.addEstimatedOldValue(v);
}
}
return this;
}

@Override
public S_ValuesEntry old(Collection<? extends PrismValue> values) {
for (PrismValue v : values) {
if (v != null) {
currentDelta.addEstimatedOldValue(v);
}
}
return this;
}

@Override
public S_ItemEntry delete(Object... realValues) {
return deleteRealValues(Arrays.asList(realValues));
Expand Down
Expand Up @@ -42,5 +42,8 @@ public interface S_ValuesEntry {
S_ItemEntry replaceRealValues(Collection<?> realValues);
S_ItemEntry replace(PrismValue... values);
S_ItemEntry replace(Collection<? extends PrismValue> values);

S_ValuesEntry old(Object... realValues);
S_ValuesEntry oldRealValues(Collection<?> realValues);
S_ValuesEntry old(PrismValue... values);
S_ValuesEntry old(Collection<? extends PrismValue> values);
}
Expand Up @@ -155,11 +155,6 @@ public <O extends ObjectType> boolean executeChanges(LensContext<O> context, Tas
}
focusContext.clearPendingPolicySituationModifications();

if (!focusContext.isDelete()) {
focusDelta = policySituationUpdater.applyAssignmentSituation(context, focusDelta);
policySituationUpdater.storeFocusPolicySituation(context);
}

if (focusDelta != null) {

ObjectPolicyConfigurationType objectPolicyConfigurationType = focusContext
Expand Down
Expand Up @@ -140,7 +140,13 @@ public DeltaSetTriple<EvaluatedAssignmentImpl<F>> processAllAssignments() throws
ObjectDelta<F> focusDelta = focusContext.getDelta();

ContainerDelta<AssignmentType> assignmentDelta = getExecutionWaveAssignmentDelta(focusContext);
assignmentDelta.expand(focusContext.getObjectCurrent());
assignmentDelta.expand(focusContext.getObjectCurrent(), LOGGER);

// Now we should have IDs for all assignments except for some borderline ones used in delete deltas
// (if the value to be deleted is not in object or if the value is ambiguous). This could have some negative
// impact on policy rules; namely, if there are some policy situations determined for such assignments,
// and the processing ends prematurely, it is possible that these situations will not be recorded.
// TODO determine if it's really this case

LOGGER.trace("Assignment delta:\n{}", assignmentDelta.debugDump());

Expand Down

0 comments on commit 8c03cff

Please sign in to comment.