use of com.evolveum.midpoint.schema.expression.ExpressionProfile in project midpoint by Evolveum.
the class DeltaExecution method prepareScripts.
// endregion
// region Provisioning scripts
/**
* TODO clarify the role of `object` parameter and why it is used only as a second choice (after ctx.objectAny).
*/
private OperationProvisioningScriptsType prepareScripts(PrismObject<E> object, ProvisioningOperationTypeType operation, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
if (resource == null) {
LOGGER.warn("Resource does not exist. Skipping processing scripts.");
return null;
}
OperationProvisioningScriptsType resourceScripts = resource.getScripts();
LensProjectionContext projCtx = (LensProjectionContext) elementContext;
PrismObject<ShadowType> shadow = getShadow(projCtx, object);
PrismObject<O> focus = getFocus();
ResourceShadowDiscriminator rsd = projCtx.getResourceShadowDiscriminator();
VariablesMap variables = ModelImplUtils.getDefaultVariablesMap(focus, shadow, rsd, resource.asPrismObject(), context.getSystemConfiguration(), elementContext, b.prismContext);
// Having delta in provisioning scripts may be very useful. E.g. the script can optimize execution of expensive operations.
variables.put(ExpressionConstants.VAR_DELTA, projCtx.getCurrentDelta(), ObjectDelta.class);
ExpressionProfile expressionProfile = MiscSchemaUtil.getExpressionProfile();
ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(context, projCtx, task, result));
try {
ScriptExecutor<O> scriptExecutor = new ScriptExecutor<>(context, projCtx, task, b);
return scriptExecutor.prepareScripts(resourceScripts, rsd, operation, null, variables, expressionProfile, result);
} finally {
ModelExpressionThreadLocalHolder.popExpressionEnvironment();
}
}
use of com.evolveum.midpoint.schema.expression.ExpressionProfile in project midpoint by Evolveum.
the class ScriptExecutor method executeReconciliationScripts.
void executeReconciliationScripts(BeforeAfterType order, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException, ObjectAlreadyExistsException {
if (!projCtx.isDoReconciliation()) {
return;
}
if (projCtx.getResource() == null) {
LOGGER.warn("Resource does not exist. Skipping processing reconciliation scripts.");
return;
}
OperationProvisioningScriptsType resourceScripts = projCtx.getResource().getScripts();
if (resourceScripts == null) {
return;
}
ExpressionProfile expressionProfile = MiscSchemaUtil.getExpressionProfile();
executeReconciliationScripts(resourceScripts, order, expressionProfile, result);
}
use of com.evolveum.midpoint.schema.expression.ExpressionProfile in project midpoint by Evolveum.
the class SearchEvaluator method evaluate.
public <T extends ObjectType> PipelineData evaluate(SearchExpressionType searchExpression, PipelineData input, ExecutionContext context, OperationResult globalResult) throws ScriptExecutionException, SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ExpressionEvaluationException {
Validate.notNull(searchExpression.getType());
ExpressionProfile expressionProfile = MiscSchemaUtil.getExpressionProfile();
List<PipelineItem> data = input.getData();
if (data.isEmpty()) {
// TODO fix this brutal hack (with dummyValue)
PrismContainerValue<?> dummyValue = prismContext.itemFactory().createContainerValue();
PipelineItem dummyItem = new PipelineItem(dummyValue, PipelineData.newOperationResult(), context.getInitialVariables());
data = Collections.singletonList(dummyItem);
}
final PipelineData outputData = PipelineData.createEmpty();
final MutableBoolean atLeastOne = new MutableBoolean(false);
for (PipelineItem item : data) {
// TODO variables from current item
// TODO operation result handling (global vs local)
boolean noFetch = expressionHelper.getArgumentAsBoolean(searchExpression.getParameter(), PARAM_NO_FETCH, input, context, false, "search", globalResult);
Class<T> objectClass = ObjectTypes.getObjectTypeFromTypeQName(searchExpression.getType()).getClassDefinition();
ObjectQuery unresolvedObjectQuery = null;
if (searchExpression.getQuery() != null) {
try {
unresolvedObjectQuery = context.getQueryConverter().createObjectQuery(objectClass, searchExpression.getQuery());
} catch (SchemaException e) {
throw new ScriptExecutionException("Couldn't parse object query. Reason: " + e.getMessage(), e);
}
} else if (searchExpression.getSearchFilter() != null) {
unresolvedObjectQuery = prismContext.queryFactory().createQuery();
try {
ObjectFilter filter = prismContext.getQueryConverter().parseFilter(searchExpression.getSearchFilter(), objectClass);
unresolvedObjectQuery.setFilter(filter);
} catch (SchemaException e) {
throw new ScriptExecutionException("Couldn't parse object query. Reason: " + e.getMessage(), e);
}
}
ObjectQuery objectQuery;
if (unresolvedObjectQuery != null) {
VariablesMap variables = new VariablesMap();
// noinspection unchecked
item.getVariables().forEach((name, value) -> variables.put(name, cloneIfNecessary(name, value)));
try {
objectQuery = ExpressionUtil.evaluateQueryExpressions(unresolvedObjectQuery, variables, expressionProfile, expressionFactory, prismContext, "bulk action query", context.getTask(), globalResult);
} catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException | CommunicationException | ConfigurationException | SecurityViolationException e) {
// TODO continue on any error?
throw new ScriptExecutionException("Couldn't evaluate expressions in object query: " + e.getMessage(), e);
}
} else {
objectQuery = null;
}
final String variableName = searchExpression.getVariable();
ResultHandler<T> handler = (object, parentResult) -> {
context.checkTaskStop();
atLeastOne.setValue(true);
if (searchExpression.getScriptingExpression() != null) {
if (variableName != null) {
// TODO
}
JAXBElement<?> childExpression = searchExpression.getScriptingExpression();
try {
PipelineData expressionResult = scriptingExpressionEvaluator.evaluateExpression((ScriptingExpressionType) childExpression.getValue(), PipelineData.create(object.getValue(), item.getVariables()), context, globalResult);
if (!BooleanUtils.isFalse(searchExpression.isAggregateOutput())) {
outputData.addAllFrom(expressionResult);
}
globalResult.setSummarizeSuccesses(true);
globalResult.summarize();
} catch (ScriptExecutionException | SchemaException | ConfigurationException | ObjectNotFoundException | CommunicationException | SecurityViolationException | ExpressionEvaluationException e) {
// todo think about this
if (context.isContinueOnAnyError()) {
LoggingUtils.logUnexpectedException(LOGGER, "Exception when evaluating item from search result list.", e);
} else {
throw new SystemException(e);
}
}
} else {
outputData.addValue(object.getValue(), item.getVariables());
}
return true;
};
try {
Collection<SelectorOptions<GetOperationOptions>> options = operationsHelper.createGetOptions(searchExpression.getOptions(), noFetch);
modelService.searchObjectsIterative(objectClass, objectQuery, handler, options, context.getTask(), globalResult);
} catch (SchemaException | ObjectNotFoundException | SecurityViolationException | CommunicationException | ConfigurationException | ExpressionEvaluationException e) {
// TODO continue on any error?
throw new ScriptExecutionException("Couldn't execute searchObjects operation: " + e.getMessage(), e);
}
}
if (atLeastOne.isFalse()) {
// temporary hack, this will be configurable
context.println("Warning: no matching object found");
}
return outputData;
}
use of com.evolveum.midpoint.schema.expression.ExpressionProfile in project midpoint by Evolveum.
the class ExecuteScriptExecutor method getParameters.
private Parameters getParameters(ActionExpressionType action, PipelineData input, ExecutionContext context, OperationResult globalResult) throws CommunicationException, ObjectNotFoundException, SchemaException, ScriptExecutionException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException {
ScriptExpressionEvaluatorType script = expressionHelper.getActionArgument(ScriptExpressionEvaluatorType.class, action, ExecuteScriptActionExpressionType.F_SCRIPT, PARAM_SCRIPT, input, context, null, PARAM_SCRIPT, globalResult);
ItemDefinition<?> outputDefinition;
String outputItemUri = expressionHelper.getSingleArgumentValue(action.getParameter(), PARAM_OUTPUT_ITEM, false, false, NAME, input, context, String.class, globalResult);
if (StringUtils.isNotBlank(outputItemUri)) {
outputDefinition = getItemDefinition(outputItemUri);
} else if (action instanceof ExecuteScriptActionExpressionType) {
ExecuteScriptActionExpressionType execute = (ExecuteScriptActionExpressionType) action;
if (execute.getOutputItemName() != null) {
outputDefinition = getItemDefinitionFromItemName(execute.getOutputItemName());
} else if (execute.getOutputTypeName() != null) {
outputDefinition = getItemDefinitionFromTypeName(execute.getOutputTypeName());
} else {
outputDefinition = null;
}
} else {
outputDefinition = null;
}
boolean forWholeInput = expressionHelper.getActionArgument(Boolean.class, action, ExecuteScriptActionExpressionType.F_FOR_WHOLE_INPUT, PARAM_FOR_WHOLE_INPUT, input, context, false, PARAM_FOR_WHOLE_INPUT, globalResult);
boolean quiet = expressionHelper.getActionArgument(Boolean.class, action, ExecuteScriptActionExpressionType.F_QUIET, PARAM_QUIET, input, context, false, PARAM_QUIET, globalResult);
if (script == null) {
throw new IllegalArgumentException("No script provided");
}
// TODO
ExpressionProfile expressionProfile = null;
ScriptExpression scriptExpression;
try {
scriptExpression = scriptExpressionFactory.createScriptExpression(script, outputDefinition, expressionProfile, expressionFactory, "script", globalResult);
} catch (ExpressionSyntaxException | SecurityViolationException e) {
throw new ScriptExecutionException("Couldn't parse script expression: " + e.getMessage(), e);
}
return new Parameters(scriptExpression, outputDefinition, forWholeInput, quiet);
}
use of com.evolveum.midpoint.schema.expression.ExpressionProfile in project midpoint by Evolveum.
the class CustomFunctions method execute.
/**
* This method is invoked by the scripts. It is supposed to be only public method exposed
* by this class.
*/
public <V extends PrismValue, D extends ItemDefinition> Object execute(String functionName, Map<String, Object> params) throws ExpressionEvaluationException {
Validate.notNull(functionName, "Function name must be specified");
ScriptExpressionEvaluationContext ctx = ScriptExpressionEvaluationContext.getThreadLocal();
Task task;
OperationResult result;
if (ctx != null) {
if (ctx.getTask() != null) {
task = ctx.getTask();
} else {
// We shouldn't use task of unknown provenience.
throw new IllegalStateException("No task in ScriptExpressionEvaluationContext for the current thread found");
}
if (ctx.getResult() != null) {
result = ctx.getResult();
} else {
// This situation should never occur anyway.
throw new IllegalStateException("No operation result in ScriptExpressionEvaluationContext for the current thread found");
}
} else {
// This situation should never occur anyway.
throw new IllegalStateException("No ScriptExpressionEvaluationContext for current thread found");
}
List<ExpressionType> functions = library.getFunction().stream().filter(expression -> functionName.equals(expression.getName())).collect(Collectors.toList());
LOGGER.trace("functions {}", functions);
ExpressionType expressionType = MiscUtil.extractSingletonRequired(functions, () -> new ExpressionEvaluationException(functions.size() + " functions named '" + functionName + "' present"), () -> new ExpressionEvaluationException("No function named '" + functionName + "' present"));
LOGGER.trace("function to execute {}", expressionType);
try {
VariablesMap variables = new VariablesMap();
if (MapUtils.isNotEmpty(params)) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
variables.put(entry.getKey(), convertInput(entry, expressionType));
}
}
QName returnType = defaultIfNull(expressionType.getReturnType(), DOMUtil.XSD_STRING);
D outputDefinition = prepareOutputDefinition(returnType, expressionType.getReturnMultiplicity());
String shortDesc = "custom function execute";
Expression<V, D> expression = expressionFactory.makeExpression(expressionType, outputDefinition, expressionProfile, shortDesc, task, result);
ExpressionEvaluationContext context = new ExpressionEvaluationContext(null, variables, shortDesc, task);
PrismValueDeltaSetTriple<V> outputTriple = expression.evaluate(context, result);
LOGGER.trace("Result of the expression evaluation: {}", outputTriple);
if (outputTriple == null) {
return null;
}
Collection<V> nonNegativeValues = outputTriple.getNonNegativeValues();
if (nonNegativeValues.isEmpty()) {
return null;
}
if (outputDefinition.isMultiValue()) {
return PrismValueCollectionsUtil.getRealValuesOfCollection(nonNegativeValues);
}
if (nonNegativeValues.size() > 1) {
throw new ExpressionEvaluationException("Expression returned more than one value (" + nonNegativeValues.size() + ") in " + shortDesc);
}
return nonNegativeValues.iterator().next().getRealValue();
} catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException | ConfigurationException | SecurityViolationException e) {
throw new ExpressionEvaluationException(e.getMessage(), e);
}
}
Aggregations