Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Mar 7, 2023
2 parents 60b62d8 + 7a89477 commit 6cfc4c5
Show file tree
Hide file tree
Showing 14 changed files with 499 additions and 286 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import com.evolveum.midpoint.gui.api.component.ObjectBrowserPanel;
import com.evolveum.midpoint.web.component.AjaxButton;
import com.evolveum.midpoint.web.component.dialog.Popupable;
import com.evolveum.midpoint.web.component.util.VisibleBehaviour;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;

import org.apache.commons.collections4.CollectionUtils;
Expand Down Expand Up @@ -81,6 +83,7 @@ protected void onSelectPerformed(AjaxRequestTarget target, O object) {
}
};
selectObject.setOutputMarkupId(true);
selectObject.add(new VisibleBehaviour(this::notDisplayedInPopup));
selectObject.add(AttributeAppender.append("title", createStringResource("ReferenceValueSearchPopupPanel.selectObject")));
add(selectObject);
}
Expand Down Expand Up @@ -146,4 +149,8 @@ protected List<QName> getAllowedRelations() {
protected boolean isAllowedNotFoundObjectRef(){
return false;
}

private boolean notDisplayedInPopup() {
return ReferenceValueSearchPanel.this.findParent(Popupable.class) == null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -668,4 +668,25 @@ public abstract class SchemaConstants {
ItemPath.create(FocusType.F_IDENTITIES, FocusIdentitiesType.F_DEFAULT_AUTHORITATIVE_SOURCE);

public static final String SIMULATION_RESULT_DEFAULT_TRANSACTION_ID = "default";

public static final @NotNull ItemPath CORRELATION_SITUATION_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_SITUATION);
public static final @NotNull ItemPath CORRELATION_RESULTING_OWNER_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_RESULTING_OWNER);
public static final @NotNull ItemPath CORRELATION_OWNER_OPTIONS_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_OWNER_OPTIONS);
public static final @NotNull ItemPath CORRELATION_START_TIMESTAMP_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATION_START_TIMESTAMP);
public static final @NotNull ItemPath CORRELATION_END_TIMESTAMP_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATION_END_TIMESTAMP);
public static final @NotNull ItemPath CORRELATION_CASE_OPEN_TIMESTAMP_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATION_CASE_OPEN_TIMESTAMP);
public static final @NotNull ItemPath CORRELATION_CASE_CLOSE_TIMESTAMP_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATION_CASE_CLOSE_TIMESTAMP);
public static final @NotNull ItemPath CORRELATION_PERFORMER_REF_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_PERFORMER_REF);
public static final @NotNull ItemPath CORRELATION_PERFORMER_COMMENT_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_PERFORMER_COMMENT);
public static final @NotNull ItemPath CORRELATION_CORRELATOR_STATE_PATH =
ItemPath.create(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATOR_STATE);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

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

import static com.evolveum.midpoint.schema.constants.SchemaConstants.*;
import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.createObjectRefWithFullObject;
import static com.evolveum.midpoint.util.MiscUtil.argCheck;

Expand Down Expand Up @@ -321,15 +322,15 @@ private void recordCaseCompletionInShadow(CaseType aCase, Task task, OperationRe
ShadowType.class,
shadowOid,
prismContext.deltaFor(ShadowType.class)
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATION_CASE_CLOSE_TIMESTAMP)
.item(CORRELATION_CASE_CLOSE_TIMESTAMP_PATH)
.replace(now)
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_PERFORMER_REF)
.item(CORRELATION_PERFORMER_REF_PATH)
.replaceRealValues(getPerformerRefs(aCase))
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_PERFORMER_COMMENT)
.item(CORRELATION_PERFORMER_COMMENT_PATH)
.replaceRealValues(getPerformerComments(aCase, task, result))
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_RESULTING_OWNER)
.item(CORRELATION_RESULTING_OWNER_PATH)
.replace(resultingOwnerRef)
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_SITUATION)
.item(CORRELATION_SITUATION_PATH)
.replace(situation)
.asItemDeltas(),
result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import javax.xml.datatype.XMLGregorianCalendar;

import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy;

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

Expand All @@ -33,6 +35,8 @@
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import static com.evolveum.midpoint.schema.constants.SchemaConstants.*;

/**
* Manages correlation that occurs _during synchronization pre-processing_.
*
Expand Down Expand Up @@ -205,7 +209,10 @@ private void closeCaseIfNeeded(OperationResult result) throws SchemaException {
}

private void applyCorrelationResultToShadow(CompleteCorrelationResult correlationResult) throws SchemaException {
S_ItemEntry builder = PrismContext.get().deltaFor(ShadowType.class);
S_ItemEntry builder =
PrismContext.get().deltaFor(ShadowType.class)
.oldObject(getShadow())
.optimizing();
XMLGregorianCalendar lastStart = getShadowCorrelationStartTimestamp();
XMLGregorianCalendar lastEnd = getShadowCorrelationEndTimestamp();
if (lastStart == null || lastEnd != null) {
Expand All @@ -218,20 +225,25 @@ private void applyCorrelationResultToShadow(CompleteCorrelationResult correlatio
// We set ERROR only if there is no previous situation recorded
// ...and we set none of the other items.
builder = builder
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_SITUATION)
.item(CORRELATION_SITUATION_PATH)
.replace(CorrelationSituationType.ERROR);
}
} else {
// The default delta-optimization does not work here because of PCV IDs, so we must compare on our own.
if (ownerOptionsChanged(correlationResult)) {
builder = builder
.item(CORRELATION_OWNER_OPTIONS_PATH)
.replace(CloneUtil.clone(correlationResult.getOwnerOptions()));
}

// @formatter:off
builder = builder
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_SITUATION)
.item(CORRELATION_SITUATION_PATH)
.replace(correlationResult.getSituation())
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_OWNER_OPTIONS)
.replace(CloneUtil.clone(correlationResult.getOwnerOptions()))
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_RESULTING_OWNER)
.item(CORRELATION_RESULTING_OWNER_PATH)
.replace(ObjectTypeUtil.createObjectRef(correlationResult.getOwner()))
// The following may be already applied by the correlator. But better twice than not at all.
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATOR_STATE)
.item(CORRELATION_CORRELATOR_STATE_PATH)
.replace(correlationContext.getCorrelatorState());
// @formatter:on
}
Expand All @@ -242,12 +254,32 @@ private void applyCorrelationResultToShadow(CompleteCorrelationResult correlatio
setShadowCorrelationEndTime(correlationResult.isDone());
}

private boolean ownerOptionsChanged(CompleteCorrelationResult correlationResult) {
var oldCorrelation = getShadow().getCorrelation();
ResourceObjectOwnerOptionsType oldOptions = oldCorrelation != null ? oldCorrelation.getOwnerOptions() : null;
ResourceObjectOwnerOptionsType newOptions = correlationResult.getOwnerOptions();

if (oldOptions == null) {
return newOptions != null;
} else {
if (newOptions == null) {
return true;
} else {
// We have to ignore auto-generated PCV IDs
return !oldOptions.asPrismContainerValue().equals(
newOptions.asPrismContainerValue(), EquivalenceStrategy.REAL_VALUE);
}
}
}

private void setShadowCorrelationEndTime(boolean done) throws SchemaException {
if (!done && getShadowCorrelationEndTimestamp() == null) {
return;
}
syncCtx.applyShadowDeltas(
PrismContext.get().deltaFor(ShadowType.class)
.oldObject(getShadow())
.optimizing()
.item(ShadowType.F_CORRELATION, ShadowCorrelationStateType.F_CORRELATION_END_TIMESTAMP)
.replace(
done ? XmlTypeConverter.createXMLGregorianCalendar() : null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;

import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationType;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -67,26 +69,31 @@ ShadowUpdater updateAllSyncMetadataRespectingMode() throws SchemaException {

XMLGregorianCalendar now = beans.clock.currentTimeXMLGregorianCalendar();

if (syncCtx.areShadowChangesPersistent()) {
updateSyncSituation();
updateSyncSituationDescription(now);
updateBasicSyncTimestamp(now); // this is questionable, but the same behavior is in LinkUpdater class
if (shadowBefore.getSynchronizationSituation() != syncCtx.getSituation()) {
updateSyncSituation(syncCtx.getSituation());
updateSyncSituationDescription(syncCtx.getSituation(), now);
}
updateCoordinatesIfUnknown();

updateBasicSyncTimestamp(now); // needed e.g. for 3rd part of reconciliation

return this;
}

private void updateSyncSituation() throws SchemaException {
void resetSynchronizationSituation() throws SchemaException {
updateSyncSituation(null);
updateSyncSituationDescription(null, beans.clock.currentTimeXMLGregorianCalendar());
}

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

private void updateSyncSituationDescription(XMLGregorianCalendar now) throws SchemaException {
private void updateSyncSituationDescription(SynchronizationSituationType situation, XMLGregorianCalendar now) throws SchemaException {
applyShadowDelta(
createSynchronizationSituationDescriptionDelta(
syncCtx.getShadowedResourceObject(),
syncCtx.getSituation(),
situation,
now,
syncCtx.getChannel(),
syncCtx.isFullMode()));
Expand All @@ -103,34 +110,24 @@ private void updateBasicSyncTimestamp(XMLGregorianCalendar now) throws SchemaExc
SynchronizationUtils.createSynchronizationTimestampDelta(shadowBefore, now));
}

ShadowUpdater updateBothSyncTimestamps() throws SchemaException {
void updateBasicSyncTimestamp() throws SchemaException {
updateBasicSyncTimestamp(
beans.clock.currentTimeXMLGregorianCalendar());
}

void updateBothSyncTimestamps() throws SchemaException {
XMLGregorianCalendar now = beans.clock.currentTimeXMLGregorianCalendar();
updateBasicSyncTimestamp(now);
updateFullSyncTimestamp(now);
return this;
}

/**
* Updates kind/intent if some of them are null/empty. This is used if synchronization is skipped.
*/
ShadowUpdater updateCoordinatesIfMissing() throws SchemaException {
assert syncCtx.isComplete();
return updateCoordinates(false);
}

/**
* Updates kind/intent if some of them are null/empty/unknown. This is used if synchronization is NOT skipped.
*
* TODO why the difference from {@link #updateCoordinatesIfMissing()}? Is there any reason for it?
* TODO this behavior should be made configurable
* Updates kind/intent if some of them are null/empty/unknown.
*/
private void updateCoordinatesIfUnknown() throws SchemaException {
assert syncCtx.isComplete();
updateCoordinates(true);
}

private ShadowUpdater updateCoordinates(boolean overwriteUnknownValues) throws SchemaException {
assert syncCtx.isComplete();
void updateCoordinates() throws SchemaException {
if (!syncCtx.isComplete()) {
return;
}
SynchronizationContext.Complete<?> completeCtx = (SynchronizationContext.Complete<?>) syncCtx;

ShadowType shadow = completeCtx.getShadowedResourceObject();
Expand All @@ -141,14 +138,10 @@ private ShadowUpdater updateCoordinates(boolean overwriteUnknownValues) throws S
String ctxIntent = completeCtx.getTypeIdentification().getIntent();
String ctxTag = completeCtx.getTag();

boolean typeEmpty = shadowKind == null || StringUtils.isBlank(shadowIntent);
boolean typeNotKnown = ShadowUtil.isNotKnown(shadowKind) || ShadowUtil.isNotKnown(shadowIntent);

// Are we going to update the kind/intent?
boolean updateType =
syncCtx.isForceClassificationUpdate() // typically when sorter is used
|| typeEmpty
|| typeNotKnown && overwriteUnknownValues;
|| !ShadowUtil.isClassified(shadowKind, shadowIntent);

if (updateType) {
// Before 4.6, the kind was updated unconditionally, only intent was driven by "force intent change" flag.
Expand All @@ -168,7 +161,6 @@ private ShadowUpdater updateCoordinates(boolean overwriteUnknownValues) throws S
.asItemDelta());
}

return this;
}

@NotNull List<ItemDelta<?, ?>> getDeltas() {
Expand All @@ -193,9 +185,9 @@ void commit(OperationResult result) {
try {
if (isShadowSimulation()) {
commitToSimulation(result);
} else {
commitToRepository(result);
keepOnlySynchronizationTimestampDelta();
}
commitToRepository(result);
recordModificationExecuted(null);
} catch (Throwable t) {
recordModificationExecuted(t);
Expand All @@ -204,6 +196,12 @@ void commit(OperationResult result) {
deltas.clear();
}

/** Even in low-level simulations, we want to record synchronization timestamp because of 3rd stage of reconciliation. */
private void keepOnlySynchronizationTimestampDelta() {
deltas.removeIf(
delta -> !ShadowType.F_SYNCHRONIZATION_TIMESTAMP.equivalent(delta.getPath()));
}

private boolean isShadowSimulation() {
return syncCtx.getTask().areShadowChangesSimulated();
}
Expand All @@ -220,6 +218,9 @@ private void commitToSimulation(OperationResult result) {
}

private void commitToRepository(OperationResult result) {
if (deltas.isEmpty()) {
return; // Could be in the low-level simulation mode
}
try {
beans.cacheRepositoryService.modifyObject(ShadowType.class, syncCtx.getShadowOid(), deltas, result);
} catch (ObjectNotFoundException ex) {
Expand Down

0 comments on commit 6cfc4c5

Please sign in to comment.