Skip to content

Commit

Permalink
Provide old values for shadow mgmt simulations
Browse files Browse the repository at this point in the history
Some deltas written to simulation result during simulated
shadow management had no "estimated old values". This is now
fixed.

Related to MID-8536.

This commit also fixes wrongly computed metrics for those low-level
simulations. (Caused by wrong working with sim result transactions.)
  • Loading branch information
mederly committed Mar 1, 2023
1 parent 4da2908 commit 62ec3d3
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
import java.util.List;
import java.util.stream.Collectors;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.path.ItemName;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -39,41 +40,46 @@ public class SynchronizationUtils {

itemDeltas.add(
createSynchronizationSituationDescriptionDelta(shadow, situation, timestamp, sourceChannel, full));
itemDeltas.add(createSynchronizationTimestampDelta(timestamp));
itemDeltas.add(
createSynchronizationTimestampDelta(shadow, timestamp));
if (full) {
itemDeltas.add(createFullSynchronizationTimestampDelta(timestamp));
itemDeltas.add(
createFullSynchronizationTimestampDelta(shadow, timestamp));
}
itemDeltas.add(createSynchronizationSituationDelta(situation));
itemDeltas.add(
createSynchronizationSituationDelta(shadow, situation));

return itemDeltas;
}

public static ItemDelta<?, ?> createSynchronizationSituationDelta(SynchronizationSituationType situation)
public static ItemDelta<?, ?> createSynchronizationSituationDelta(ShadowType shadow, SynchronizationSituationType situation)
throws SchemaException {
return PrismContext.get().deltaFor(ShadowType.class)
.oldObject(shadow)
.item(ShadowType.F_SYNCHRONIZATION_SITUATION)
.replace(situation)
.asItemDelta();
}

public static ItemDelta<?, ?> createSynchronizationTimestampDelta(XMLGregorianCalendar timestamp) throws SchemaException {
return createSynchronizationTimestampDelta(ShadowType.F_SYNCHRONIZATION_TIMESTAMP, timestamp);
public static ItemDelta<?, ?> createSynchronizationTimestampDelta(ShadowType oldShadow, XMLGregorianCalendar timestamp) throws SchemaException {
return createSynchronizationTimestampDelta(oldShadow, ShadowType.F_SYNCHRONIZATION_TIMESTAMP, timestamp);
}

public static ItemDelta<?, ?> createFullSynchronizationTimestampDelta(XMLGregorianCalendar timestamp) throws SchemaException {
return createSynchronizationTimestampDelta(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP, timestamp);
public static ItemDelta<?, ?> createFullSynchronizationTimestampDelta(ShadowType oldShadow, XMLGregorianCalendar timestamp) throws SchemaException {
return createSynchronizationTimestampDelta(oldShadow, ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP, timestamp);
}

private static ItemDelta<?, ?> createSynchronizationTimestampDelta(
QName propName, XMLGregorianCalendar timestamp) throws SchemaException {
ShadowType oldShadow, ItemName propName, XMLGregorianCalendar timestamp) throws SchemaException {
return PrismContext.get().deltaFor(ShadowType.class)
.oldObject(oldShadow)
.item(propName)
.replace(timestamp)
.asItemDelta();
}

/** Creates delta for `synchronizationSituationDescription` (adding new, removing obsolete if present). */
public static ItemDelta<?, ?> createSynchronizationSituationDescriptionDelta(
public static @NotNull ItemDelta<?, ?> createSynchronizationSituationDescriptionDelta(
ShadowType shadow, SynchronizationSituationType situation, XMLGregorianCalendar timestamp,
String sourceChannel, boolean full) throws SchemaException {

Expand All @@ -87,6 +93,7 @@ public class SynchronizationUtils {
getDescriptionsFromSameChannel(shadow, sourceChannel);

return PrismContext.get().deltaFor(ShadowType.class)
.oldObject(shadow)
.item(ShadowType.F_SYNCHRONIZATION_SITUATION_DESCRIPTION)
.deleteRealValues(descriptionsToDelete)
.add(descriptionToAdd)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ private void addComputedMetricValues(@NotNull List<SimulationProcessedObjectMetr
delta,
InternalState.CREATING);

processedObject.addComputedMetricValues(List.of()); // Ignoring metrics in this mode
processedObject.addComputedMetricValues(List.of()); // Ignoring custom metrics in this mode

return processedObject;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,12 @@ class ShadowUpdater {
@NotNull private final SynchronizationContext<?> syncCtx;
@NotNull private final ModelBeans beans;
@NotNull private final List<ItemDelta<?, ?>> deltas = new ArrayList<>();

/** Only for simulation purposes. */
private final ShadowType shadowBefore;
@NotNull private final ShadowType shadowBefore;

ShadowUpdater(@NotNull SynchronizationContext<?> syncCtx, @NotNull ModelBeans beans) {
this.syncCtx = syncCtx;
this.beans = beans;
this.shadowBefore = isShadowSimulation() ? syncCtx.getShadowedResourceObject().clone() : null;
this.shadowBefore = syncCtx.getShadowedResourceObject().clone();
}

ShadowUpdater updateAllSyncMetadataRespectingMode() throws SchemaException {
Expand All @@ -81,7 +79,7 @@ ShadowUpdater updateAllSyncMetadataRespectingMode() throws SchemaException {

private void updateSyncSituation() throws SchemaException {
applyShadowDelta(
createSynchronizationSituationDelta(syncCtx.getSituation()));
createSynchronizationSituationDelta(shadowBefore, syncCtx.getSituation()));
}

private void updateSyncSituationDescription(XMLGregorianCalendar now) throws SchemaException {
Expand All @@ -96,13 +94,13 @@ private void updateSyncSituationDescription(XMLGregorianCalendar now) throws Sch

ShadowUpdater updateFullSyncTimestamp(XMLGregorianCalendar now) throws SchemaException {
applyShadowDelta(
SynchronizationUtils.createFullSynchronizationTimestampDelta(now));
SynchronizationUtils.createFullSynchronizationTimestampDelta(shadowBefore, now));
return this;
}

private void updateBasicSyncTimestamp(XMLGregorianCalendar now) throws SchemaException {
applyShadowDelta(
SynchronizationUtils.createSynchronizationTimestampDelta(now));
SynchronizationUtils.createSynchronizationTimestampDelta(shadowBefore, now));
}

ShadowUpdater updateBothSyncTimestamps() throws SchemaException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,10 @@ private void executeSimulatedClassificationAndReclassification(
.assertSize(2); // temporarily
// @formatter:on

assertSimulationResult(simResult3, "after")
.display()
.assertMetricValueByEventMark(MARK_SHADOW_CLASSIFICATION_CHANGED.oid, BigDecimal.ONE);

REPORT_SIMULATION_VALUES_CHANGED.export()
.withDefaultParametersValues(simResult3.getSimulationResultRef())
.execute(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,11 +447,13 @@ private boolean processSingleBucket(OperationResult result) throws ActivityRunEx
BucketProcessingRecord record = new BucketProcessingRecord(getLiveItemProcessing());

beforeBucketProcessing(result);
simulationSupport.openSimulationTransaction(result);

setExpectedInCurrentBucket(result);

coordinator = setupCoordinatorAndWorkerThreads();

var oldTx = getRunningTask().setSimulationTransaction(
simulationSupport.openSimulationTransaction(result));
try {
iterateOverItemsInBucket(result);
} finally {
Expand All @@ -460,6 +462,7 @@ private boolean processSingleBucket(OperationResult result) throws ActivityRunEx
//
// But overall, it is necessary to do this here in order to avoid endless waiting if any exception occurs.
coordinator.finishProcessing(result);
getRunningTask().setSimulationTransaction(oldTx);
}

afterBucketProcessing(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,11 @@ private String getSimulationResultTxId() {
return activityRun.getActivityPath() + "#" + getBucketSequentialNumber();
}

void openSimulationTransaction(OperationResult result) {
SimulationTransaction openSimulationTransaction(OperationResult result) {
if (simulationResult != null) {
simulationTransaction = simulationResult.openTransaction(getSimulationResultTxId(), result);
}
return simulationTransaction;
}

void commitSimulationTransaction(OperationResult result) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@ public void test200AddManyUsers() throws Exception {
addObject(TASK_ASYNC_UPDATE_MULTI, task, result);

waitForTaskCloseOrSuspend(TASK_RECOMPUTE_MULTI.oid, 1800000);
waitForTaskProgress(TASK_ASYNC_UPDATE_MULTI.oid, users, () -> countUsers(result) - usersAtStart >= users*2,
waitForTaskProgress(
TASK_ASYNC_UPDATE_MULTI.oid,
users, () -> countUsers(result) - usersAtStart >= users*2,
1800000, 5000, result);

then();
Expand Down

0 comments on commit 62ec3d3

Please sign in to comment.