Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Oct 14, 2022
2 parents 342c914 + eb4cb89 commit e7c4d27
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
* . completing a correlation case;
*
* and further auxiliary methods.
*
*/
@Component
public class CorrelationServiceImpl implements CorrelationService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@

package com.evolveum.midpoint.model.impl.sync;

import javax.xml.datatype.XMLGregorianCalendar;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.evolveum.midpoint.model.api.correlation.CompleteCorrelationResult;
import com.evolveum.midpoint.model.api.correlation.CorrelationContext;
import com.evolveum.midpoint.model.api.correlator.Correlator;
import com.evolveum.midpoint.model.api.correlator.CorrelatorContext;
import com.evolveum.midpoint.model.impl.ModelBeans;
import com.evolveum.midpoint.model.impl.correlation.CorrelationCaseManager;
import com.evolveum.midpoint.model.impl.correlation.CorrelationServiceImpl;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.delta.builder.S_ItemEntry;
import com.evolveum.midpoint.prism.util.CloneUtil;
Expand All @@ -27,19 +33,15 @@
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.xml.datatype.XMLGregorianCalendar;

/**
* Manages correlation that occurs _during synchronization pre-processing_.
*
* The correlation itself is delegated to appropriate {@link Correlator} instance.
* The correlation itself is delegated to appropriate {@link Correlator} instance via {@link CorrelationServiceImpl}.
*
* Specific responsibilities:
*
* 1. updating shadow with the result of the correlation
* 1. updating shadow with the status (e.g. all the timestamps) and the result of the correlation
* (although the {@link CorrelationCaseManager} and some other classes manipulate the state as well);
* 2. calls {@link CorrelationCaseManager} to open, update, or cancel cases (if needed)
*/
class CorrelationProcessing<F extends FocusType> {
Expand Down Expand Up @@ -95,6 +97,7 @@ class CorrelationProcessing<F extends FocusType> {
CompleteCorrelationResult existing = getResultFromExistingCorrelationState(parentResult);
if (existing != null) {
LOGGER.debug("Result determined from existing correlation state in shadow: {}", existing.getSituation());
markShadowCorrelationFinished();
return existing;
}

Expand Down Expand Up @@ -225,12 +228,6 @@ private void applyCorrelationResultToShadow(CompleteCorrelationResult correlatio
.replace(CorrelationSituationType.ERROR);
}
} else {
if (correlationResult.isDone()) {
builder = builder
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATION_END_TIMESTAMP)
.replace(
XmlTypeConverter.createXMLGregorianCalendar());
}
// @formatter:off
builder = builder
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_SITUATION)
Expand All @@ -247,6 +244,19 @@ private void applyCorrelationResultToShadow(CompleteCorrelationResult correlatio

syncCtx.applyShadowDeltas(
builder.asItemDeltas());

if (correlationResult.isDone()) {
markShadowCorrelationFinished();
}
}

private void markShadowCorrelationFinished() throws SchemaException {
syncCtx.applyShadowDeltas(
PrismContext.get().deltaFor(ShadowType.class)
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATION_END_TIMESTAMP)
.replace(
XmlTypeConverter.createXMLGregorianCalendar())
.asItemDeltas());
}

private @NotNull ShadowType getShadow() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.util.PrismAsserts;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.test.asserter.prism.PrismObjectAsserter;
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
Expand Down Expand Up @@ -398,4 +400,66 @@ private List<ResourceObjectOwnerOptionType> getPotentialOwnerOptions() {
return state.getOwnerOptions().getOption();
}
}

public ShadowAsserter<RA> assertCorrelationCaseOpenTimestampBetween(long start, long end) {
TestUtil.assertBetween(
"correlation case open timestamp", start, end, getCorrelationCaseOpenTimestamp());
return this;
}

public ShadowAsserter<RA> assertCorrelationCaseCloseTimestampBetween(long start, long end) {
TestUtil.assertBetween(
"correlation case close timestamp", start, end, getCorrelationCaseCloseTimestamp());
return this;
}

public ShadowAsserter<RA> assertCorrelationStartTimestampBetween(long start, long end) {
TestUtil.assertBetween(
"correlation start timestamp", start, end, getCorrelationStartTimestamp());
return this;
}

public ShadowAsserter<RA> assertCorrelationEndTimestampBetween(long start, long end) {
TestUtil.assertBetween(
"correlation end timestamp", start, end, getCorrelationEndTimestamp());
return this;
}

public ShadowAsserter<RA> assertNoCorrelationCaseCloseTimestamp() {
assertThat(getCorrelationCaseCloseTimestamp()).as("correlation case close timestamp").isNull();
return this;
}

public ShadowAsserter<RA> assertNoCorrelationEndTimestamp() {
assertThat(getCorrelationEndTimestamp()).as("correlation case end timestamp").isNull();
return this;
}

private Long getCorrelationCaseOpenTimestamp() {
ShadowCorrelationStateType correlationState = getObjectable().getCorrelation();
return correlationState != null ?
XmlTypeConverter.toMillisNullable(correlationState.getCorrelationCaseOpenTimestamp()) :
null;
}

private Long getCorrelationCaseCloseTimestamp() {
ShadowCorrelationStateType correlationState = getObjectable().getCorrelation();
return correlationState != null ?
XmlTypeConverter.toMillisNullable(correlationState.getCorrelationCaseCloseTimestamp()) :
null;
}

private Long getCorrelationStartTimestamp() {
ShadowCorrelationStateType correlationState = getObjectable().getCorrelation();
return correlationState != null ?
XmlTypeConverter.toMillisNullable(correlationState.getCorrelationStartTimestamp()) :
null;
}

private Long getCorrelationEndTimestamp() {
ShadowCorrelationStateType correlationState = getObjectable().getCorrelation();
return correlationState != null ?
XmlTypeConverter.toMillisNullable(correlationState.getCorrelationEndTimestamp()) :
null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public abstract class AbstractSimpleInternalCorrelationTest extends AbstractCorr
private static final int HR_ACCOUNTS = 5;
private static final int TARGET_ACCOUNTS = 6;

private long firstTargetImportStart;

abstract CsvResource getTargetResource();

@Override
Expand Down Expand Up @@ -133,7 +135,9 @@ public void test200FirstImportFromTarget() throws CommonException {
OperationResult result = task.getResult();

when("import task (dry run) from target is run");
firstTargetImportStart = System.currentTimeMillis();
TASK_IMPORT_TARGET.rerun(result);
long firstTargetImportEnd = System.currentTimeMillis();

then("task is OK, all accounts are processed");

Expand All @@ -156,7 +160,11 @@ public void test200FirstImportFromTarget() throws CommonException {
PrismObject<ShadowType> ag3 = getTargetShadow("ag3", result);
assertShadowAfter(ag3)
.assertCorrelationSituation(CorrelationSituationType.UNCERTAIN)
.assertSynchronizationSituation(SynchronizationSituationType.DISPUTED);
.assertSynchronizationSituation(SynchronizationSituationType.DISPUTED)
.assertCorrelationStartTimestampBetween(firstTargetImportStart, firstTargetImportEnd)
.assertCorrelationCaseOpenTimestampBetween(firstTargetImportStart, firstTargetImportEnd)
.assertNoCorrelationCaseCloseTimestamp()
.assertNoCorrelationEndTimestamp();

assertUserAfterByUsername("green1")
.assertLinks(1, 0);
Expand All @@ -183,7 +191,11 @@ public void test200FirstImportFromTarget() throws CommonException {
assertShadowAfter(rb5)
.assertCorrelationSituation(CorrelationSituationType.UNCERTAIN)
.assertPotentialOwnerOptions(3) // 2 existing + 1 new
.assertSynchronizationSituation(SynchronizationSituationType.DISPUTED);
.assertSynchronizationSituation(SynchronizationSituationType.DISPUTED)
.assertCorrelationStartTimestampBetween(firstTargetImportStart, firstTargetImportEnd)
.assertCorrelationCaseOpenTimestampBetween(firstTargetImportStart, firstTargetImportEnd)
.assertNoCorrelationCaseCloseTimestamp()
.assertNoCorrelationEndTimestamp();

assertUserAfterByUsername("black2")
.assertLinks(1, 0);
Expand All @@ -194,7 +206,11 @@ public void test200FirstImportFromTarget() throws CommonException {
assertShadowAfter(nn6)
.assertCorrelationSituation(CorrelationSituationType.UNCERTAIN)
.assertPotentialOwnerOptions(2)
.assertSynchronizationSituation(SynchronizationSituationType.DISPUTED);
.assertSynchronizationSituation(SynchronizationSituationType.DISPUTED)
.assertCorrelationStartTimestampBetween(firstTargetImportStart, firstTargetImportEnd)
.assertCorrelationCaseOpenTimestampBetween(firstTargetImportStart, firstTargetImportEnd)
.assertNoCorrelationCaseCloseTimestamp()
.assertNoCorrelationEndTimestamp();
}

private void assertTargetLinked(String userName, String accountName, OperationResult result) throws CommonException {
Expand All @@ -221,15 +237,30 @@ public void test210ResolveAliceAndBob() throws CommonException {
String aliceOid = findUserByUsername("green1").getOid();
String bobOid = findUserByUsername("black1").getOid();

when("cases for Alice and Bob are resolved");
when("case for Alice is resolved");

long aliceCaseResolutionStart = System.currentTimeMillis();
resolveCase(ag3case, aliceOid, task, result);
long aliceCaseResolutionEnd = System.currentTimeMillis();

and("case for Bob is resolved");
resolveCase(bb4case, bobOid, task, result);

then("shadows are linked to the users");

assertTargetLinked("green1", "ag3", result);
assertTargetLinked("black1", "bb4", result);

and("alice's case is OK");
assertCaseAfter(ag3case.getOid())
.assertClosed();

and("alice's shadow is OK");
assertShadowAfter(getTargetShadow("ag3", result))
.assertCorrelationStartTimestampBetween(firstTargetImportStart, aliceCaseResolutionStart)
.assertCorrelationCaseOpenTimestampBetween(firstTargetImportStart, aliceCaseResolutionStart)
.assertCorrelationCaseCloseTimestampBetween(aliceCaseResolutionStart, aliceCaseResolutionEnd)
.assertCorrelationEndTimestampBetween(aliceCaseResolutionStart, aliceCaseResolutionEnd);
}

private @NotNull PrismObject<ShadowType> getTargetShadow(String name, OperationResult result) throws SchemaException {
Expand Down

0 comments on commit e7c4d27

Please sign in to comment.