Skip to content

Commit

Permalink
Providing stateBefore/stateAfter to sim manager
Browse files Browse the repository at this point in the history
Here we had to rework the mechanism of passing info to simulation
result manager: instead of passing each delta as soon as it's
produced, we use information from LensElementContext at the end
of the clockwork. This way we have the full "object old" information
that would not be available otherwise.

Work in progress. The full info is not stored into the repo now;
and the deltas are not retrieved either.
  • Loading branch information
mederly committed Dec 7, 2022
1 parent 9921b44 commit faa23b9
Show file tree
Hide file tree
Showing 17 changed files with 347 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
<xsd:sequence>
<xsd:element name="metric" type="tns:SimulationMetricType" maxOccurs="unbounded"/>
<xsd:element name="processedObject" type="tns:SimulationResultProcessedObjectType" maxOccurs="unbounded" />
<xsd:element name="useOwnPartitionForProcessedObjects" type="xsd:boolean" />
<xsd:element name="useOwnPartitionForProcessedObjects" type="xsd:boolean" minOccurs="0" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
Expand All @@ -72,7 +72,7 @@
<xsd:sequence>
<xsd:element name="useOwnPartitionForProcessedObjects" type="xsd:boolean" />
<!-- TODO: Do we want storage strategies per type? or per metric?
Storage strategies may be beneficial for large deployments
- eg. do not store information about objects, that do not match any metric
or are unmodified.
Expand Down Expand Up @@ -135,7 +135,7 @@
<xsd:element name="matchedObjects" type="xsd:decimal"/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="SimulationResultProcessedObjectType">
<xsd:annotation>
<xsd:documentation>
Expand All @@ -152,7 +152,7 @@
<xsd:element name="name" type="t:PolyStringType" />
<xsd:element name="state" type="tns:ObjectProcessingStateType" />
<xsd:element name="metricIdentifier" type="xsd:string" maxOccurs="unbounded" />

<!-- Extra stored state -->
<xsd:element name="before" type="tns:ObjectType" />
<xsd:element name="after" type="tns:ObjectType" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
package com.evolveum.midpoint.model.api.simulation;

import com.evolveum.midpoint.task.api.ObjectProcessingListener;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.AggregatedObjectProcessingListener;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SimulationResultType;

import org.jetbrains.annotations.NotNull;

import java.util.Collection;

public interface SimulationResultContext {

ObjectProcessingListener objectProcessingListener();
AggregatedObjectProcessingListener aggregatedObjectProcessingListener();

/** OID of the {@link SimulationResultType} object that can be used to retrieve the data. */
@NotNull String getResultOid();

/** TEMPORARY. Retrieves stored deltas. May be replaced by something more general in the future. */
@NotNull Collection<ObjectDelta<?>> getStoredDeltas(OperationResult result) throws SchemaException, ObjectNotFoundException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ <F extends ObjectType> HookOperationMode runWithConflictDetection(LensContext<F>
}
} finally {
operationExecutionRecorder.recordOperationExecutions(context, task, result);
beans.clockworkAuditHelper.submitSimulationDeltas(context, task, result);
clockworkConflictResolver.unregisterConflictWatcher(context);
exitCaches();
context.reportProgress(new ProgressInformation(CLOCKWORK, EXITING));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@
*/
package com.evolveum.midpoint.model.impl.lens;

import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.asObjectable;

import static java.util.Collections.emptyList;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import javax.xml.datatype.XMLGregorianCalendar;

import com.evolveum.midpoint.prism.delta.ObjectDeltaCollectionsUtil;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -99,7 +104,8 @@ <F extends ObjectType> void auditEvent(
boolean alwaysAudit, Task task, OperationResult result, OperationResult overallResult) {

if (!task.isPersistentExecution()) {
// Or, should we record the simulation deltas here?
// Or, should we record the simulation deltas here? It is better done at the end, because we have all deltas there,
// so we can have one aggregated delta per object.
LOGGER.trace("No persistent execution, no auditing");
return;
}
Expand Down Expand Up @@ -355,4 +361,52 @@ private void addRecordMessage(AuditEventRecord auditRecord, String message) {
}
auditRecord.setMessage(sb.toString());
}

/**
* Passes the simulation deltas to the appropriate listener.
*
* The code is here because of the similarity with auditing.
*
* Temporary code.
*/
<F extends ObjectType> void submitSimulationDeltas(LensContext<F> context, Task task, OperationResult result)
throws SchemaException {
if (task.isPersistentExecution()) {
return;
}

LensFocusContext<F> focusContext = context.getFocusContext();
if (focusContext != null) {
submitElementSimulationDelta(focusContext, task, result);
}
// We ignore duplicates stemming from higher-order contexts for now
for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
submitElementSimulationDelta(projectionContext, task, result);
}
}

/**
* Submits the information about the (summary) change computed.
*
* Limitations:
*
* - We ignore the fact that sometimes we don't have full shadow loaded. The deltas applied to "shadow-only" state
* may be misleading.
*/
private <E extends ObjectType> void submitElementSimulationDelta(
LensElementContext<E> elementContext, Task task, OperationResult result) throws SchemaException {
task.onItemProcessed(
asObjectable(elementContext.getObjectOld()),
null, // maybe will be filled-in later
getSummaryExecutedDelta(elementContext),
result);
}

private static <E extends ObjectType> ObjectDelta<E> getSummaryExecutedDelta(LensElementContext<E> elementContext)
throws SchemaException {
List<ObjectDelta<E>> executedDeltas = elementContext.getExecutedDeltas().stream()
.map(odo -> odo.getObjectDelta())
.collect(Collectors.toList());
return ObjectDeltaCollectionsUtil.summarize(executedDeltas);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ private void executeAddition(OperationResult result)
if (task.isPersistentExecution()) {
oid = executeRealAddition(objectToAdd, result);
} else {
oid = executeSimulatedAddition(objectToAdd, result);
oid = executeSimulatedAddition(objectToAdd);
}
if (!delta.isImmutable()) {
delta.setOid(oid);
Expand Down Expand Up @@ -493,12 +493,10 @@ private String executeRealAddition(PrismObject<E> objectToAdd, OperationResult r
FocusConstraintsChecker.clearCacheFor(objectToAdd.asObjectable().getName());
oid = b.cacheRepositoryService.addObject(objectToAdd, createRepoAddOptions(), result);
}
task.onChangeExecuted(objectToAdd.createAddDelta(), true, result);
return oid;
}

private String executeSimulatedAddition(PrismObject<E> objectToAdd, OperationResult result) {
task.onChangeExecuted(objectToAdd.createAddDelta(), false, result);
private String executeSimulatedAddition(PrismObject<E> objectToAdd) {
String explicitOid = objectToAdd.getOid();
if (explicitOid != null) {
return explicitOid;
Expand Down Expand Up @@ -581,8 +579,6 @@ private void executeModification(OperationResult result)

if (task.isPersistentExecution()) {
executeRealModification(objectClass, result);
} else {
executeSimulatedModification(result);
}
task.recordObjectActionExecuted(baseObject, objectClass, delta.getOid(), ChangeType.MODIFY,
context.getChannel(), null);
Expand Down Expand Up @@ -617,11 +613,6 @@ private void executeRealModification(Class<E> objectClass, OperationResult resul
throw new ConflictDetectedException(e);
}
}
task.onChangeExecuted(delta, true, result);
}

private void executeSimulatedModification(OperationResult result) {
task.onChangeExecuted(delta, false, result);
}

private String modifyProvisioningObject(OperationResult result) throws ObjectNotFoundException, CommunicationException,
Expand Down Expand Up @@ -732,8 +723,6 @@ private void executeDeletion(OperationResult result)

if (task.isPersistentExecution()) {
executeRealDeletion(objectTypeClass, oid, result);
} else {
executeSimulatedDeletion(result);
}
deleted = true;
task.recordObjectActionExecuted(objectOld, objectTypeClass, oid, ChangeType.DELETE, context.getChannel(), null);
Expand Down Expand Up @@ -791,11 +780,6 @@ private void executeRealDeletion(Class<E> objectTypeClass, String oid, Operation
}
objectAfterModification = null;
}
task.onChangeExecuted(delta, true, result);
}

private void executeSimulatedDeletion(OperationResult result) {
task.onChangeExecuted(delta, false, result);
}

private PrismObject<E> deleteProvisioningObject(Class<E> type, String oid, OperationResult result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ private void executeFocusDelta(ObjectDelta<F> delta, String opName, OperationRes
if (real) {
repositoryService.modifyObject(focusType, focus.getOid(), delta.getModifications(), result);
}
task.onChangeExecuted(delta, real, result);
task.recordObjectActionExecuted(focus, focusType, focus.getOid(), ChangeType.MODIFY, channel, null);
} catch (ObjectAlreadyExistsException ex) {
task.recordObjectActionExecuted(focus, focusType, focus.getOid(), ChangeType.MODIFY, channel, ex);
Expand Down Expand Up @@ -434,10 +433,6 @@ private void updateSituationInShadow(SynchronizationSituationType newSituation,
if (real) {
executeShadowDelta(syncSituationDeltas, result);
}
ObjectDelta<ShadowType> modifyDelta =
prismContext.deltaFactory().object().createModifyDelta(projectionOid, syncSituationDeltas, ShadowType.class);
task.onChangeExecuted(modifyDelta, real, result);

LOGGER.trace("Situation in projection {} was updated to {} (real={})", projCtx, newSituation, real);
} catch (Exception ex) {
result.recordFatalError(ex);
Expand Down

0 comments on commit faa23b9

Please sign in to comment.