Skip to content

Commit

Permalink
MID-4568 small steps to improve safety of createOnDemand, still not w…
Browse files Browse the repository at this point in the history
…orking correctly. code not yet cleaned up. wip
  • Loading branch information
1azyman committed Oct 26, 2022
1 parent 8bdff50 commit a91f619
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
import java.util.List;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.api.ModelInteractionService;

import com.evolveum.midpoint.model.api.context.ModelContext;

import com.evolveum.midpoint.model.api.context.ModelElementContext;

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

Expand Down Expand Up @@ -79,16 +85,22 @@ public abstract class AbstractSearchExpressionEvaluator<

private final ObjectResolver objectResolver;
private final ModelService modelService;
/**
* todo preview changes method calls in this class should be removed and everything should go through ModelService.executeChanges()
*/
@Deprecated
private final ModelInteractionService modelInteractionService;
protected CacheConfigurationManager cacheConfigurationManager;

AbstractSearchExpressionEvaluator(QName elementName, E expressionEvaluatorType,
D outputDefinition, Protector protector, PrismContext prismContext,
ObjectResolver objectResolver, ModelService modelService, SecurityContextManager securityContextManager,
ObjectResolver objectResolver, ModelService modelService, ModelInteractionService modelInteractionService, SecurityContextManager securityContextManager,
LocalizationService localizationService,
CacheConfigurationManager cacheConfigurationManager) {
super(elementName, expressionEvaluatorType, outputDefinition, protector, prismContext, securityContextManager, localizationService);
this.objectResolver = objectResolver;
this.modelService = modelService;
this.modelInteractionService = modelInteractionService;
this.cacheConfigurationManager = cacheConfigurationManager;
}

Expand Down Expand Up @@ -139,7 +151,7 @@ protected List<V> transformSingleValue(
resultValues = new ArrayList<>(1);
resultValues.add(
createPrismValue(
expressionEvaluatorBean.getOid(), targetTypeQName, additionalAttributeDeltas, context));
expressionEvaluatorBean.getOid(), null, targetTypeQName, additionalAttributeDeltas, context));

} else {

Expand All @@ -165,18 +177,22 @@ protected List<V> transformSingleValue(
if (defaultTargetRef != null) {
resultValues.add(
createPrismValue(
defaultTargetRef.getOid(), targetTypeQName, additionalAttributeDeltas, context));
defaultTargetRef.getOid(), null, targetTypeQName, additionalAttributeDeltas, context));
}
}
}

if (resultValues.isEmpty()
&& Boolean.TRUE.equals(expressionEvaluatorBean.isCreateOnDemand())
&& (valueDestination == PlusMinusZero.PLUS || valueDestination == PlusMinusZero.ZERO || useNew)) {
String createdObjectOid =
createOnDemand(targetTypeClass, variables, context, context.getContextDescription(), task, result);
// String createdObjectOid =
// createOnDemand(targetTypeClass, variables, context, context.getContextDescription(), task, result);
// resultValues.add(
// createPrismValue(createdObjectOid, targetTypeQName, additionalAttributeDeltas, context));

PrismObject createdObject = createOnDemand(targetTypeClass, variables, context, context.getContextDescription(), task, result);
resultValues.add(
createPrismValue(createdObjectOid, targetTypeQName, additionalAttributeDeltas, context));
createPrismValue(createdObject.getOid(), createdObject, targetTypeQName, additionalAttributeDeltas, context));
}

LOGGER.trace("Search expression {} (valueDestination={}) got {} results for query {}",
Expand Down Expand Up @@ -442,7 +458,7 @@ private void executeSearch(
if (rawResults != null) {
rawResults.add(object);
}
valueResults.add(createPrismValue(object.getOid(), targetTypeQName, additionalAttributeDeltas, params));
valueResults.add(createPrismValue(object.getOid(), null, targetTypeQName, additionalAttributeDeltas, params));
}
}

Expand All @@ -459,11 +475,12 @@ protected void extendOptions(Collection<SelectorOptions<GetOperationOptions>> op

protected abstract V createPrismValue(
String oid,
PrismObject object,
QName targetTypeQName,
List<ItemDelta<V, D>> additionalAttributeDeltas,
ExpressionEvaluationContext params);

private String createOnDemand(Class<O> targetTypeClass, VariablesMap variables,
private PrismObject createOnDemand(Class<O> targetTypeClass, VariablesMap variables,
ExpressionEvaluationContext params, String contextDescription, Task task, OperationResult result)
throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException {
if (LOGGER.isTraceEnabled()) {
Expand All @@ -490,6 +507,26 @@ private String createOnDemand(Class<O> targetTypeClass, VariablesMap variables,

ObjectDelta<O> addDelta = newObject.createAddDelta();
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(addDelta);

boolean isCreateOnDemandSafe = false; // todo this should be true by default later on

// todo we should probably store model execute options in task directly, using model operation context is not correct
ModelExecuteOptionsType options = task.getModelOperationContext() != null ? task.getModelOperationContext().getOptions() : new ModelExecuteOptionsType();
SimulationOptionsType simulation = options.getSimulation();
if (simulation != null && simulation.getCreateOnDemand() != null) {
isCreateOnDemandSafe = CreateOnDemandOptionsType.SAFE.equals(simulation.getCreateOnDemand());
}

if (isCreateOnDemandSafe) {
try {
ModelContext<O> context = modelInteractionService.previewChanges(deltas, null, task, result);
ModelElementContext focusContext = context.getFocusContext();
return focusContext.getObjectNew();
} catch (Exception ex) {
throw new ExpressionEvaluationException(ex.getMessage(), ex);
}
}

Collection<ObjectDeltaOperation<? extends ObjectType>> executedChanges;
try {
executedChanges = modelService.executeChanges(deltas, null, task, result);
Expand All @@ -498,7 +535,8 @@ private String createOnDemand(Class<O> targetTypeClass, VariablesMap variables,
throw new ExpressionEvaluationException(e.getMessage(), e);
}

return ObjectDeltaOperation.findAddDeltaOid(executedChanges, newObject);
ObjectDeltaOperation deltaOperation = ObjectDeltaOperation.findAddDelta(executedChanges, newObject);
return deltaOperation != null ? deltaOperation.getObjectDelta().getObjectToAdd() : null;
}

// Override the default in this case. It makes more sense like this.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
import javax.xml.namespace.QName;

import com.evolveum.midpoint.common.LocalizationService;
import com.evolveum.midpoint.model.api.ModelInteractionService;
import com.evolveum.midpoint.model.api.ModelService;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.crypto.Protector;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.ItemDeltaCollectionsUtil;
Expand Down Expand Up @@ -45,20 +47,24 @@ public class AssignmentTargetSearchExpressionEvaluator
AssignmentTargetSearchExpressionEvaluator(QName elementName,
AssignmentTargetSearchExpressionEvaluatorType expressionEvaluatorType,
PrismContainerDefinition<AssignmentType> outputDefinition,Protector protector, PrismContext prismContext,
ObjectResolver objectResolver, ModelService modelService, SecurityContextManager securityContextManager,
ObjectResolver objectResolver, ModelService modelService, ModelInteractionService modelInteractionService, SecurityContextManager securityContextManager,
LocalizationService localizationService, CacheConfigurationManager cacheConfigurationManager) {
super(elementName, expressionEvaluatorType, outputDefinition, protector, prismContext, objectResolver,
modelService, securityContextManager, localizationService, cacheConfigurationManager);
modelService, modelInteractionService, securityContextManager, localizationService, cacheConfigurationManager);
}

protected PrismContainerValue<AssignmentType> createPrismValue(
String oid,
PrismObject object,
QName targetTypeQName,
List<ItemDelta<PrismContainerValue<AssignmentType>, PrismContainerDefinition<AssignmentType>>> additionalAttributeDeltas,
ExpressionEvaluationContext context) {

AssignmentType assignment = new AssignmentType()
.targetRef(oid, targetTypeQName, getRelation());
ObjectReferenceType ref = new ObjectReferenceType();
ref.oid(oid).type(targetTypeQName).relation(getRelation());
ref.asReferenceValue().setObject(object);

AssignmentType assignment = new AssignmentType().targetRef(ref);
assignment.getSubtype().addAll(getSubtypes());

//noinspection unchecked
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.api.ModelInteractionService;
import com.evolveum.midpoint.model.api.ModelService;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
Expand Down Expand Up @@ -40,15 +41,17 @@ public class AssignmentTargetSearchExpressionEvaluatorFactory
private final PrismContext prismContext;
private final Protector protector;
private final ModelService modelService;
private final ModelInteractionService modelInteractionService;
private final SecurityContextManager securityContextManager;

public AssignmentTargetSearchExpressionEvaluatorFactory(ExpressionFactory expressionFactory, PrismContext prismContext,
Protector protector, ModelService modelService, SecurityContextManager securityContextManager,
Protector protector, ModelService modelService, ModelInteractionService modelInteractionService, SecurityContextManager securityContextManager,
CacheConfigurationManager cacheConfigurationManager) {
super(expressionFactory, cacheConfigurationManager);
this.prismContext = prismContext;
this.protector = protector;
this.modelService = modelService;
this.modelInteractionService = modelInteractionService;
this.securityContextManager = securityContextManager;
}

Expand All @@ -68,7 +71,7 @@ public <V extends PrismValue, D extends ItemDefinition> ExpressionEvaluator<V> c
//noinspection unchecked
return (ExpressionEvaluator<V>) new AssignmentTargetSearchExpressionEvaluator(
ELEMENT_NAME, evaluatorBean, (PrismContainerDefinition<AssignmentType>) outputDefinition, protector,
prismContext, getObjectResolver(), modelService, securityContextManager, getLocalizationService(),
prismContext, getObjectResolver(), modelService, modelInteractionService, securityContextManager, getLocalizationService(),
cacheConfigurationManager);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import javax.xml.namespace.QName;

import com.evolveum.midpoint.common.LocalizationService;
import com.evolveum.midpoint.model.api.ModelInteractionService;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.processor.ResourceObjectTypeDefinition;
import com.evolveum.midpoint.model.api.ModelService;
Expand Down Expand Up @@ -65,6 +66,7 @@ public class AssociationTargetSearchExpressionEvaluator
PrismContext prismContext,
ObjectResolver objectResolver,
ModelService modelService,
ModelInteractionService modelInteractionService,
SecurityContextManager securityContextManager,
LocalizationService localizationService,
CacheConfigurationManager cacheConfigurationManager) {
Expand All @@ -76,6 +78,7 @@ public class AssociationTargetSearchExpressionEvaluator
prismContext,
objectResolver,
modelService,
modelInteractionService,
securityContextManager,
localizationService,
cacheConfigurationManager);
Expand Down Expand Up @@ -137,13 +140,16 @@ protected boolean isAcceptable(@NotNull PrismObject<ShadowType> object) {

protected PrismContainerValue<ShadowAssociationType> createPrismValue(
String oid,
PrismObject object,
QName targetTypeQName,
List<ItemDelta<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>> additionalAttributeDeltas,
ExpressionEvaluationContext params) {
ShadowAssociationType association = new ShadowAssociationType()
.name(params.getMappingQName())
.shadowRef(oid, targetTypeQName);

association.getShadowRef().asReferenceValue().setObject(object);

//noinspection unchecked
PrismContainerValue<ShadowAssociationType> associationCVal = association.asPrismContainerValue();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.api.ModelInteractionService;
import com.evolveum.midpoint.model.api.ModelService;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
Expand Down Expand Up @@ -40,15 +41,17 @@ public class AssociationTargetSearchExpressionEvaluatorFactory extends AbstractO
private final PrismContext prismContext;
private final Protector protector;
private final ModelService modelService;
private final ModelInteractionService modelInteractionService;
private final SecurityContextManager securityContextManager;

public AssociationTargetSearchExpressionEvaluatorFactory(ExpressionFactory expressionFactory, PrismContext prismContext,
Protector protector, ModelService modelService, SecurityContextManager securityContextManager,
Protector protector, ModelService modelService, ModelInteractionService modelInteractionService, SecurityContextManager securityContextManager,
CacheConfigurationManager cacheConfigurationManager) {
super(expressionFactory, cacheConfigurationManager);
this.prismContext = prismContext;
this.protector = protector;
this.modelService = modelService;
this.modelInteractionService = modelInteractionService;
this.securityContextManager = securityContextManager;
}

Expand All @@ -70,7 +73,7 @@ public <V extends PrismValue,D extends ItemDefinition> ExpressionEvaluator<V> cr
return (ExpressionEvaluator<V>)
new AssociationTargetSearchExpressionEvaluator(ELEMENT_NAME, evaluatorBean,
(PrismContainerDefinition<ShadowAssociationType>) outputDefinition, protector, prismContext,
getObjectResolver(), modelService, securityContextManager, getLocalizationService(),
getObjectResolver(), modelService, modelInteractionService, securityContextManager, getLocalizationService(),
cacheConfigurationManager);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
import javax.xml.namespace.QName;

import com.evolveum.midpoint.common.LocalizationService;
import com.evolveum.midpoint.model.api.ModelInteractionService;
import com.evolveum.midpoint.model.api.ModelService;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismReferenceDefinition;
import com.evolveum.midpoint.prism.PrismReferenceValue;
import com.evolveum.midpoint.prism.crypto.Protector;
Expand Down Expand Up @@ -45,6 +47,7 @@ public class ReferenceSearchExpressionEvaluator
PrismContext prismContext,
ObjectResolver objectResolver,
ModelService modelService,
ModelInteractionService modelInteractionService,
SecurityContextManager securityContextManager,
LocalizationService localizationService,
CacheConfigurationManager cacheConfigurationManager) {
Expand All @@ -56,13 +59,15 @@ public class ReferenceSearchExpressionEvaluator
prismContext,
objectResolver,
modelService,
modelInteractionService,
securityContextManager,
localizationService,
cacheConfigurationManager);
}

protected PrismReferenceValue createPrismValue(
String oid,
PrismObject object,
QName targetTypeQName,
List<ItemDelta<PrismReferenceValue, PrismReferenceDefinition>> additionalAttributeValues,
ExpressionEvaluationContext params) {
Expand All @@ -71,6 +76,7 @@ protected PrismReferenceValue createPrismValue(
refVal.setOid(oid);
refVal.setTargetType(targetTypeQName);
refVal.setRelation(expressionEvaluatorBean.getRelation());
refVal.setObject(object);

return refVal;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.api.ModelInteractionService;
import com.evolveum.midpoint.model.api.ModelService;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContext;
Expand Down Expand Up @@ -39,15 +40,17 @@ public class ReferenceSearchExpressionEvaluatorFactory extends AbstractObjectRes
private final PrismContext prismContext;
private final Protector protector;
private final ModelService modelService;
private final ModelInteractionService modelInteractionService;
private final SecurityContextManager securityContextManager;

public ReferenceSearchExpressionEvaluatorFactory(ExpressionFactory expressionFactory, PrismContext prismContext,
Protector protector, ModelService modelService, SecurityContextManager securityContextManager,
Protector protector, ModelService modelService, ModelInteractionService modelInteractionService, SecurityContextManager securityContextManager,
CacheConfigurationManager cacheConfigurationManager) {
super(expressionFactory, cacheConfigurationManager);
this.prismContext = prismContext;
this.protector = protector;
this.modelService = modelService;
this.modelInteractionService = modelInteractionService;
this.securityContextManager = securityContextManager;
}

Expand All @@ -69,7 +72,7 @@ public <V extends PrismValue,D extends ItemDefinition> ExpressionEvaluator<V> cr
//noinspection unchecked
return (ExpressionEvaluator<V>)
new ReferenceSearchExpressionEvaluator(ELEMENT_NAME, evaluatorBean,
(PrismReferenceDefinition) outputDefinition, protector, prismContext, getObjectResolver(), modelService, securityContextManager, getLocalizationService(),
cacheConfigurationManager);
(PrismReferenceDefinition) outputDefinition, protector, prismContext, getObjectResolver(), modelService,
modelInteractionService, securityContextManager, getLocalizationService(), cacheConfigurationManager);
}
}

0 comments on commit a91f619

Please sign in to comment.