/* * Copyright (c) 2010-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.model.impl.controller; import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.model.common.expression.ObjectDeltaObject; import com.evolveum.midpoint.model.common.mapping.Mapping; import com.evolveum.midpoint.model.common.mapping.MappingFactory; import com.evolveum.midpoint.model.impl.ModelObjectResolver; import com.evolveum.midpoint.model.impl.expr.ExpressionEnvironment; import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Executes mappings in diagnostic mode. * * @author mederly */ @Component public class MappingDiagEvaluator { @Autowired private MappingFactory mappingFactory; @Autowired private ModelService modelService; @Autowired private ModelObjectResolver objectResolver; @Autowired private PrismContext prismContext; @Autowired private Clock clock; public MappingEvaluationResponseType evaluateMapping(@NotNull MappingEvaluationRequestType request, @NotNull Task task, @NotNull OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { Mapping.Builder<?,?> builder = mappingFactory.createMappingBuilder(); ObjectDeltaObject<?> sourceContext = createSourceContext(request, task, result); builder = builder .mappingType(request.getMapping()) .contextDescription("mapping diagnostic execution") .sourceContext(sourceContext) .targetContext(createTargetContext(request, sourceContext)) .profiling(true) .now(clock.currentTimeXMLGregorianCalendar()); Mapping<?,?> mapping = builder.build(); ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(task, result)); try { mapping.evaluate(task, result); } finally { ModelExpressionThreadLocalHolder.popExpressionEnvironment(); } StringBuilder sb = new StringBuilder(); sb.append("Output triple: "); dumpOutputTriple(sb, mapping.getOutputTriple()); sb.append("Condition output triple: "); dumpOutputTriple(sb, mapping.getConditionOutputTriple()); sb.append("Time constraint valid: ").append(mapping.evaluateTimeConstraintValid(task, result)).append("\n"); sb.append("Next recompute time: ").append(mapping.getNextRecomputeTime()).append("\n"); sb.append("\n"); sb.append("Evaluation time: ").append(mapping.getEtime()).append(" ms\n"); MappingEvaluationResponseType response = new MappingEvaluationResponseType(); response.setResponse(sb.toString()); return response; } private void dumpOutputTriple(StringBuilder sb, PrismValueDeltaSetTriple<?> triple) { if (triple != null) { sb.append("\n").append(triple.debugDump(1)).append("\n\n"); } else { sb.append("(null)\n\n"); } } private PrismObjectDefinition<?> createTargetContext(MappingEvaluationRequestType request, ObjectDeltaObject<?> sourceContext) { if (request.getTargetContext() == null) { return sourceContext.getDefinition(); } return prismContext.getSchemaRegistry().findObjectDefinitionByType(request.getTargetContext()); } private ObjectDeltaObject<?> createSourceContext(MappingEvaluationRequestType request, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException { if (request.getSourceContext() == null) { return null; } MappingEvaluationSourceContextType ctx = request.getSourceContext(); PrismObject<?> oldObject; if (ctx.getObject() != null) { oldObject = ctx.getObject().getValue().asPrismObject(); } else if (ctx.getObjectRef() != null) { oldObject = objectResolver.resolve(ctx.getObjectRef(), ObjectType.class, null, "resolving default source", task, result).asPrismObject(); } else { oldObject = null; } ObjectDelta<?> delta; if (ctx.getDelta() != null) { delta = DeltaConvertor.createObjectDelta(ctx.getDelta(), prismContext); } else { delta = null; } return new ObjectDeltaObject(oldObject, delta, null); } }