Search in sources :

Example 1 with UcfAsyncUpdateChange

use of com.evolveum.midpoint.provisioning.ucf.api.UcfAsyncUpdateChange in project midpoint by Evolveum.

the class TransformationalAsyncUpdateMessageListener method onMessage.

@Override
public void onMessage(AsyncUpdateMessageType message, AcknowledgementSink acknowledgementSink) {
    int messageNumber = messagesSeen.getAndIncrement();
    LOGGER.trace("Got message number {}: {}", messageNumber, message);
    SecurityContextManager securityContextManager = connectorInstance.getSecurityContextManager();
    Authentication oldAuthentication = securityContextManager.getAuthentication();
    try {
        securityContextManager.setupPreAuthenticatedSecurityContext(authentication);
        Task task = connectorInstance.getTaskManager().createTaskInstance(OP_ON_MESSAGE_PREPARATION);
        task.setChannel(CHANNEL_ASYNC_UPDATE_URI);
        if (authentication != null && authentication.getPrincipal() instanceof MidPointPrincipal) {
            task.setOwner(((MidPointPrincipal) authentication.getPrincipal()).getFocus().asPrismObject().clone());
        }
        Tracer tracer = connectorInstance.getTracer();
        OperationResult result = task.getResult();
        OperationResultBuilder resultBuilder = OperationResult.createFor(OP_ON_MESSAGE);
        try {
            ActivityTracingDefinitionType tracing = connectorInstance.getConfiguration().getProcessTracingConfiguration();
            if (tracing != null) {
                int interval = defaultIfNull(tracing.getInterval(), 1);
                boolean matches = interval > 0 && messageNumber % interval == 0;
                if (matches) {
                    task.setTracingProfile(tracing.getTracingProfile());
                    if (tracing.getTracingPoint().isEmpty()) {
                        task.addTracingRequest(TracingRootType.ASYNCHRONOUS_MESSAGE_PROCESSING);
                    } else {
                        tracing.getTracingPoint().forEach(task::addTracingRequest);
                    }
                }
            }
            if (task.getTracingRequestedFor().contains(TracingRootType.ASYNCHRONOUS_MESSAGE_PROCESSING)) {
                TracingProfileType profile = task.getTracingProfile() != null ? task.getTracingProfile() : tracer.getDefaultProfile();
                resultBuilder.tracingProfile(tracer.compileProfile(profile, task.getResult()));
            }
            // replace task result with the newly-built one
            result = resultBuilder.build();
            task.setResult(result);
            VariablesMap variables = new VariablesMap();
            variables.put(VAR_MESSAGE, message, AsyncUpdateMessageType.class);
            List<UcfChangeType> changeBeans;
            try {
                ExpressionType transformExpression = connectorInstance.getTransformExpression();
                if (transformExpression != null) {
                    changeBeans = connectorInstance.getUcfExpressionEvaluator().evaluate(transformExpression, variables, SchemaConstantsGenerated.C_UCF_CHANGE, "computing UCF change from async update", task, result);
                } else {
                    changeBeans = unwrapMessage(message);
                }
            } catch (RuntimeException | SchemaException | ObjectNotFoundException | SecurityViolationException | CommunicationException | ConfigurationException | ExpressionEvaluationException e) {
                throw new SystemException("Couldn't evaluate message transformation expression: " + e.getMessage(), e);
            }
            if (changeBeans.isEmpty()) {
                acknowledgementSink.acknowledge(true, result);
            } else {
                AcknowledgementSink aggregatedSink = createAggregatingAcknowledgeSink(acknowledgementSink, changeBeans.size());
                for (UcfChangeType changeBean : changeBeans) {
                    // For this to work reliably, we have to run in a single thread. But that's ok.
                    // If we receive messages in multiple threads, there is no message ordering.
                    int changeSequentialNumber = changesProduced.incrementAndGet();
                    // intentionally in this order - to process changes even after failure
                    // (if listener wants to fail fast, it can throw an exception)
                    UcfAsyncUpdateChange change = createChange(changeBean, result, changeSequentialNumber, aggregatedSink);
                    changeListener.onChange(change, task, result);
                }
            }
        } catch (Exception e) {
            LoggingUtils.logUnexpectedException(LOGGER, "Got exception while processing asynchronous message in {}", e, task);
            result.recordFatalError(e.getMessage(), e);
            int changeSequentialNumber = changesProduced.incrementAndGet();
            UcfAsyncUpdateChange change = new UcfAsyncUpdateChange(changeSequentialNumber, UcfErrorState.error(e), acknowledgementSink);
            changeListener.onChange(change, task, result);
        } finally {
            result.computeStatusIfUnknown();
            // (Otherwise it captures only the pre-processing activities.)
            if (result.isTraced()) {
                tracer.storeTrace(task, result, null);
            }
        }
    } finally {
        securityContextManager.setupPreAuthenticatedSecurityContext(oldAuthentication);
    }
}
Also used : Task(com.evolveum.midpoint.task.api.Task) AcknowledgementSink(com.evolveum.midpoint.schema.AcknowledgementSink) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) UcfAsyncUpdateChange(com.evolveum.midpoint.provisioning.ucf.api.UcfAsyncUpdateChange) VariablesMap(com.evolveum.midpoint.schema.expression.VariablesMap) OperationResultBuilder(com.evolveum.midpoint.schema.result.OperationResultBuilder) MidPointPrincipal(com.evolveum.midpoint.security.api.MidPointPrincipal) Tracer(com.evolveum.midpoint.task.api.Tracer) Authentication(org.springframework.security.core.Authentication) SecurityContextManager(com.evolveum.midpoint.security.api.SecurityContextManager)

Example 2 with UcfAsyncUpdateChange

use of com.evolveum.midpoint.provisioning.ucf.api.UcfAsyncUpdateChange in project midpoint by Evolveum.

the class TransformationalAsyncUpdateMessageListener method createChange.

@NotNull
private UcfAsyncUpdateChange createChange(UcfChangeType changeBean, OperationResult result, int changeSequentialNumber, AcknowledgementSink acknowledgeSink) throws SchemaException {
    QName objectClassName = changeBean.getObjectClass();
    if (objectClassName == null) {
        throw new SchemaException("Object class name is null in " + changeBean);
    }
    ResourceSchema resourceSchema = getResourceSchema(result);
    ResourceObjectDefinition objectClassDef = resourceSchema.findDefinitionForObjectClass(objectClassName);
    if (objectClassDef == null) {
        throw new SchemaException("Object class " + objectClassName + " not found in " + resourceSchema);
    }
    ObjectDelta<ShadowType> delta;
    ObjectDeltaType deltaBean = changeBean.getObjectDelta();
    if (deltaBean != null) {
        setFromDefaults((ShadowType) deltaBean.getObjectToAdd(), objectClassName);
        if (deltaBean.getObjectType() == null) {
            deltaBean.setObjectType(ShadowType.COMPLEX_TYPE);
        }
        delta = DeltaConvertor.createObjectDelta(deltaBean, getPrismContext());
    } else {
        delta = null;
    }
    setFromDefaults(changeBean.getObject(), objectClassName);
    Holder<Object> primaryIdentifierRealValueHolder = new Holder<>();
    Collection<ResourceAttribute<?>> identifiers = getIdentifiers(changeBean, objectClassDef, primaryIdentifierRealValueHolder);
    if (identifiers.isEmpty()) {
        throw new SchemaException("No identifiers in async update change bean " + changeBean);
    }
    boolean notificationOnly = changeBean.getObject() == null && delta == null;
    return new UcfAsyncUpdateChange(changeSequentialNumber, primaryIdentifierRealValueHolder.getValue(), objectClassDef.getObjectClassDefinition(), identifiers, delta, asPrismObject(changeBean.getObject()), notificationOnly, acknowledgeSink);
}
Also used : QName(javax.xml.namespace.QName) Holder(com.evolveum.midpoint.util.Holder) UcfAsyncUpdateChange(com.evolveum.midpoint.provisioning.ucf.api.UcfAsyncUpdateChange) ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) ObjectTypeUtil.asPrismObject(com.evolveum.midpoint.schema.util.ObjectTypeUtil.asPrismObject) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

UcfAsyncUpdateChange (com.evolveum.midpoint.provisioning.ucf.api.UcfAsyncUpdateChange)2 AcknowledgementSink (com.evolveum.midpoint.schema.AcknowledgementSink)1 VariablesMap (com.evolveum.midpoint.schema.expression.VariablesMap)1 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)1 OperationResultBuilder (com.evolveum.midpoint.schema.result.OperationResultBuilder)1 ObjectTypeUtil.asPrismObject (com.evolveum.midpoint.schema.util.ObjectTypeUtil.asPrismObject)1 MidPointPrincipal (com.evolveum.midpoint.security.api.MidPointPrincipal)1 SecurityContextManager (com.evolveum.midpoint.security.api.SecurityContextManager)1 Task (com.evolveum.midpoint.task.api.Task)1 Tracer (com.evolveum.midpoint.task.api.Tracer)1 Holder (com.evolveum.midpoint.util.Holder)1 ObjectDeltaType (com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType)1 QName (javax.xml.namespace.QName)1 NotNull (org.jetbrains.annotations.NotNull)1 Authentication (org.springframework.security.core.Authentication)1