Search in sources :

Example 1 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class ReconciliationTaskHandler method runInternal.

public TaskRunResult runInternal(Task coordinatorTask) {
    ReconciliationTaskResult reconResult = new ReconciliationTaskResult();
    boolean finishOperationsOnly = BooleanUtils.isTrue(coordinatorTask.getExtensionPropertyRealValue(SchemaConstants.MODEL_EXTENSION_FINISH_OPERATIONS_ONLY));
    OperationResult opResult = new OperationResult(OperationConstants.RECONCILIATION);
    opResult.setStatus(OperationResultStatus.IN_PROGRESS);
    TaskRunResult runResult = new TaskRunResult();
    runResult.setOperationResult(opResult);
    String resourceOid = coordinatorTask.getObjectOid();
    opResult.addContext("resourceOid", resourceOid);
    if (coordinatorTask.getChannel() == null) {
        coordinatorTask.setChannel(SchemaConstants.CHANGE_CHANNEL_RECON_URI);
    }
    if (resourceOid == null) {
        throw new IllegalArgumentException("Resource OID is missing in task extension");
    }
    recordProgress(coordinatorTask, 0, opResult);
    // todo consider setting expectedTotal to null here
    PrismObject<ResourceType> resource;
    ObjectClassComplexTypeDefinition objectclassDef;
    try {
        resource = provisioningService.getObject(ResourceType.class, resourceOid, null, coordinatorTask, opResult);
        RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource, LayerType.MODEL, prismContext);
        objectclassDef = Utils.determineObjectClass(refinedSchema, coordinatorTask);
    } catch (ObjectNotFoundException ex) {
        // This is bad. The resource does not exist. Permanent problem.
        processErrorPartial(runResult, "Resource does not exist, OID: " + resourceOid, ex, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
        return runResult;
    } catch (CommunicationException ex) {
        // Error, but not critical. Just try later.
        processErrorPartial(runResult, "Communication error", ex, TaskRunResultStatus.TEMPORARY_ERROR, null, coordinatorTask, opResult);
        return runResult;
    } catch (SchemaException ex) {
        // Not sure about this. But most likely it is a misconfigured resource or connector
        // It may be worth to retry. Error is fatal, but may not be permanent.
        processErrorPartial(runResult, "Error dealing with schema", ex, TaskRunResultStatus.TEMPORARY_ERROR, null, coordinatorTask, opResult);
        return runResult;
    } catch (RuntimeException ex) {
        // Can be anything ... but we can't recover from that.
        // It is most likely a programming error. Does not make much sense
        // to retry.
        processErrorPartial(runResult, "Internal Error", ex, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
        return runResult;
    } catch (ConfigurationException ex) {
        // Not sure about this. But most likely it is a misconfigured resource or connector
        // It may be worth to retry. Error is fatal, but may not be permanent.
        processErrorPartial(runResult, "Configuration error", ex, TaskRunResultStatus.TEMPORARY_ERROR, null, coordinatorTask, opResult);
        return runResult;
    } catch (SecurityViolationException ex) {
        processErrorPartial(runResult, "Security violation", ex, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
        return runResult;
    } catch (ExpressionEvaluationException ex) {
        processErrorPartial(runResult, "Expression error", ex, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
        return runResult;
    }
    if (objectclassDef == null) {
        processErrorPartial(runResult, "Reconciliation without an object class specification is not supported", null, TaskRunResultStatus.PERMANENT_ERROR, null, coordinatorTask, opResult);
        return runResult;
    }
    reconResult.setResource(resource);
    reconResult.setObjectclassDefinition(objectclassDef);
    LOGGER.info("Start executing reconciliation of resource {}, reconciling object class {}, finish operations only: {}", resource, objectclassDef, finishOperationsOnly);
    long reconStartTimestamp = clock.currentTimeMillis();
    AuditEventRecord requestRecord = new AuditEventRecord(AuditEventType.RECONCILIATION, AuditEventStage.REQUEST);
    requestRecord.setTarget(resource);
    auditService.audit(requestRecord, coordinatorTask);
    try {
        if (!scanForUnfinishedOperations(coordinatorTask, resourceOid, reconResult, opResult)) {
            // appends also "last N failures" (TODO refactor)
            processInterruption(runResult, resource, coordinatorTask, opResult);
            return runResult;
        }
    } catch (ObjectNotFoundException ex) {
        // This is bad. The resource does not exist. Permanent problem.
        processErrorPartial(runResult, "Resource does not exist, OID: " + resourceOid, ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
    } catch (ObjectAlreadyExistsException ex) {
        processErrorPartial(runResult, "Object already exist", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
    } catch (CommunicationException ex) {
        // Error, but not critical. Just try later.
        // appends also "last N failures" (TODO refactor)
        processErrorFinal(runResult, "Communication error", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (SchemaException ex) {
        // Not sure about this. But most likely it is a misconfigured resource or connector
        // It may be worth to retry. Error is fatal, but may not be permanent.
        processErrorPartial(runResult, "Error dealing with schema", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
    } catch (RuntimeException ex) {
        // Can be anything ... but we can't recover from that.
        // It is most likely a programming error. Does not make much sense
        // to retry.
        processErrorFinal(runResult, "Internal Error", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (ConfigurationException ex) {
        // Not sure about this. But most likely it is a misconfigured resource or connector
        // It may be worth to retry. Error is fatal, but may not be permanent.
        processErrorFinal(runResult, "Configuration error", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (SecurityViolationException ex) {
        processErrorPartial(runResult, "Security violation", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
    }
    long beforeResourceReconTimestamp = clock.currentTimeMillis();
    long afterResourceReconTimestamp;
    long afterShadowReconTimestamp;
    try {
        if (!finishOperationsOnly && !performResourceReconciliation(resource, objectclassDef, reconResult, coordinatorTask, opResult)) {
            processInterruption(runResult, resource, coordinatorTask, opResult);
            return runResult;
        }
        afterResourceReconTimestamp = clock.currentTimeMillis();
        if (!finishOperationsOnly && !performShadowReconciliation(resource, objectclassDef, reconStartTimestamp, afterResourceReconTimestamp, reconResult, coordinatorTask, opResult)) {
            processInterruption(runResult, resource, coordinatorTask, opResult);
            return runResult;
        }
        afterShadowReconTimestamp = clock.currentTimeMillis();
    } catch (ObjectNotFoundException ex) {
        // This is bad. The resource does not exist. Permanent problem.
        processErrorFinal(runResult, "Resource does not exist, OID: " + resourceOid, ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (CommunicationException ex) {
        // Error, but not critical. Just try later.
        processErrorFinal(runResult, "Communication error", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (SchemaException ex) {
        // Not sure about this. But most likely it is a misconfigured resource or connector
        // It may be worth to retry. Error is fatal, but may not be permanent.
        processErrorFinal(runResult, "Error dealing with schema", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (RuntimeException ex) {
        // Can be anything ... but we can't recover from that.
        // It is most likely a programming error. Does not make much sense
        // to retry.
        processErrorFinal(runResult, "Internal Error", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (ConfigurationException ex) {
        // Not sure about this. But most likely it is a misconfigured resource or connector
        // It may be worth to retry. Error is fatal, but may not be permanent.
        processErrorFinal(runResult, "Configuration error", ex, TaskRunResultStatus.TEMPORARY_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (SecurityViolationException ex) {
        processErrorFinal(runResult, "Security violation", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    } catch (ExpressionEvaluationException ex) {
        processErrorFinal(runResult, "Expression error", ex, TaskRunResultStatus.PERMANENT_ERROR, resource, coordinatorTask, opResult);
        return runResult;
    }
    opResult.computeStatus();
    // This "run" is finished. But the task goes on ...
    runResult.setRunResultStatus(TaskRunResultStatus.FINISHED);
    runResult.setProgress(coordinatorTask.getProgress());
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Reconciliation.run stopping, result: {}", opResult.getStatus());
    //			LOGGER.trace("Reconciliation.run stopping, result: {}", opResult.dump());
    }
    AuditEventRecord executionRecord = new AuditEventRecord(AuditEventType.RECONCILIATION, AuditEventStage.EXECUTION);
    executionRecord.setTarget(resource);
    executionRecord.setOutcome(OperationResultStatus.SUCCESS);
    auditService.audit(executionRecord, coordinatorTask);
    long reconEndTimestamp = clock.currentTimeMillis();
    long etime = reconEndTimestamp - reconStartTimestamp;
    long unOpsTime = beforeResourceReconTimestamp - reconStartTimestamp;
    long resourceReconTime = afterResourceReconTimestamp - beforeResourceReconTimestamp;
    long shadowReconTime = afterShadowReconTimestamp - afterResourceReconTimestamp;
    LOGGER.info("Done executing reconciliation of resource {}, object class {}, Etime: {} ms (un-ops: {}, resource: {}, shadow: {})", new Object[] { resource, objectclassDef, etime, unOpsTime, resourceReconTime, shadowReconTime });
    reconResult.setRunResult(runResult);
    if (reconciliationTaskResultListener != null) {
        reconciliationTaskResultListener.process(reconResult);
    }
    TaskHandlerUtil.appendLastFailuresInformation(OperationConstants.RECONCILIATION, coordinatorTask, opResult);
    return runResult;
}
Also used : OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ResourceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType) ObjectClassComplexTypeDefinition(com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition) RefinedResourceSchema(com.evolveum.midpoint.common.refinery.RefinedResourceSchema) AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Example 2 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class ReconciliationTaskHandler method processErrorFinal.

private void processErrorFinal(TaskRunResult runResult, String errorDesc, Exception ex, TaskRunResultStatus runResultStatus, PrismObject<ResourceType> resource, Task task, OperationResult opResult) {
    String message = errorDesc + ": " + ex.getMessage();
    LOGGER.error("Reconciliation: {}", new Object[] { message, ex });
    opResult.recordFatalError(message, ex);
    // TODO implement more seriously
    TaskHandlerUtil.appendLastFailuresInformation(OperationConstants.RECONCILIATION, task, opResult);
    runResult.setRunResultStatus(runResultStatus);
    runResult.setProgress(task.getProgress());
    AuditEventRecord executionRecord = new AuditEventRecord(AuditEventType.RECONCILIATION, AuditEventStage.EXECUTION);
    executionRecord.setTarget(resource);
    executionRecord.setOutcome(OperationResultStatus.FATAL_ERROR);
    executionRecord.setMessage(ex.getMessage());
    auditService.audit(executionRecord, task);
}
Also used : AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Example 3 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class Clockwork method auditEvent.

private <F extends ObjectType> void auditEvent(LensContext<F> context, AuditEventStage stage, XMLGregorianCalendar timestamp, boolean alwaysAudit, Task task, OperationResult result) throws SchemaException {
    PrismObject<? extends ObjectType> primaryObject;
    ObjectDelta<? extends ObjectType> primaryDelta;
    if (context.getFocusContext() != null) {
        primaryObject = context.getFocusContext().getObjectOld();
        if (primaryObject == null) {
            primaryObject = context.getFocusContext().getObjectNew();
        }
        primaryDelta = context.getFocusContext().getDelta();
    } else {
        Collection<LensProjectionContext> projectionContexts = context.getProjectionContexts();
        if (projectionContexts == null || projectionContexts.isEmpty()) {
            throw new IllegalStateException("No focus and no projections in " + context);
        }
        if (projectionContexts.size() > 1) {
            throw new IllegalStateException("No focus and more than one projection in " + context);
        }
        LensProjectionContext projection = projectionContexts.iterator().next();
        primaryObject = projection.getObjectOld();
        if (primaryObject == null) {
            primaryObject = projection.getObjectNew();
        }
        primaryDelta = projection.getDelta();
    }
    AuditEventType eventType;
    if (primaryDelta == null) {
        eventType = AuditEventType.SYNCHRONIZATION;
    } else if (primaryDelta.isAdd()) {
        eventType = AuditEventType.ADD_OBJECT;
    } else if (primaryDelta.isModify()) {
        eventType = AuditEventType.MODIFY_OBJECT;
    } else if (primaryDelta.isDelete()) {
        eventType = AuditEventType.DELETE_OBJECT;
    } else {
        throw new IllegalStateException("Unknown state of delta " + primaryDelta);
    }
    AuditEventRecord auditRecord = new AuditEventRecord(eventType, stage);
    if (primaryObject != null) {
        auditRecord.setTarget(primaryObject.clone());
    //		} else {
    //			throw new IllegalStateException("No primary object in:\n"+context.dump());
    }
    auditRecord.setChannel(context.getChannel());
    if (stage == AuditEventStage.REQUEST) {
        Collection<ObjectDeltaOperation<? extends ObjectType>> clonedDeltas = ObjectDeltaOperation.cloneDeltaCollection(context.getPrimaryChanges());
        checkNamesArePresent(clonedDeltas, primaryObject);
        auditRecord.addDeltas(clonedDeltas);
        if (auditRecord.getTarget() == null) {
            auditRecord.setTarget(Utils.determineAuditTargetDeltaOps(clonedDeltas));
        }
    } else if (stage == AuditEventStage.EXECUTION) {
        auditRecord.setOutcome(result.getComputeStatus());
        Collection<ObjectDeltaOperation<? extends ObjectType>> unauditedExecutedDeltas = context.getUnauditedExecutedDeltas();
        if (!alwaysAudit && (unauditedExecutedDeltas == null || unauditedExecutedDeltas.isEmpty())) {
            // No deltas, nothing to audit in this wave
            return;
        }
        Collection<ObjectDeltaOperation<? extends ObjectType>> clonedDeltas = ObjectDeltaOperation.cloneCollection(unauditedExecutedDeltas);
        checkNamesArePresent(clonedDeltas, primaryObject);
        auditRecord.addDeltas(clonedDeltas);
    } else {
        throw new IllegalStateException("Unknown audit stage " + stage);
    }
    if (timestamp != null) {
        auditRecord.setTimestamp(XmlTypeConverter.toMillis(timestamp));
    }
    addRecordMessage(auditRecord, result);
    auditService.audit(auditRecord, task);
    if (stage == AuditEventStage.EXECUTION) {
        // We need to clean up so these deltas will not be audited again in next wave
        context.markExecutedDeltasAudited();
        context.setExecutionAudited(true);
    } else if (stage == AuditEventStage.REQUEST) {
        context.setRequestAudited(true);
    } else {
        throw new IllegalStateException("Unknown audit stage " + stage);
    }
}
Also used : AuditEventType(com.evolveum.midpoint.audit.api.AuditEventType) ObjectDeltaOperation(com.evolveum.midpoint.schema.ObjectDeltaOperation) AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Example 4 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class SecurityHelper method auditLogin.

private void auditLogin(@Nullable String username, @Nullable UserType user, @NotNull ConnectionEnvironment connEnv, @NotNull OperationResultStatus status, @Nullable String message) {
    Task task = taskManager.createTaskInstance();
    task.setChannel(connEnv.getChannel());
    LOGGER.debug("Login {} username={}, channel={}: {}", status == OperationResultStatus.SUCCESS ? "success" : "failure", username, connEnv.getChannel(), message);
    AuditEventRecord record = new AuditEventRecord(AuditEventType.CREATE_SESSION, AuditEventStage.REQUEST);
    record.setParameter(username);
    if (user != null) {
        record.setInitiator(user.asPrismObject());
    }
    record.setTimestamp(System.currentTimeMillis());
    record.setOutcome(status);
    record.setMessage(message);
    storeConnectionEnvironment(record, connEnv);
    auditService.audit(record, task);
}
Also used : Task(com.evolveum.midpoint.task.api.Task) AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Example 5 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class AuditController method rollBackTime.

private <O extends ObjectType> PrismObject<O> rollBackTime(PrismObject<O> object, List<AuditEventRecord> changeTrail) throws SchemaException {
    for (AuditEventRecord event : changeTrail) {
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Applying event {} ({})", event.getEventIdentifier(), XmlTypeConverter.createXMLGregorianCalendar(event.getTimestamp()));
        }
        Collection<ObjectDeltaOperation<? extends ObjectType>> deltaOperations = event.getDeltas();
        if (deltaOperations != null) {
            for (ObjectDeltaOperation<? extends ObjectType> deltaOperation : deltaOperations) {
                ObjectDelta<O> objectDelta = (ObjectDelta<O>) deltaOperation.getObjectDelta();
                if (!isApplicable(deltaOperation, object, event)) {
                    continue;
                }
                if (objectDelta.isDelete()) {
                    throw new SchemaException("Delete delta found in the audit trail. Object history cannot be reconstructed.");
                }
                if (objectDelta.isAdd()) {
                    throw new SchemaException("Add delta found in the audit trail. Object history cannot be reconstructed.");
                }
                ObjectDelta<O> reverseDelta = objectDelta.createReverseDelta();
                if (LOGGER.isTraceEnabled()) {
                    LOGGER.trace("Applying delta (reverse):\n{}", reverseDelta.debugDump(1));
                }
                reverseDelta.applyTo(object);
            }
        }
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Object after application of event {} ({}):\n{}", event.getEventIdentifier(), XmlTypeConverter.createXMLGregorianCalendar(event.getTimestamp()), object.debugDump(1));
        }
    }
    return object;
}
Also used : ObjectType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) ObjectDeltaOperation(com.evolveum.midpoint.schema.ObjectDeltaOperation) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Aggregations

AuditEventRecord (com.evolveum.midpoint.audit.api.AuditEventRecord)83 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)28 Task (com.evolveum.midpoint.task.api.Task)18 Test (org.testng.annotations.Test)18 ObjectDeltaOperation (com.evolveum.midpoint.schema.ObjectDeltaOperation)11 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)9 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)8 PrismObject (com.evolveum.midpoint.prism.PrismObject)7 ObjectType (com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType)6 ArrayList (java.util.ArrayList)6 MidPointPrincipal (com.evolveum.midpoint.security.api.MidPointPrincipal)5 NullTaskImpl (com.evolveum.midpoint.task.api.test.NullTaskImpl)5 PolyString (com.evolveum.midpoint.prism.polystring.PolyString)4 MAuditEventRecord (com.evolveum.midpoint.repo.sql.audit.beans.MAuditEventRecord)4 AuditResultHandler (com.evolveum.midpoint.audit.api.AuditResultHandler)3 MidpointAuthentication (com.evolveum.midpoint.authentication.api.config.MidpointAuthentication)3 Message (com.evolveum.midpoint.notifications.api.transports.Message)3 QAuditEventRecord (com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditEventRecord)3 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)3 AuditEventRecordType (com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType)3