diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java
index 4eb63704292..58163fd6dc4 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java
@@ -159,10 +159,18 @@ public boolean isVisible(){
protected void populateAssignmentDetailsPanel(ListItem item){
AssignmentEditorPanel editor = new AssignmentEditorPanel(ID_ROW, item.getModel()){
+ private static final long serialVersionUID = 1L;
+
@Override
protected boolean ignoreMandatoryAttributes(){
return AssignmentTablePanel.this.ignoreMandatoryAttributes();
}
+
+ @Override
+ protected boolean isRelationEditable(){
+ return AssignmentTablePanel.this.isRelationEditable();
+ }
+
};
item.add(editor);
@@ -299,6 +307,10 @@ public void onClick(AjaxRequestTarget target) {
return items;
}
+ protected boolean isRelationEditable(){
+ return true;
+ }
+
protected void showAllAssignments(AjaxRequestTarget target) {
}
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java
index b1af5f02c6c..ba879dd2a66 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/InducedEntitlementsPanel.java
@@ -20,6 +20,7 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails;
import com.evolveum.midpoint.web.util.validation.MidpointFormValidator;
+import com.evolveum.midpoint.web.util.validation.MidpointFormValidatorImpl;
import com.evolveum.midpoint.web.util.validation.SimpleValidationError;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;
@@ -80,7 +81,10 @@ public InducedEntitlementsPanel(String id, IModel validateObject(PrismObject extends ObjectType> object, Collection> deltas) {
List errors = new ArrayList();
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentsList.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentsList.java
index 20fa26a37d4..2d507be1543 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentsList.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentsList.java
@@ -117,6 +117,8 @@ public void initLayout() {
AssignmentTablePanel panel = new AssignmentTablePanel(ID_ASSIGNMENT_TABLE_PANEL,
assignmentsModel){
+ private static final long serialVersionUID = 1L;
+
@Override
protected List createAssignmentMenu() {
List items = new ArrayList<>();
@@ -138,11 +140,17 @@ public void onClick(AjaxRequestTarget target) {
items.add(item);
return items;
}
-
+
@Override
- public IModel getLabel() {
- return createStringResource("PageAssignmentsList.assignmentsToRequest");
- }
+ public IModel getLabel() {
+ return createStringResource("PageAssignmentsList.assignmentsToRequest");
+ }
+
+ @Override
+ protected boolean isRelationEditable() {
+ return false;
+ }
+
};
mainForm.add(panel);
@@ -153,23 +161,23 @@ public List getObject() {
return getSessionStorage().getRoleCatalog().getTargetUserList();
}
},
- true, createStringResource("AssignmentCatalogPanel.selectTargetUser")){
+ true, createStringResource("AssignmentCatalogPanel.selectTargetUser")) {
private static final long serialVersionUID = 1L;
@Override
- protected String getUserButtonLabel(){
+ protected String getUserButtonLabel() {
return getTargetUserSelectionButtonLabel(getModelObject());
}
@Override
- protected void onDeleteSelectedUsersPerformed(AjaxRequestTarget target){
+ protected void onDeleteSelectedUsersPerformed(AjaxRequestTarget target) {
super.onDeleteSelectedUsersPerformed(target);
getSessionStorage().getRoleCatalog().setTargetUserList(new ArrayList<>());
targetUserChangePerformed(target);
}
@Override
- protected void multipleUsersSelectionPerformed(AjaxRequestTarget target, List usersList){
+ protected void multipleUsersSelectionPerformed(AjaxRequestTarget target, List usersList) {
getSessionStorage().getRoleCatalog().setTargetUserList(usersList);
targetUserChangePerformed(target);
}
@@ -278,9 +286,7 @@ private void onSingleUserRequestPerformed(AjaxRequestTarget target) {
result.recomputeStatus();
}
- findBackgroundTaskOperation(result);
- if (backgroundTaskOperationResult != null
- && StringUtils.isNotEmpty(backgroundTaskOperationResult.getAsynchronousOperationReference())){
+ if (hasBackgroundTaskOperation(result)){
result.setMessage(createStringResource("PageAssignmentsList.requestInProgress").getString());
showResult(result);
clearStorage();
@@ -340,9 +346,7 @@ private void onMultiUserRequestPerformed(AjaxRequestTarget target) {
"Failed to execute operaton " + result.getOperation(), e);
target.add(getFeedbackPanel());
}
- findBackgroundTaskOperation(result);
- if (backgroundTaskOperationResult != null
- && StringUtils.isNotEmpty(backgroundTaskOperationResult.getAsynchronousOperationReference())) {
+ if (hasBackgroundTaskOperation(result)) {
result.setMessage(createStringResource("PageAssignmentsList.requestInProgress").getString());
showResult(result);
clearStorage();
@@ -411,24 +415,9 @@ private ContainerDelta handleAssignmentDeltas(ObjectDelta focusDelta,
}
- private void findBackgroundTaskOperation(OperationResult result){
- if (backgroundTaskOperationResult != null) {
- return;
- } else {
- List subresults = result.getSubresults();
- if (subresults == null || subresults.size() == 0) {
- return;
- }
- for (OperationResult subresult : subresults) {
- if (subresult.getOperation().equals(OPERATION_WF_TASK_CREATED)) {
- backgroundTaskOperationResult = subresult;
- return;
- } else {
- findBackgroundTaskOperation(subresult);
- }
- }
- }
- return;
+ private boolean hasBackgroundTaskOperation(OperationResult result){
+ String caseOid = OperationResult.referenceToCaseOid(result.findAsynchronousOperationReference());
+ return StringUtils.isNotEmpty(caseOid);
}
private void handleModifyAssignmentDelta(AssignmentEditorDto assDto,
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/validation/MidpointFormValidatorImpl.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/validation/MidpointFormValidatorImpl.java
index 20ea088a598..b0ddbf27c4f 100644
--- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/validation/MidpointFormValidatorImpl.java
+++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/validation/MidpointFormValidatorImpl.java
@@ -14,6 +14,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -23,7 +24,9 @@
*
* @author shood
* */
-public class MidpointFormValidatorImpl implements MidpointFormValidator {
+public class MidpointFormValidatorImpl implements MidpointFormValidator, Serializable {
+
+ private static final long serialVersionUID = 1L;
@Override
public Collection validateObject(PrismObject extends ObjectType> object, Collection> deltas) {
diff --git a/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/equivalence/ParameterizedEquivalenceStrategy.java b/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/equivalence/ParameterizedEquivalenceStrategy.java
index 33118ecddb0..f21187991eb 100644
--- a/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/equivalence/ParameterizedEquivalenceStrategy.java
+++ b/infra/prism-api/src/main/java/com/evolveum/midpoint/prism/equivalence/ParameterizedEquivalenceStrategy.java
@@ -27,7 +27,7 @@ public class ParameterizedEquivalenceStrategy implements EquivalenceStrategy {
/**
* The (almost) highest level of recognition. Useful e.g. for comparing values for the purpose of XML editing.
- * Still, ignores e.g. definitions, parent objects, immutability flag, etc.
+ * Still, ignores e.g. definitions, parent objects, origin, immutability flag, etc.
*
* Corresponds to pre-4.0 flags ignoreMetadata = false, literal = true.
*/
@@ -39,7 +39,7 @@ public class ParameterizedEquivalenceStrategy implements EquivalenceStrategy {
*
* Currently this is the default for equals/hashCode.
*
- * Corresponds to pre-4.0 flags ignoreMetadata = false, literal = false.
+ * Roughly corresponds to pre-4.0 flags ignoreMetadata = false, literal = false.
*/
public static final ParameterizedEquivalenceStrategy NOT_LITERAL;
@@ -101,7 +101,7 @@ public class ParameterizedEquivalenceStrategy implements EquivalenceStrategy {
LITERAL.consideringOperationalData = true;
LITERAL.consideringContainerIds = true;
LITERAL.consideringDifferentContainerIds = true;
- LITERAL.consideringValueOrigin = true;
+ LITERAL.consideringValueOrigin = false;
LITERAL.consideringReferenceFilters = true;
LITERAL.compareElementNames = true;
putIntoNiceNames(LITERAL, "LITERAL");
@@ -111,7 +111,7 @@ public class ParameterizedEquivalenceStrategy implements EquivalenceStrategy {
NOT_LITERAL.consideringOperationalData = true;
NOT_LITERAL.consideringContainerIds = true;
NOT_LITERAL.consideringDifferentContainerIds = true;
- NOT_LITERAL.consideringValueOrigin = true;
+ NOT_LITERAL.consideringValueOrigin = false;
NOT_LITERAL.consideringReferenceFilters = true;
NOT_LITERAL.compareElementNames = true;
putIntoNiceNames(NOT_LITERAL, "NOT_LITERAL");
diff --git a/infra/prism-api/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/DeltaSetTripleType.java b/infra/prism-api/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/DeltaSetTripleType.java
index b58dd6d79e8..591f0614b9f 100644
--- a/infra/prism-api/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/DeltaSetTripleType.java
+++ b/infra/prism-api/src/main/java/com/evolveum/prism/xml/ns/_public/types_3/DeltaSetTripleType.java
@@ -29,7 +29,7 @@
"plus",
"minus"
})
-public class DeltaSetTripleType implements Serializable, JaxbVisitable {
+public class DeltaSetTripleType implements Serializable, JaxbVisitable, Cloneable {
@XmlElement
@Raw
diff --git a/infra/prism-impl/src/main/java/com/evolveum/midpoint/prism/impl/PrismObjectValueImpl.java b/infra/prism-impl/src/main/java/com/evolveum/midpoint/prism/impl/PrismObjectValueImpl.java
index 2d0e7054661..259ed7f3172 100644
--- a/infra/prism-impl/src/main/java/com/evolveum/midpoint/prism/impl/PrismObjectValueImpl.java
+++ b/infra/prism-impl/src/main/java/com/evolveum/midpoint/prism/impl/PrismObjectValueImpl.java
@@ -116,7 +116,7 @@ public boolean equals(Object o) {
// TODO consider the strategy
@Override
- public int hashCode(ParameterizedEquivalenceStrategy strategy) {
+ public int hashCode(@NotNull ParameterizedEquivalenceStrategy strategy) {
return Objects.hash(super.hashCode(strategy), oid);
}
diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/OperationResult.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/OperationResult.java
index 2f23d75da97..7c1aafd94fe 100644
--- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/OperationResult.java
+++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/result/OperationResult.java
@@ -153,6 +153,12 @@ public class OperationResult implements Serializable, DebugDumpable, ShortDumpab
private boolean collectingLogEntries; // NOT SERIALIZED
private boolean startedLoggingOverride; // NOT SERIALIZED
+ /**
+ * After a trace rooted at this operation result is stored, the dictionary that was extracted is stored here.
+ * It is necessary to correctly interpret traces in this result and its subresults.
+ */
+ private TraceDictionaryType extractedDictionary; // NOT SERIALIZED
+
private final List traces = new ArrayList<>();
// Caller can specify the reason of the operation invocation.
@@ -2414,4 +2420,12 @@ public void setCallerReason(String callerReason) {
public List getLogSegments() {
return logSegments;
}
+
+ public TraceDictionaryType getExtractedDictionary() {
+ return extractedDictionary;
+ }
+
+ public void setExtractedDictionary(TraceDictionaryType extractedDictionary) {
+ this.extractedDictionary = extractedDictionary;
+ }
}
diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java
index c5537234121..b039161a238 100644
--- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java
+++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java
@@ -571,7 +571,7 @@ public static ObjectType toObjectable(PrismObject object) {
return object != null ? (ObjectType) object.asObjectable() : null;
}
- public static PrismObject toPrismObject(T objectable) {
+ public static PrismObject asPrismObject(T objectable) {
//noinspection unchecked
return objectable != null ? objectable.asPrismObject() : null;
}
diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd
index 666f4ff99b3..941bf7a697e 100644
--- a/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd
+++ b/infra/schema/src/main/resources/xml/ns/public/common/common-model-context-3.xsd
@@ -813,6 +813,26 @@
+
+
+
+ Lens (model) context at input (text dump).
+
+
+ 4.0.1
+
+
+
+
+
+
+ Lens (model) context at output (text dump).
+
+
+ 4.0.1
+
+
+
@@ -2166,6 +2186,16 @@
+
+
+
+ Identifier of the dictionary. Used when multiple dictionaries are to be merged.
+
+
+ 4.0.1
+
+
+
@@ -2190,13 +2220,20 @@
-
+
Entry identifier.
+
+
+
+
+
+ Identifier of the dictionary in which this entry was originally created.
+
- true
+ 4.0.1
diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd
index ee34b586a2e..ae0a1fd345d 100644
--- a/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd
+++ b/infra/schema/src/main/resources/xml/ns/public/common/common-policy-3.xsd
@@ -2235,7 +2235,7 @@
for activation in these hardcoded states ("undefined" for active and deprecated
states, "archived" for archived state, "disabled" for all other states). To turn off this default behaviour
those hardcoded lifecycle states need to be explicitly defined in the state model
- and the forcedActivationStatus property shoule be left undefined.
+ and the forcedActivationStatus property should be left undefined.
@@ -2249,10 +2249,10 @@
There are cases when you need to force midpoint thinks that user has assigned some
- role. The assignemnt actually doesn't exist but there is a need to preted as it does.
+ role. The assignment actually doesn't exist but there is a need to pretend as it does.
This can be used e.g. for post-authentication flow. The user has assigned all business,
application, etc. roles but we don't want to consider these roles during his
- post-authentication proces. Instead, we want to pretend he has "temporary" role assigned
+ post-authentication process. Instead, we want to pretend he has "temporary" role assigned
which allows him to perform post-authentication.
@@ -2340,10 +2340,10 @@
There are cases when you need to force midpoint thinks that user has assigned some
- role. The assignemnt actually doesn't exist but there is a need to preted as it does.
+ role. The assignment actually doesn't exist but there is a need to pretend as it does.
This can be used e.g. for post-authentication flow. The user has assigned all business,
application, etc. roles but we don't want to consider these roles during his
- post-authentication proces. Instead, we want to pretend he has "temporary" role assigned
+ post-authentication process. Instead, we want to pretend he has "temporary" role assigned
which allows him to perform post-authentication.
diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java
index ad270b2762f..2819e2573a4 100644
--- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java
+++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java
@@ -2309,24 +2309,23 @@ public void notifyChange(ResourceObjectShadowChangeDescriptionType changeDescrip
PrismObject oldShadow;
LOGGER.trace("resolving old object");
if (!StringUtils.isEmpty(oldShadowOid)) {
+ // FIXME we should not get object from resource here: it should be sufficient to retrieve object from the repository
+ // (and even that can be skipped, if identifiers are correctly set) ... MID-5834
oldShadow = getObject(ShadowType.class, oldShadowOid, SelectorOptions.createCollection(GetOperationOptions.createDoNotDiscovery()), task, parentResult);
- eventDescription.setOldShadow(oldShadow);
+ eventDescription.setOldRepoShadow(oldShadow);
LOGGER.trace("old object resolved to: {}", oldShadow.debugDumpLazily());
} else {
LOGGER.trace("Old shadow null");
}
- PrismObject currentShadow = null;
- ShadowType currentShadowType = changeDescription.getCurrentShadow();
- LOGGER.trace("resolving current shadow");
- if (currentShadowType != null) {
- prismContext.adopt(currentShadowType);
- currentShadow = currentShadowType.asPrismObject();
- LOGGER.trace("current shadow resolved to {}", currentShadow.debugDumpLazily());
+ ShadowType currentResourceObjectBean = changeDescription.getCurrentShadow();
+ if (currentResourceObjectBean != null) {
+ PrismObject currentResourceObject = currentResourceObjectBean.asPrismObject();
+ prismContext.adopt(currentResourceObject);
+ LOGGER.trace("current resource object:\n{}", currentResourceObject.debugDumpLazily());
+ eventDescription.setCurrentResourceObject(currentResourceObject);
}
- eventDescription.setCurrentShadow(currentShadow);
-
ObjectDeltaType deltaType = changeDescription.getObjectDelta();
if (deltaType != null) {
diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java
index ee25e58770b..040e9167d1f 100644
--- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java
+++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java
@@ -236,7 +236,7 @@ public HookOperationMode run(LensContext context, Task
} finally {
recordTraceAtEnd(context, trace, result);
if (tracingRequested) {
- tracer.storeTrace(task, result);
+ tracer.storeTrace(task, result, parentResult);
TracingAppender.terminateCollecting(); // todo reconsider
LevelOverrideTurboFilter.cancelLoggingOverride(); // todo reconsider
}
@@ -266,10 +266,7 @@ private boolean startTracingIfRequested(LensContext co
private ClockworkRunTraceType recordTraceAtStart(LensContext context, Task task,
OperationResult result) throws SchemaException {
ClockworkRunTraceType trace = new ClockworkRunTraceType(prismContext);
- TracingLevelType level = result.getTracingLevel(trace.getClass());
- if (level.ordinal() >= TracingLevelType.MINIMAL.ordinal()) {
- trace.getText().add(context.debugDump()); // todo
- }
+ trace.setInputLensContextText(context.debugDump());
trace.setInputLensContext(context.toLensContextType(getExportTypeTraceOrReduced(trace, result)));
result.addTrace(trace);
return trace;
@@ -278,6 +275,7 @@ private ClockworkRunTraceType recordTraceAtStart(LensCont
private void recordTraceAtEnd(LensContext context, ClockworkRunTraceType trace,
OperationResult result) throws SchemaException {
if (trace != null) {
+ trace.setOutputLensContextText(context.debugDump());
trace.setOutputLensContext(context.toLensContextType(getExportTypeTraceOrReduced(trace, result)));
if (context.getFocusContext() != null) { // todo reconsider this
PrismObject objectAny = context.getFocusContext().getObjectAny();
@@ -537,6 +535,9 @@ public HookOperationMode click(LensContext context, Ta
ClockworkClickTraceType trace;
if (result.isTraced()) {
trace = new ClockworkClickTraceType(prismContext);
+ if (result.isTracingNormal(ClockworkClickTraceType.class)) {
+ trace.setInputLensContextText(context.debugDump());
+ }
trace.setInputLensContext(context.toLensContextType(getExportType(trace, result)));
result.getTraces().add(trace);
} else {
@@ -627,6 +628,9 @@ public HookOperationMode click(LensContext context, Ta
throw e;
} finally {
if (trace != null) {
+ if (result.isTracingNormal(ClockworkClickTraceType.class)) {
+ trace.setOutputLensContextText(context.debugDump());
+ }
trace.setOutputLensContext(context.toLensContextType(getExportType(trace, result)));
}
result.computeStatusIfUnknown();
diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ClockworkMedic.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ClockworkMedic.java
index 408509e07c4..712fac566af 100644
--- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ClockworkMedic.java
+++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ClockworkMedic.java
@@ -195,6 +195,9 @@ public void partialExecute(String baseComponentName, ProjectorComponentRunnable
ProjectorComponentTraceType trace;
if (result.isTraced()) {
trace = new ProjectorComponentTraceType();
+ if (result.isTracingNormal(ProjectorComponentTraceType.class)) {
+ trace.setInputLensContextText(context.debugDump());
+ }
trace.setInputLensContext(context.toLensContextType(getExportType(trace, result)));
result.addTrace(trace);
} else {
@@ -215,6 +218,9 @@ public void partialExecute(String baseComponentName, ProjectorComponentRunnable
} finally {
result.computeStatusIfUnknown();
if (trace != null) {
+ if (result.isTracingNormal(ProjectorComponentTraceType.class)) {
+ trace.setOutputLensContextText(context.debugDump());
+ }
trace.setOutputLensContext(context.toLensContextType(getExportType(trace, result)));
}
if (clockworkInspector != null) {
diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java
index ac8a14cde8e..24e8667564a 100644
--- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java
+++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java
@@ -107,6 +107,9 @@ public void load(LensContext context, String activityD
ProjectorComponentTraceType trace;
if (result.isTraced()) {
trace = new ProjectorComponentTraceType(prismContext);
+ if (result.isTracingNormal(ProjectorComponentTraceType.class)) {
+ trace.setInputLensContextText(context.debugDump());
+ }
trace.setInputLensContext(context.toLensContextType(getExportType(trace, result)));
result.addTrace(trace);
} else {
@@ -194,6 +197,9 @@ public void load(LensContext context, String activityD
throw e;
} finally {
if (trace != null) {
+ if (result.isTracingNormal(ProjectorComponentTraceType.class)) {
+ trace.setOutputLensContextText(context.debugDump());
+ }
trace.setOutputLensContext(context.toLensContextType(getExportType(trace, result)));
}
}
@@ -327,6 +333,9 @@ public void determineFocusContext(LensContext context,
FocusLoadedTraceType trace;
if (result.isTraced()) {
trace = new FocusLoadedTraceType();
+ if (result.isTracingNormal(FocusLoadedTraceType.class)) {
+ trace.setInputLensContextText(context.debugDump());
+ }
trace.setInputLensContext(context.toLensContextType(getExportType(trace, result)));
result.addTrace(trace);
} else {
@@ -392,6 +401,9 @@ public void determineFocusContext(LensContext context,
throw t;
} finally {
if (trace != null) {
+ if (result.isTracingNormal(FocusLoadedTraceType.class)) {
+ trace.setOutputLensContextText(context.debugDump());
+ }
trace.setOutputLensContext(context.toLensContextType(getExportType(trace, result)));
}
result.computeStatusIfUnknown();
@@ -1450,6 +1462,9 @@ public void loadFullShadow(LensContext context, LensPr
FullShadowLoadedTraceType trace;
if (result.isTraced()) {
trace = new FullShadowLoadedTraceType(prismContext);
+ if (result.isTracingNormal(FullShadowLoadedTraceType.class)) {
+ trace.setInputLensContextText(context.debugDump());
+ }
trace.setInputLensContext(context.toLensContextType(getExportType(trace, result)));
result.addTrace(trace);
} else {
@@ -1518,6 +1533,9 @@ public void loadFullShadow(LensContext context, LensPr
throw t;
} finally {
if (trace != null) {
+ if (result.isTracingNormal(FullShadowLoadedTraceType.class)) {
+ trace.setOutputLensContextText(context.debugDump());
+ }
trace.setOutputLensContext(context.toLensContextType(getExportType(trace, result)));
}
result.computeStatusIfUnknown();
diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationContext.java
index 1e5cac2a63a..d7516749650 100644
--- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationContext.java
+++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationContext.java
@@ -56,7 +56,7 @@ public class SynchronizationContext implements DebugDumpabl
private PrismObject currentShadow;
private PrismObject resource;
private PrismObject systemConfiguration;
- private String chanel;
+ private String channel;
private ExpressionProfile expressionProfile;
private Task task;
@@ -81,11 +81,11 @@ public class SynchronizationContext implements DebugDumpabl
private PrismContext prismContext;
- public SynchronizationContext(PrismObject applicableShadow, PrismObject currentShadow, PrismObject resource, String chanel, PrismContext prismContext, Task task, OperationResult result) {
+ public SynchronizationContext(PrismObject applicableShadow, PrismObject currentShadow, PrismObject resource, String channel, PrismContext prismContext, Task task, OperationResult result) {
this.applicableShadow = applicableShadow;
this.currentShadow = currentShadow;
this.resource = resource;
- this.chanel = chanel;
+ this.channel = channel;
this.task = task;
this.result = result;
this.prismContext = prismContext;
@@ -125,7 +125,7 @@ public boolean isSatisfyTaskConstraints() throws SchemaException {
return isApplicable;
}
- //TODO multi-threded tasks?
+ //TODO multi-threaded tasks?
private T getTaskPropertyValue(QName propertyName) {
PrismProperty prop = task.getExtensionPropertyOrClone(ItemName.fromQName(propertyName));
if (prop == null || prop.isEmpty()) {
@@ -197,19 +197,18 @@ public SynchronizationReactionType getReaction() throws ConfigurationException {
throw new ConfigurationException("No situation defined for a reaction in " + resource);
}
if (reactionSituation.equals(situation)) {
- if (syncReaction.getChannel() != null && !syncReaction.getChannel().isEmpty()) {
+ if (syncReaction.getChannel().isEmpty()) {
+ defaultReaction = syncReaction;
+ } else {
if (syncReaction.getChannel().contains("") || syncReaction.getChannel().contains(null)) {
defaultReaction = syncReaction;
}
- if (syncReaction.getChannel().contains(chanel)) {
+ if (syncReaction.getChannel().contains(channel)) {
reaction = syncReaction;
return reaction;
} else {
- LOGGER.trace("Skipping reaction {} because the channel does not match {}", reaction, chanel);
- continue;
+ LOGGER.trace("Skipping reaction {} because the channel does not match {}", reaction, channel);
}
- } else {
- defaultReaction = syncReaction;
}
}
}
@@ -243,8 +242,8 @@ public Boolean isDoReconciliation() {
}
public Boolean isLimitPropagation() {
- if (StringUtils.isNotBlank(chanel)) {
- QName channelQName = QNameUtil.uriToQName(chanel);
+ if (StringUtils.isNotBlank(channel)) {
+ QName channelQName = QNameUtil.uriToQName(channel);
// Discovery channel is used when compensating some inconsistent
// state. Therefore we do not want to propagate changes to other
// resources. We only want to resolve the problem and continue in
@@ -344,8 +343,8 @@ public void setSituation(SynchronizationSituationType situation) {
public PrismObject getSystemConfiguration() {
return systemConfiguration;
}
- public String getChanel() {
- return chanel;
+ public String getChannel() {
+ return channel;
}
public void setApplicableShadow(PrismObject applicableShadow) {
this.applicableShadow = applicableShadow;
@@ -359,8 +358,8 @@ public void setResource(PrismObject resource) {
public void setSystemConfiguration(PrismObject systemConfiguration) {
this.systemConfiguration = systemConfiguration;
}
- public void setChanel(String chanel) {
- this.chanel = chanel;
+ public void setChannel(String channel) {
+ this.channel = channel;
}
// public SynchronizationReactionType getReaction() {
@@ -448,7 +447,7 @@ public String debugDump(int indent) {
DebugUtil.debugDumpWithLabelLn(sb, "currentShadow", currentShadow, indent + 1);
DebugUtil.debugDumpWithLabelToStringLn(sb, "resource", resource, indent + 1);
DebugUtil.debugDumpWithLabelToStringLn(sb, "systemConfiguration", systemConfiguration, indent + 1);
- DebugUtil.debugDumpWithLabelToStringLn(sb, "chanel", chanel, indent + 1);
+ DebugUtil.debugDumpWithLabelToStringLn(sb, "channel", channel, indent + 1);
DebugUtil.debugDumpWithLabelToStringLn(sb, "expressionProfile", expressionProfile, indent + 1);
DebugUtil.debugDumpWithLabelToStringLn(sb, "objectSynchronization", objectSynchronization, indent + 1);
DebugUtil.debugDumpWithLabelLn(sb, "focusClass", focusClass, indent + 1);
diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java
index 77c9f08c3a7..cce1b42ecb4 100644
--- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java
+++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/SynchronizationServiceImpl.java
@@ -322,7 +322,7 @@ private ObjectSynchronizationDiscriminatorType evaluateSyn
String desc = "synchronization divider type ";
ExpressionVariables variables = ModelImplUtils.getDefaultExpressionVariables(null, syncCtx.getApplicableShadow(), null,
syncCtx.getResource(), syncCtx.getSystemConfiguration(), null, syncCtx.getPrismContext());
- variables.put(ExpressionConstants.VAR_CHANNEL, syncCtx.getChanel(), String.class);
+ variables.put(ExpressionConstants.VAR_CHANNEL, syncCtx.getChannel(), String.class);
try {
ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(task, result));
//noinspection unchecked
@@ -380,7 +380,7 @@ private boolean checkSynchronizationPolicy(Synchronization
if (!syncCtx.hasApplicablePolicy()) {
String message = "SYNCHRONIZATION no matching policy for " + syncCtx.getApplicableShadow() + " ("
+ syncCtx.getApplicableShadow().asObjectable().getObjectClass() + ") " + " on " + syncCtx.getResource()
- + ", ignoring change from channel " + syncCtx.getChanel();
+ + ", ignoring change from channel " + syncCtx.getChannel();
LOGGER.debug(message);
List> modifications = createShadowIntentAndSynchronizationTimestampDelta(syncCtx, false);
executeShadowModifications(syncCtx.getApplicableShadow(), modifications, task, subResult);
@@ -392,7 +392,7 @@ private boolean checkSynchronizationPolicy(Synchronization
if (!syncCtx.isSynchronizationEnabled()) {
String message = "SYNCHRONIZATION is not enabled for " + syncCtx.getResource()
- + " ignoring change from channel " + syncCtx.getChanel();
+ + " ignoring change from channel " + syncCtx.getChannel();
LOGGER.debug(message);
List> modifications = createShadowIntentAndSynchronizationTimestampDelta(syncCtx, true);
executeShadowModifications(syncCtx.getApplicableShadow(), modifications, task, subResult);
diff --git a/model/model-intest/src/test/resources/logback-test.xml b/model/model-intest/src/test/resources/logback-test.xml
index e9c8745cf89..940c95dacd8 100644
--- a/model/model-intest/src/test/resources/logback-test.xml
+++ b/model/model-intest/src/test/resources/logback-test.xml
@@ -87,7 +87,7 @@
-
+
diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java
index 7178824f503..5f86a51e781 100644
--- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java
+++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java
@@ -1642,7 +1642,7 @@ protected PrismObject getUserFromRepo(String userOid) throws ObjectNot
}
protected PrismObject findObjectByName(Class type, String name) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
- Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".findObjectByName");
+ Task task = getOrCreateTask("findObjectByName");
OperationResult result = task.getResult();
List> objects = modelService.searchObjects(type, createNameQuery(name), null, task, result);
if (objects.isEmpty()) {
@@ -3601,25 +3601,33 @@ protected void restartTask(String taskOid) throws CommonException {
LOGGER.warn("Sleep interrupted: {}", e.getMessage(), e);
}
- final OperationResult result = new OperationResult(AbstractIntegrationTest.class+".restartTask");
- Task task = taskManager.getTaskWithResult(taskOid, result);
- LOGGER.info("Restarting task {}", taskOid);
- if (task.getExecutionStatus() == TaskExecutionStatus.SUSPENDED) {
- LOGGER.debug("Task {} is suspended, resuming it", task);
- taskManager.resumeTask(task, result);
- } else if (task.getExecutionStatus() == TaskExecutionStatus.CLOSED) {
- LOGGER.debug("Task {} is closed, scheduling it to run now", task);
- taskManager.scheduleTasksNow(singleton(taskOid), result);
- } else if (task.getExecutionStatus() == TaskExecutionStatus.RUNNABLE) {
- if (taskManager.getLocallyRunningTaskByIdentifier(task.getTaskIdentifier()) != null) {
- // Task is really executing. Let's wait until it finishes; hopefully it won't start again (TODO)
- LOGGER.debug("Task {} is running, waiting while it finishes before restarting", task);
- waitForTaskFinish(taskOid, false);
+ OperationResult result = createSubresult("restartTask");
+ try {
+ Task task = taskManager.getTaskWithResult(taskOid, result);
+ LOGGER.info("Restarting task {}", taskOid);
+ if (task.getExecutionStatus() == TaskExecutionStatus.SUSPENDED) {
+ LOGGER.debug("Task {} is suspended, resuming it", task);
+ taskManager.resumeTask(task, result);
+ } else if (task.getExecutionStatus() == TaskExecutionStatus.CLOSED) {
+ LOGGER.debug("Task {} is closed, scheduling it to run now", task);
+ taskManager.scheduleTasksNow(singleton(taskOid), result);
+ } else if (task.getExecutionStatus() == TaskExecutionStatus.RUNNABLE) {
+ if (taskManager.getLocallyRunningTaskByIdentifier(task.getTaskIdentifier()) != null) {
+ // Task is really executing. Let's wait until it finishes; hopefully it won't start again (TODO)
+ LOGGER.debug("Task {} is running, waiting while it finishes before restarting", task);
+ waitForTaskFinish(taskOid, false);
+ }
+ LOGGER.debug("Task {} is finished, scheduling it to run now", task);
+ taskManager.scheduleTasksNow(singleton(taskOid), result);
+ } else {
+ throw new IllegalStateException(
+ "Task " + task + " cannot be restarted, because its state is: " + task.getExecutionStatus());
}
- LOGGER.debug("Task {} is finished, scheduling it to run now", task);
- taskManager.scheduleTasksNow(singleton(taskOid), result);
- } else {
- throw new IllegalStateException("Task " + task + " cannot be restarted, because its state is: " + task.getExecutionStatus());
+ } catch (Throwable t) {
+ result.recordFatalError(t);
+ throw t;
+ } finally {
+ result.computeStatusIfUnknown();
}
}
diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/access/WorkItemManager.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/access/WorkItemManager.java
index 5c634bd20d4..2fd340f2aee 100644
--- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/access/WorkItemManager.java
+++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/access/WorkItemManager.java
@@ -91,13 +91,14 @@ public void completeWorkItem(WorkItemId workItemId, @NotNull AbstractWorkItemOut
throw e;
} finally {
result.computeStatusIfUnknown();
- storeTraceIfRequested(tracingRequested, task, result);
+ storeTraceIfRequested(tracingRequested, task, result, parentResult);
}
}
- private void storeTraceIfRequested(boolean tracingRequested, Task task, OperationResult result) {
+ private void storeTraceIfRequested(boolean tracingRequested, Task task, OperationResult result,
+ OperationResult parentResult) {
if (tracingRequested) {
- tracer.storeTrace(task, result);
+ tracer.storeTrace(task, result, parentResult);
TracingAppender.terminateCollecting(); // todo reconsider
LevelOverrideTurboFilter.cancelLoggingOverride(); // todo reconsider
}
@@ -131,7 +132,7 @@ public void completeWorkItems(CompleteWorkItemsRequest request, Task task, Opera
throw e;
} finally {
result.computeStatusIfUnknown();
- storeTraceIfRequested(tracingRequested, task, result);
+ storeTraceIfRequested(tracingRequested, task, result, parentResult);
}
}
@@ -153,7 +154,7 @@ public void claimWorkItem(WorkItemId workItemId, Task task, OperationResult pare
throw e;
} finally {
result.computeStatusIfUnknown();
- storeTraceIfRequested(tracingRequested, task, result);
+ storeTraceIfRequested(tracingRequested, task, result, parentResult);
}
}
@@ -175,7 +176,7 @@ public void releaseWorkItem(WorkItemId workItemId, Task task, OperationResult pa
throw e;
} finally {
result.computeStatusIfUnknown();
- storeTraceIfRequested(tracingRequested, task, result);
+ storeTraceIfRequested(tracingRequested, task, result, parentResult);
}
}
@@ -215,7 +216,7 @@ public void delegateWorkItem(@NotNull WorkItemId workItemId, @NotNull WorkItemDe
throw new IllegalStateException(e);
} finally {
result.computeStatusIfUnknown();
- storeTraceIfRequested(tracingRequested, task, result);
+ storeTraceIfRequested(tracingRequested, task, result, parentResult);
}
}
diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/TestAssignmentsAdvanced.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/TestAssignmentsAdvanced.java
index af233d071e4..816f658e1d0 100644
--- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/TestAssignmentsAdvanced.java
+++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/assignments/TestAssignmentsAdvanced.java
@@ -1212,7 +1212,7 @@ private void previewAssignRolesToJack(String TEST_NAME, boolean immediate, boole
result.computeStatus();
//noinspection ConstantConditions
if (TRACE) {
- tracer.storeTrace(task, result);
+ tracer.storeTrace(task, result, null);
}
// we do not assert success here, because there are (intentional) exceptions in some of the expressions
diff --git a/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ResourceEventDescription.java b/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ResourceEventDescription.java
index 63ba13e6442..41648f49aff 100644
--- a/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ResourceEventDescription.java
+++ b/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ResourceEventDescription.java
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2010-2019 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
@@ -17,19 +17,19 @@
public class ResourceEventDescription implements Serializable, DebugDumpable{
- private PrismObject oldShadow;
- private PrismObject currentShadow;
+ private PrismObject oldRepoShadow;
+ private PrismObject currentResourceObject;
private ObjectDelta delta;
private String sourceChannel;
// private PrismObject resource;
- public PrismObject getCurrentShadow() {
- return currentShadow;
+ public PrismObject getCurrentResourceObject() {
+ return currentResourceObject;
}
- public PrismObject getOldShadow() {
- return oldShadow;
+ public PrismObject getOldRepoShadow() {
+ return oldRepoShadow;
}
public ObjectDelta getDelta() {
@@ -47,12 +47,12 @@ public void setDelta(ObjectDelta delta) {
this.delta = delta;
}
- public void setOldShadow(PrismObject oldShadow) {
- this.oldShadow = oldShadow;
+ public void setOldRepoShadow(PrismObject oldRepoShadow) {
+ this.oldRepoShadow = oldRepoShadow;
}
- public void setCurrentShadow(PrismObject currentShadow) {
- this.currentShadow = currentShadow;
+ public void setCurrentResourceObject(PrismObject currentResourceObject) {
+ this.currentResourceObject = currentResourceObject;
}
public void setSourceChannel(String sourceChannel) {
@@ -60,8 +60,8 @@ public void setSourceChannel(String sourceChannel) {
}
public boolean isProtected() {
- if ((currentShadow != null && ShadowUtil.isProtected(currentShadow))
- || (oldShadow != null && ShadowUtil.isProtected(oldShadow))) {
+ if ((currentResourceObject != null && ShadowUtil.isProtected(currentResourceObject))
+ || (oldRepoShadow != null && ShadowUtil.isProtected(oldRepoShadow))) {
return true;
}
if (delta != null && delta.isAdd() && ShadowUtil.isProtected(delta.getObjectToAdd())) {
@@ -72,8 +72,8 @@ public boolean isProtected() {
@Override
public String toString() {
- return "ResourceEventDescription(delta=" + delta + ", currentShadow="
- + SchemaDebugUtil.prettyPrint(currentShadow) + ", oldShadow=" + SchemaDebugUtil.prettyPrint(oldShadow) + ", sourceChannel=" + sourceChannel
+ return "ResourceEventDescription(delta=" + delta + ", currentResourceObject="
+ + SchemaDebugUtil.prettyPrint(currentResourceObject) + ", oldRepoShadow=" + SchemaDebugUtil.prettyPrint(oldRepoShadow) + ", sourceChannel=" + sourceChannel
+ ")";
}
@@ -107,22 +107,22 @@ public String debugDump(int indent) {
sb.append("\n");
SchemaDebugUtil.indentDebugDump(sb, indent+1);
- sb.append("oldShadow:");
- if (oldShadow == null) {
+ sb.append("oldRepoShadow:");
+ if (oldRepoShadow == null) {
sb.append(" null");
} else {
- sb.append(oldShadow.debugDump(indent+2));
+ sb.append(oldRepoShadow.debugDump(indent+2));
}
sb.append("\n");
SchemaDebugUtil.indentDebugDump(sb, indent+1);
- sb.append("currentShadow:");
- if (currentShadow == null) {
+ sb.append("currentResourceObject:");
+ if (currentResourceObject == null) {
sb.append(" null\n");
} else {
sb.append("\n");
- sb.append(currentShadow.debugDump(indent+2));
+ sb.append(currentResourceObject.debugDump(indent+2));
}
return sb.toString();
@@ -135,10 +135,10 @@ public String debugDump(int indent) {
public PrismObject getShadow() {
PrismObject shadow;
- if (getCurrentShadow() != null) {
- shadow = getCurrentShadow();
- } else if (getOldShadow() != null) {
- shadow = getOldShadow();
+ if (getCurrentResourceObject() != null) {
+ shadow = getCurrentResourceObject();
+ } else if (getOldRepoShadow() != null) {
+ shadow = getOldRepoShadow();
} else if (getDelta() != null && getDelta().isAdd()) {
if (getDelta().getObjectToAdd() == null) {
throw new IllegalStateException("Found ADD delta, but no object to add was specified.");
diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java
index 54bd5c12a81..6e722f3d668 100644
--- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java
+++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java
@@ -19,6 +19,7 @@
import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.StateReporter;
+import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
@@ -57,6 +58,8 @@ public class ProvisioningContext extends StateReporter {
private Map,ConnectorInstance> connectorMap;
private RefinedResourceSchema refinedSchema;
+ private String channelOverride;
+
public ProvisioningContext(@NotNull ResourceManager resourceManager, OperationResult parentResult) {
this.resourceManager = resourceManager;
this.parentResult = parentResult;
@@ -198,7 +201,12 @@ public RefinedObjectClassDefinition computeCompositeObjectClassDefinition(PrismO
}
public String getChannel() {
- return getTask()==null?null:getTask().getChannel();
+ Task task = getTask();
+ if (task != null && channelOverride == null) {
+ return task.getChannel();
+ } else {
+ return channelOverride;
+ }
}
public ConnectorInstance getConnector(Class operationCapabilityClass, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
@@ -357,4 +365,12 @@ public CachingStategyType getCachingStrategy()
ExpressionEvaluationException {
return ProvisioningUtil.getCachingStrategy(this);
}
+
+ public String getChannelOverride() {
+ return channelOverride;
+ }
+
+ public void setChannelOverride(String channelOverride) {
+ this.channelOverride = channelOverride;
+ }
}
diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceEventListenerImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceEventListenerImpl.java
index 0433acc1c58..334ee047a6b 100644
--- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceEventListenerImpl.java
+++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceEventListenerImpl.java
@@ -72,7 +72,7 @@ public void notifyEvent(ResourceEventDescription eventDescription, Task task, Op
LOGGER.trace("Received event notification with the description: {}", eventDescription.debugDumpLazily());
- if (eventDescription.getCurrentShadow() == null && eventDescription.getDelta() == null) {
+ if (eventDescription.getCurrentResourceObject() == null && eventDescription.getDelta() == null) {
throw new IllegalStateException("Neither current shadow, nor delta specified. It is required to have at least one of them specified.");
}
@@ -84,12 +84,12 @@ public void notifyEvent(ResourceEventDescription eventDescription, Task task, Op
Collection> primaryIdentifiers = ShadowUtil.getPrimaryIdentifiers(shadow);
- // TODO reconsider this
+ // TODO reconsider this... MID-5834 (e.g. is this OK with index-only attributes? probably not)
if (ctx.getCachingStrategy() == CachingStategyType.PASSIVE) {
- if (eventDescription.getCurrentShadow() == null && eventDescription.getOldShadow() != null && eventDescription.getDelta() != null) {
- PrismObject newShadow = eventDescription.getOldShadow().clone();
+ if (eventDescription.getCurrentResourceObject() == null && eventDescription.getOldRepoShadow() != null && eventDescription.getDelta() != null) {
+ PrismObject newShadow = eventDescription.getOldRepoShadow().clone();
eventDescription.getDelta().applyTo(newShadow);
- eventDescription.setCurrentShadow(newShadow);
+ eventDescription.setCurrentResourceObject(newShadow);
}
}
@@ -107,8 +107,9 @@ public void notifyEvent(ResourceEventDescription eventDescription, Task task, Op
LOGGER.warn("More than one primary identifier real value in {}: {}", eventDescription, primaryIdentifierRealValues);
primaryIdentifierRealValue = null;
}
- Change change = new Change(primaryIdentifierRealValue, primaryIdentifiers, eventDescription.getCurrentShadow(),
- eventDescription.getOldShadow(), eventDescription.getDelta());
+ Change change = new Change(primaryIdentifierRealValue, primaryIdentifiers, eventDescription.getCurrentResourceObject(),
+ eventDescription.getDelta());
+ change.setOldRepoShadow(eventDescription.getOldRepoShadow());
change.setObjectClassDefinition(ShadowUtil.getObjectClassDefinition(shadow));
LOGGER.trace("Starting to synchronize change: {}", change);
@@ -118,12 +119,12 @@ public void notifyEvent(ResourceEventDescription eventDescription, Task task, Op
private void applyDefinitions(ResourceEventDescription eventDescription,
OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
- if (eventDescription.getCurrentShadow() != null){
- shadowCache.applyDefinition(eventDescription.getCurrentShadow(), parentResult);
+ if (eventDescription.getCurrentResourceObject() != null){
+ shadowCache.applyDefinition(eventDescription.getCurrentResourceObject(), parentResult);
}
- if (eventDescription.getOldShadow() != null){
- shadowCache.applyDefinition(eventDescription.getOldShadow(), parentResult);
+ if (eventDescription.getOldRepoShadow() != null){
+ shadowCache.applyDefinition(eventDescription.getOldRepoShadow(), parentResult);
}
if (eventDescription.getDelta() != null) {
diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java
index 076872d42a2..6ab36136bde 100644
--- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java
+++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java
@@ -1823,7 +1823,7 @@ public boolean handleChange(Change change, OperationResult parentResult) {
} finally {
result.computeStatusIfUnknown();
if (tracingRequested) {
- tracer.storeTrace(task, result);
+ tracer.storeTrace(task, result, parentResult);
}
}
} finally {
@@ -1904,14 +1904,14 @@ private boolean preprocessChange(ProvisioningContext ctx, AttributesToReturn att
}
if (change.getObjectDelta() == null || !change.getObjectDelta().isDelete()) {
- if (change.getCurrentShadow() == null) {
+ if (change.getCurrentResourceObject() == null) {
// There is no current shadow in a change. Add it by fetching it explicitly.
try {
// TODO maybe we can postpone this fetch to ShadowCache.preProcessChange where it is implemented [pmed]
LOGGER.trace("Re-fetching object {} because it is not in the change", change.getIdentifiers());
PrismObject currentShadow = fetchResourceObject(shadowCtx,
change.getIdentifiers(), shadowAttrsToReturn, true, result); // todo consider whether it is always necessary to fetch the entitlements
- change.setCurrentShadow(currentShadow);
+ change.setCurrentResourceObject(currentShadow);
} catch (ObjectNotFoundException ex) {
result.recordHandledError(
"Object detected in change log no longer exist on the resource. Skipping processing this object.", ex);
@@ -1929,12 +1929,12 @@ private boolean preprocessChange(ProvisioningContext ctx, AttributesToReturn att
LOGGER.trace("Re-fetching object {} because of attrsToReturn", identification);
currentShadow = connector.fetchObject(identification, shadowAttrsToReturn, ctx, result);
} else {
- currentShadow = change.getCurrentShadow();
+ currentShadow = change.getCurrentResourceObject();
}
PrismObject processedCurrentShadow = postProcessResourceObjectRead(shadowCtx, currentShadow,
true, result);
- change.setCurrentShadow(processedCurrentShadow);
+ change.setCurrentResourceObject(processedCurrentShadow);
}
}
LOGGER.trace("Processed change\n:{}", change.debugDumpLazily());
@@ -1976,11 +1976,11 @@ public String startListeningForAsyncUpdates(@NotNull ProvisioningContext ctx,
change.setObjectClassDefinition(shadowCtx.getObjectClassDefinition());
}
- if (change.getCurrentShadow() != null) {
- shadowCaretaker.applyAttributesDefinition(ctx, change.getCurrentShadow());
+ if (change.getCurrentResourceObject() != null) {
+ shadowCaretaker.applyAttributesDefinition(ctx, change.getCurrentResourceObject());
PrismObject processedCurrentShadow = postProcessResourceObjectRead(shadowCtx,
- change.getCurrentShadow(), true, listenerResult);
- change.setCurrentShadow(processedCurrentShadow);
+ change.getCurrentResourceObject(), true, listenerResult);
+ change.setCurrentResourceObject(processedCurrentShadow);
} else {
// we will fetch current shadow later
}
@@ -1998,8 +1998,8 @@ public String startListeningForAsyncUpdates(@NotNull ProvisioningContext ctx,
}
private void setResourceOidIfMissing(Change change, String resourceOid) {
- setResourceOidIfMissing(change.getOldShadow(), resourceOid);
- setResourceOidIfMissing(change.getCurrentShadow(), resourceOid);
+ setResourceOidIfMissing(change.getOldRepoShadow(), resourceOid);
+ setResourceOidIfMissing(change.getCurrentResourceObject(), resourceOid);
if (change.getObjectDelta() != null) {
setResourceOidIfMissing(change.getObjectDelta().getObjectToAdd(), resourceOid);
}
diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectReferenceResolver.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectReferenceResolver.java
index 679569c3399..17b0a94a6ed 100644
--- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectReferenceResolver.java
+++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectReferenceResolver.java
@@ -11,6 +11,7 @@
import javax.xml.namespace.QName;
+import com.evolveum.midpoint.provisioning.impl.shadowmanager.ShadowManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@@ -32,9 +33,7 @@
import com.evolveum.midpoint.repo.common.expression.ExpressionFactory;
import com.evolveum.midpoint.repo.common.expression.ExpressionUtil;
import com.evolveum.midpoint.repo.common.expression.ExpressionVariables;
-import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.ResultHandler;
-import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.processor.ResourceObjectIdentification;
import com.evolveum.midpoint.schema.result.OperationResult;
diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java
index e788375c29b..0b3d2215a4c 100644
--- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java
+++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java
@@ -23,6 +23,7 @@
import com.evolveum.midpoint.provisioning.api.*;
import com.evolveum.midpoint.provisioning.impl.errorhandling.ErrorHandler;
import com.evolveum.midpoint.provisioning.impl.errorhandling.ErrorHandlerLocator;
+import com.evolveum.midpoint.provisioning.impl.shadowmanager.ShadowManager;
import com.evolveum.midpoint.provisioning.ucf.api.*;
import com.evolveum.midpoint.provisioning.util.ProvisioningUtil;
import com.evolveum.midpoint.repo.api.RepositoryService;
@@ -255,7 +256,6 @@ public PrismObject getShadow(String oid, PrismObject rep
Collection extends ResourceAttribute>> identifiers = ShadowUtil.getAllIdentifiers(repositoryShadow);
try {
-
try {
resourceShadow = resourceObjectConverter.getResourceObject(ctx, identifiers, true, parentResult);
@@ -292,31 +292,24 @@ public PrismObject getShadow(String oid, PrismObject rep
resourceShadow.asObjectable().setIntent(repositoryShadow.asObjectable().getIntent());
ProvisioningContext shadowCtx = ctx.spawn(resourceShadow);
- resourceManager.modifyResourceAvailabilityStatus(resource.asPrismObject(),
- AvailabilityStatusType.UP, parentResult);
+ resourceManager.modifyResourceAvailabilityStatus(resource.asPrismObject(), AvailabilityStatusType.UP, parentResult);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Shadow from repository:\n{}", repositoryShadow.debugDump(1));
LOGGER.trace("Resource object fetched from resource:\n{}", resourceShadow.debugDump(1));
}
- repositoryShadow = shadowManager.updateShadow(shadowCtx, resourceShadow, repositoryShadow,
- shadowState, parentResult);
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("Repository shadow after update:\n{}", repositoryShadow.debugDump(1));
- }
+ repositoryShadow = shadowManager.updateShadow(shadowCtx, resourceShadow, null, repositoryShadow, shadowState, parentResult);
+ LOGGER.trace("Repository shadow after update:\n{}", repositoryShadow.debugDumpLazily(1));
+
// Complete the shadow by adding attributes from the resource object
// This also completes the associations by adding shadowRefs
- PrismObject resultShadow = completeShadow(shadowCtx, resourceShadow, repositoryShadow, false, parentResult);
+ PrismObject assembledShadow = completeShadow(shadowCtx, resourceShadow, repositoryShadow, false, parentResult);
+ LOGGER.trace("Shadow when assembled:\n{}", assembledShadow.debugDumpLazily(1));
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("Shadow when assembled:\n{}", resultShadow.debugDump(1));
- }
+ PrismObject resultShadow = futurizeShadow(ctx, repositoryShadow, assembledShadow, options, now);
+ LOGGER.trace("Futurized assembled shadow:\n{}", resultShadow.debugDumpLazily(1));
- resultShadow = futurizeShadow(ctx, repositoryShadow, resultShadow, options, now);
- if (LOGGER.isTraceEnabled()) {
- LOGGER.trace("Futurized assembled shadow:\n{}", resultShadow.debugDump(1));
- }
parentResult.recordSuccess();
validateShadow(resultShadow, true);
return resultShadow;
@@ -333,9 +326,9 @@ public PrismObject getShadow(String oid, PrismObject rep
// is returned
parentResult.setStatus(OperationResultStatus.PARTIAL_ERROR);
}
- handledShadow = futurizeShadow(ctx, handledShadow, null, options, now);
- validateShadow(handledShadow, true);
- return handledShadow;
+ PrismObject futurizedShadow = futurizeShadow(ctx, handledShadow, null, options, now);
+ validateShadow(futurizedShadow, true);
+ return futurizedShadow;
} catch (GenericFrameworkException | ObjectAlreadyExistsException | PolicyViolationException e) {
throw new SystemException(e.getMessage(), e);
@@ -348,7 +341,6 @@ public PrismObject getShadow(String oid, PrismObject rep
// fetch for protected objects?
if (!ShadowUtil.isProtected(resourceShadow)) {
InternalMonitor.recordCount(InternalCounters.SHADOW_FETCH_OPERATION_COUNT);
-
}
}
}
@@ -2042,10 +2034,13 @@ public SearchResultMetadata searchObjectsIterative(final ProvisioningContext ctx
// shadow should have proper kind/intent
ProvisioningContext shadowCtx = shadowCaretaker.applyAttributesDefinition(ctx, repoShadow);
// TODO: shadowState
- repoShadow = shadowManager.updateShadow(shadowCtx, resourceShadow, repoShadow, null, parentResult);
+ repoShadow = shadowManager.updateShadow(shadowCtx, resourceShadow, null, repoShadow,
+ null, parentResult);
resultShadow = completeShadow(shadowCtx, resourceShadow, repoShadow, isDoDiscovery, objResult);
-
+
+ // TODO do we want also to futurize the shadow like in getObject?
+
//check and fix kind/intent
ShadowType repoShadowType = repoShadow.asObjectable();
if (isDoDiscovery && (repoShadowType.getKind() == null || repoShadowType.getIntent() == null)) { //TODO: check also empty?
diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/errorhandling/ObjectAlreadyExistHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/errorhandling/ObjectAlreadyExistHandler.java
index 0ad45d35cff..24366975a4e 100644
--- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/errorhandling/ObjectAlreadyExistHandler.java
+++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/errorhandling/ObjectAlreadyExistHandler.java
@@ -7,7 +7,6 @@
package com.evolveum.midpoint.provisioning.impl.errorhandling;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -29,7 +28,7 @@
import com.evolveum.midpoint.provisioning.impl.ProvisioningContext;
import com.evolveum.midpoint.provisioning.impl.ProvisioningOperationState;
import com.evolveum.midpoint.provisioning.impl.ShadowCaretaker;
-import com.evolveum.midpoint.provisioning.impl.ShadowManager;
+import com.evolveum.midpoint.provisioning.impl.shadowmanager.ShadowManager;
import com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException;
import com.evolveum.midpoint.provisioning.util.ProvisioningUtil;
import com.evolveum.midpoint.repo.api.RepositoryService;
diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/errorhandling/ObjectNotFoundHandler.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/errorhandling/ObjectNotFoundHandler.java
index f2139bcdd75..42ea1ef4bc9 100644
--- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/errorhandling/ObjectNotFoundHandler.java
+++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/errorhandling/ObjectNotFoundHandler.java
@@ -22,7 +22,7 @@
import com.evolveum.midpoint.provisioning.impl.ProvisioningContext;
import com.evolveum.midpoint.provisioning.impl.ProvisioningOperationState;
import com.evolveum.midpoint.provisioning.impl.ShadowCaretaker;
-import com.evolveum.midpoint.provisioning.impl.ShadowManager;
+import com.evolveum.midpoint.provisioning.impl.shadowmanager.ShadowManager;
import com.evolveum.midpoint.provisioning.impl.ShadowState;
import com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException;
import com.evolveum.midpoint.provisioning.util.ProvisioningUtil;
diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/shadowmanager/ShadowDeltaComputer.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/shadowmanager/ShadowDeltaComputer.java
new file mode 100644
index 00000000000..38e4709f49a
--- /dev/null
+++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/shadowmanager/ShadowDeltaComputer.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2019 Evolveum and contributors
+ *
+ * This work is dual-licensed under the Apache License 2.0
+ * and European Union Public License. See LICENSE file for details.
+ */
+
+package com.evolveum.midpoint.provisioning.impl.shadowmanager;
+
+import com.evolveum.midpoint.common.Clock;
+import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition;
+import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition;
+import com.evolveum.midpoint.prism.*;
+import com.evolveum.midpoint.prism.delta.ItemDelta;
+import com.evolveum.midpoint.prism.delta.ObjectDelta;
+import com.evolveum.midpoint.prism.delta.PropertyDelta;
+import com.evolveum.midpoint.prism.match.MatchingRule;
+import com.evolveum.midpoint.prism.match.MatchingRuleRegistry;
+import com.evolveum.midpoint.prism.path.ItemPath;
+import com.evolveum.midpoint.prism.polystring.PolyString;
+import com.evolveum.midpoint.provisioning.impl.ProvisioningContext;
+import com.evolveum.midpoint.provisioning.impl.ShadowState;
+import com.evolveum.midpoint.provisioning.util.ProvisioningUtil;
+import com.evolveum.midpoint.schema.constants.SchemaConstants;
+import com.evolveum.midpoint.schema.util.ShadowUtil;
+import com.evolveum.midpoint.util.QNameUtil;
+import com.evolveum.midpoint.util.exception.*;
+import com.evolveum.midpoint.util.logging.Trace;
+import com.evolveum.midpoint.util.logging.TraceManager;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingMetadataType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.CachingStategyType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.xml.namespace.QName;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Computes deltas to be applied to repository shadows.
+ * This functionality grew too large to deserve special implementation class.
+ *
+ * In the future we might move more functionality here and rename this class.
+ */
+@Component
+public class ShadowDeltaComputer {
+
+ private static final Trace LOGGER = TraceManager.getTrace(ShadowDeltaComputer.class);
+
+ @Autowired private Clock clock;
+ @Autowired private MatchingRuleRegistry matchingRuleRegistry;
+ @Autowired private PrismContext prismContext;
+
+ @NotNull
+ ObjectDelta computeShadowDelta(@NotNull ProvisioningContext ctx,
+ @NotNull PrismObject repoShadowOld, PrismObject resourceShadowNew,
+ ObjectDelta resourceObjectDelta, ShadowState shadowState)
+ throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException,
+ ExpressionEvaluationException {
+
+ ObjectDelta computedShadowDelta = repoShadowOld.createModifyDelta();
+
+ RefinedObjectClassDefinition ocDef = ctx.computeCompositeObjectClassDefinition(resourceShadowNew);
+ PrismContainer currentResourceAttributes = resourceShadowNew.findContainer(ShadowType.F_ATTRIBUTES);
+ PrismContainer oldRepoAttributes = repoShadowOld.findContainer(ShadowType.F_ATTRIBUTES);
+ ShadowType oldRepoShadowType = repoShadowOld.asObjectable();
+
+ CachingStategyType cachingStrategy = ProvisioningUtil.getCachingStrategy(ctx);
+ Collection incompleteCacheableItems = new HashSet<>();
+
+ processAttributes(computedShadowDelta, incompleteCacheableItems, oldRepoAttributes, currentResourceAttributes,
+ resourceObjectDelta, ocDef, cachingStrategy);
+
+ PolyString currentShadowName = ShadowUtil.determineShadowName(resourceShadowNew);
+ PolyString oldRepoShadowName = repoShadowOld.getName();
+ if (!currentShadowName.equalsOriginalValue(oldRepoShadowName)) {
+ PropertyDelta> shadowNameDelta = prismContext.deltaFactory().property().createModificationReplaceProperty(ShadowType.F_NAME,
+ repoShadowOld.getDefinition(),currentShadowName);
+ computedShadowDelta.addModification(shadowNameDelta);
+ }
+
+ PropertyDelta auxOcDelta = ItemUtil.diff(
+ repoShadowOld.findProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS),
+ resourceShadowNew.findProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS));
+ if (auxOcDelta != null) {
+ computedShadowDelta.addModification(auxOcDelta);
+ }
+
+ // Resource object obviously exists in this case. However, we do not want to mess with isExists flag in some
+ // situations (e.g. in CORPSE state) as this existence may be just a quantum illusion.
+ if (shadowState == ShadowState.CONCEPTION || shadowState == ShadowState.GESTATION) {
+ PropertyDelta existsDelta = computedShadowDelta.createPropertyModification(ShadowType.F_EXISTS);
+ existsDelta.setRealValuesToReplace(true);
+ computedShadowDelta.addModification(existsDelta);
+ }
+
+ if (cachingStrategy == CachingStategyType.NONE) {
+ if (oldRepoShadowType.getCachingMetadata() != null) {
+ computedShadowDelta.addModificationReplaceProperty(ShadowType.F_CACHING_METADATA);
+ }
+
+ } else if (cachingStrategy == CachingStategyType.PASSIVE) {
+
+ compareUpdateProperty(computedShadowDelta, SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, resourceShadowNew, repoShadowOld);
+ compareUpdateProperty(computedShadowDelta, SchemaConstants.PATH_ACTIVATION_VALID_FROM, resourceShadowNew, repoShadowOld);
+ compareUpdateProperty(computedShadowDelta, SchemaConstants.PATH_ACTIVATION_VALID_TO, resourceShadowNew, repoShadowOld);
+ compareUpdateProperty(computedShadowDelta, SchemaConstants.PATH_ACTIVATION_LOCKOUT_STATUS, resourceShadowNew, repoShadowOld);
+
+ if (incompleteCacheableItems.isEmpty()) {
+ CachingMetadataType cachingMetadata = new CachingMetadataType();
+ cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar());
+ computedShadowDelta.addModificationReplaceProperty(ShadowType.F_CACHING_METADATA, cachingMetadata);
+ } else {
+ LOGGER.trace("Shadow has incomplete cacheable items; will not update caching timestamp: {}", incompleteCacheableItems);
+ }
+ } else {
+ throw new ConfigurationException("Unknown caching strategy "+cachingStrategy);
+ }
+ return computedShadowDelta;
+ }
+
+ private void processAttributes(ObjectDelta computedShadowDelta, Collection incompleteCacheableAttributes,
+ PrismContainer oldRepoAttributes, PrismContainer currentResourceAttributes,
+ ObjectDelta resourceObjectDelta, RefinedObjectClassDefinition ocDef, CachingStategyType cachingStrategy)
+ throws SchemaException, ConfigurationException {
+
+ // For complete attributes we can proceed as before: take currentResourceAttributes as authoritative.
+ // If not obtained from the resource, they were created from object delta anyway. :)
+ // However, for incomplete (e.g. index-only) attributes we have to rely on object delta, if present.
+ // TODO clean this up! MID-5834
+
+ for (Item, ?> currentResourceAttrItem: currentResourceAttributes.getValue().getItems()) {
+ if (currentResourceAttrItem instanceof PrismProperty>) {
+ //noinspection unchecked
+ PrismProperty