Search in sources :

Example 1 with AsynchronousOperationResult

use of com.evolveum.midpoint.schema.result.AsynchronousOperationResult in project midpoint by Evolveum.

the class ResourceObjectConverter method deleteResourceObject.

public AsynchronousOperationResult deleteResourceObject(ProvisioningContext ctx, PrismObject<ShadowType> shadow, OperationProvisioningScriptsType scripts, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
    OperationResult result = parentResult.createSubresult(OPERATION_DELETE_RESOURCE_OBJECT);
    LOGGER.trace("Deleting resource object {}", shadow);
    Collection<? extends ResourceAttribute<?>> identifiers = ShadowUtil.getAllIdentifiers(shadow);
    if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), shadow, matchingRuleRegistry)) {
        LOGGER.error("Attempt to delete protected resource object " + ctx.getObjectClassDefinition() + ": " + identifiers + "; ignoring the request");
        SecurityViolationException e = new SecurityViolationException("Cannot delete protected resource object " + ctx.getObjectClassDefinition() + ": " + identifiers);
        result.recordFatalError(e);
        throw e;
    }
    //check idetifier if it is not null
    if (identifiers.isEmpty() && shadow.asObjectable().getFailedOperationType() != null) {
        throw new GenericConnectorException("Unable to delete object from the resource. Probably it has not been created yet because of previous unavailability of the resource.");
    }
    // Execute entitlement modification on other objects (if needed)
    executeEntitlementChangesDelete(ctx, shadow, scripts, result);
    Collection<Operation> additionalOperations = new ArrayList<Operation>();
    addExecuteScriptOperation(additionalOperations, ProvisioningOperationTypeType.DELETE, scripts, ctx.getResource(), result);
    ConnectorInstance connector = ctx.getConnector(DeleteCapabilityType.class, result);
    try {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("PROVISIONING DELETE operation on {}\n DELETE object, object class {}, identified by:\n{}\n additional operations:\n{}", ctx.getResource(), shadow.asObjectable().getObjectClass(), SchemaDebugUtil.debugDump(identifiers), SchemaDebugUtil.debugDump(additionalOperations));
        }
        if (!ResourceTypeUtil.isDeleteCapabilityEnabled(ctx.getResource())) {
            UnsupportedOperationException e = new UnsupportedOperationException("Resource does not support 'delete' operation");
            result.recordFatalError(e);
            throw e;
        }
        connector.deleteObject(ctx.getObjectClassDefinition(), additionalOperations, identifiers, ctx, result);
        computeResultStatus(result);
        LOGGER.debug("PROVISIONING DELETE: {}", result.getStatus());
    } catch (ObjectNotFoundException ex) {
        result.recordFatalError("Can't delete object " + shadow + ". Reason: " + ex.getMessage(), ex);
        throw new ObjectNotFoundException("An error occured while deleting resource object " + shadow + "whith identifiers " + identifiers + ": " + ex.getMessage(), ex);
    } catch (CommunicationException ex) {
        result.recordFatalError("Error communicating with the connector " + connector + ": " + ex.getMessage(), ex);
        throw new CommunicationException("Error communicating with the connector " + connector + ": " + ex.getMessage(), ex);
    } catch (ConfigurationException ex) {
        result.recordFatalError("Configuration error in connector " + connector + ": " + ex.getMessage(), ex);
        throw new ConfigurationException("Configuration error in connector " + connector + ": " + ex.getMessage(), ex);
    } catch (ExpressionEvaluationException ex) {
        result.recordFatalError("Expression error while setting up the resource: " + ex.getMessage(), ex);
        throw new ExpressionEvaluationException("Expression error while setting up the resource: " + ex.getMessage(), ex);
    } catch (GenericFrameworkException ex) {
        result.recordFatalError("Generic error in connector: " + ex.getMessage(), ex);
        throw new GenericConnectorException("Generic error in connector: " + ex.getMessage(), ex);
    }
    LOGGER.trace("Deleted resource object {}", shadow);
    return AsynchronousOperationResult.wrap(result);
}
Also used : OperationResult(com.evolveum.midpoint.schema.result.OperationResult) AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult) GenericConnectorException(com.evolveum.midpoint.provisioning.api.GenericConnectorException)

Example 2 with AsynchronousOperationResult

use of com.evolveum.midpoint.schema.result.AsynchronousOperationResult in project midpoint by Evolveum.

the class AbstractManualConnectorInstance method deleteObject.

@Override
public AsynchronousOperationResult deleteObject(ObjectClassComplexTypeDefinition objectClass, Collection<Operation> additionalOperations, Collection<? extends ResourceAttribute<?>> identifiers, StateReporter reporter, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, ConfigurationException {
    OperationResult result = parentResult.createSubresult(OPERATION_DELETE);
    String ticketIdentifier = null;
    try {
        ticketIdentifier = createTicketDelete(objectClass, identifiers, result);
    } catch (ObjectNotFoundException | CommunicationException | GenericFrameworkException | SchemaException | ConfigurationException | RuntimeException | Error e) {
        result.recordFatalError(e);
        throw e;
    }
    result.recordInProgress();
    result.setAsynchronousOperationReference(ticketIdentifier);
    return AsynchronousOperationResult.wrap(result);
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) GenericFrameworkException(com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult)

Example 3 with AsynchronousOperationResult

use of com.evolveum.midpoint.schema.result.AsynchronousOperationResult in project midpoint by Evolveum.

the class ConnectorInstanceConnIdImpl method deleteObject.

@Override
public AsynchronousOperationResult deleteObject(ResourceObjectDefinition objectDefinition, PrismObject<ShadowType> shadow, Collection<? extends ResourceAttribute<?>> identifiers, UcfExecutionContext ctx, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException {
    Validate.notNull(objectDefinition, "No objectclass");
    OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".deleteObject");
    result.addArbitraryObjectCollectionAsParam("identifiers", identifiers);
    ObjectClass objClass = objectClassToConnId(objectDefinition);
    Uid uid;
    try {
        uid = getUid(objectDefinition, identifiers);
    } catch (SchemaException e) {
        result.recordFatalError(e);
        throw e;
    }
    OperationResult icfResult = result.createSubresult(ConnectorFacade.class.getName() + ".delete");
    icfResult.addArbitraryObjectAsParam("uid", uid);
    icfResult.addArbitraryObjectAsParam("objectClass", objClass);
    icfResult.addContext("connector", connIdConnectorFacade.getClass());
    InternalMonitor.recordConnectorOperation("delete");
    InternalMonitor.recordConnectorModification("delete");
    ConnIdOperation operation = recordIcfOperationStart(ctx, ProvisioningOperation.ICF_DELETE, objectDefinition, uid);
    LOGGER.trace("Invoking ConnId delete operation: {}", operation);
    try {
        connIdConnectorFacade.delete(objClass, uid, new OperationOptionsBuilder().build());
        recordIcfOperationEnd(ctx, operation, null);
        icfResult.recordSuccess();
    } catch (Throwable ex) {
        recordIcfOperationEnd(ctx, operation, ex);
        String desc = this.getHumanReadableName() + " while deleting object identified by ConnId UID '" + uid.getUidValue() + "'";
        Throwable midpointEx = processConnIdException(ex, desc, icfResult);
        result.computeStatus("Removing attribute values failed");
        // exception
        if (midpointEx instanceof ObjectNotFoundException) {
            throw (ObjectNotFoundException) midpointEx;
        } else if (midpointEx instanceof CommunicationException) {
            throw (CommunicationException) midpointEx;
        } else if (midpointEx instanceof GenericFrameworkException) {
            throw (GenericFrameworkException) midpointEx;
        } else if (midpointEx instanceof SchemaException) {
            // Schema exception during delete? It must be a missing UID
            throw new IllegalArgumentException(midpointEx.getMessage(), midpointEx);
        } else if (midpointEx instanceof RuntimeException) {
            throw (RuntimeException) midpointEx;
        } else if (midpointEx instanceof Error) {
            throw (Error) midpointEx;
        } else {
            throw new SystemException("Got unexpected exception: " + ex.getClass().getName() + ": " + ex.getMessage(), ex);
        }
    }
    result.computeStatus();
    return AsynchronousOperationResult.wrap(result);
}
Also used : OperationResult(com.evolveum.midpoint.schema.result.OperationResult) AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult) GuardedString(org.identityconnectors.common.security.GuardedString) ConnIdOperation(com.evolveum.midpoint.schema.reporting.ConnIdOperation)

Example 4 with AsynchronousOperationResult

use of com.evolveum.midpoint.schema.result.AsynchronousOperationResult in project midpoint by Evolveum.

the class RefreshHelper method refreshShadowRetryOperations.

private RefreshShadowOperation refreshShadowRetryOperations(ProvisioningContext ctx, PrismObject<ShadowType> repoShadow, List<PendingOperationType> sortedOperations, ProvisioningOperationOptions options, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException, EncryptionException {
    ShadowType shadowType = repoShadow.asObjectable();
    OperationResult retryResult = new OperationResult(OP_REFRESH_RETRY);
    if (ShadowUtil.isDead(shadowType)) {
        RefreshShadowOperation rso = new RefreshShadowOperation();
        retryResult.recordSuccess();
        rso.setRefreshedShadow(repoShadow);
        rso.setRefreshResult(retryResult);
        return rso;
    }
    Duration retryPeriod = ProvisioningUtil.getRetryPeriod(ctx);
    Collection<ObjectDeltaOperation<ShadowType>> executedDeltas = new ArrayList<>();
    for (PendingOperationType pendingOperation : sortedOperations) {
        if (!needsRetry(pendingOperation)) {
            continue;
        }
        // We really want to get "now" here. Retrying operation may take some time. We want good timestamps that do not lie.
        XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar();
        if (!isAfterRetryPeriod(pendingOperation, retryPeriod, now)) {
            if (PendingOperationTypeType.RETRY != pendingOperation.getType()) {
                continue;
            }
            if (!ProvisioningOperationOptions.isForceRetry(options)) {
                continue;
            }
        }
        LOGGER.trace("Going to retry operation {} on {}", pendingOperation, repoShadow);
        // Record attempt number and timestamp before the operation
        // TODO: later use this as an optimistic lock to make sure that two threads won't retry the operation at the same time
        // TODO: move to a better place
        ObjectDelta<ShadowType> shadowDelta = repoShadow.createModifyDelta();
        ItemPath containerPath = pendingOperation.asPrismContainerValue().getPath();
        int attemptNumber = pendingOperation.getAttemptNumber() + 1;
        PropertyDelta<Integer> attemptNumberDelta = shadowDelta.createPropertyModification(containerPath.append(PendingOperationType.F_ATTEMPT_NUMBER));
        attemptNumberDelta.setRealValuesToReplace(attemptNumber);
        shadowDelta.addModification(attemptNumberDelta);
        PropertyDelta<XMLGregorianCalendar> lastAttemptTimestampDelta = shadowDelta.createPropertyModification(containerPath.append(PendingOperationType.F_LAST_ATTEMPT_TIMESTAMP));
        lastAttemptTimestampDelta.setRealValuesToReplace(now);
        shadowDelta.addModification(lastAttemptTimestampDelta);
        PropertyDelta<OperationResultStatusType> resultStatusDelta = shadowDelta.createPropertyModification(containerPath.append(PendingOperationType.F_RESULT_STATUS));
        resultStatusDelta.setRealValuesToReplace(OperationResultStatusType.IN_PROGRESS);
        shadowDelta.addModification(resultStatusDelta);
        shadowManager.modifyShadowAttributes(ctx, repoShadow, shadowDelta.getModifications(), parentResult);
        shadowDelta.applyTo(repoShadow);
        ObjectDeltaType pendingDeltaType = pendingOperation.getDelta();
        ObjectDelta<ShadowType> pendingDelta = DeltaConvertor.createObjectDelta(pendingDeltaType, prismContext);
        ProvisioningOperationState<? extends AsynchronousOperationResult> opState = ProvisioningOperationState.fromPendingOperation(repoShadow, pendingOperation);
        LOGGER.debug("Retrying operation {} on {}, attempt #{}", pendingDelta, repoShadow, attemptNumber);
        ObjectDeltaOperation<ShadowType> objectDeltaOperation = new ObjectDeltaOperation<>(pendingDelta);
        OperationResult result = parentResult.createSubresult(OP_OPERATION_RETRY);
        try {
            retryOperation(ctx, pendingDelta, opState, task, result);
            repoShadow = opState.getRepoShadow();
            result.computeStatus();
            if (result.isError()) {
                retryResult.setStatus(result.getStatus());
            }
            // TODO maybe add whole "result" as subresult to the retryResult?
            result.muteError();
        } catch (CommunicationException | GenericFrameworkException | ObjectAlreadyExistsException | SchemaException | ObjectNotFoundException | ConfigurationException | SecurityViolationException e) {
            // This is final failure: the error is not handled.
            // Therefore the operation is now completed - finished with an error.
            // But we do not want to stop the task. Just log the error.
            LOGGER.error("Operation {} on {} ended up with an error after {} retries: {}", pendingDelta, repoShadow, attemptNumber, e.getMessage(), e);
            // The retry itself was a success. Operation that was retried might have failed.
            // And that is recorded in the shadow. But we have successfully retried the operation.
            result.recordHandledError(e);
            retryResult.recordFatalError("Operation " + pendingDelta + " on " + repoShadow + " ended with an error after " + attemptNumber + " retries: " + e.getMessage());
        } catch (Throwable e) {
            // This is unexpected error during retry. This means that there was other
            // failure that we did not expected. This is likely to be bug - or maybe wrong
            // error handling. This means that the retry was a failure.
            result.recordFatalError(e);
            retryResult.recordFatalError(e);
        } finally {
            // Status should be set by now, we just want to close the result
            result.computeStatusIfUnknown();
        }
        objectDeltaOperation.setExecutionResult(result);
        executedDeltas.add(objectDeltaOperation);
    }
    RefreshShadowOperation rso = new RefreshShadowOperation();
    rso.setExecutedDeltas(executedDeltas);
    rso.setRefreshedShadow(repoShadow);
    parentResult.computeStatus();
    rso.setRefreshResult(retryResult);
    LOGGER.trace("refreshShadowOperation {}", rso.debugDumpLazily());
    return rso;
}
Also used : ArrayList(java.util.ArrayList) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult) GenericFrameworkException(com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException) RefreshShadowOperation(com.evolveum.midpoint.schema.RefreshShadowOperation) Duration(javax.xml.datatype.Duration) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) ObjectDeltaOperation(com.evolveum.midpoint.schema.ObjectDeltaOperation) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 5 with AsynchronousOperationResult

use of com.evolveum.midpoint.schema.result.AsynchronousOperationResult in project midpoint by Evolveum.

the class MaintenanceExceptionHandler method handleDeleteError.

@Override
public OperationResultStatus handleDeleteError(ProvisioningContext ctx, PrismObject<ShadowType> repoShadow, ProvisioningOperationOptions options, ProvisioningOperationState<AsynchronousOperationResult> opState, Exception cause, OperationResult failedOperationResult, Task task, OperationResult parentResult) {
    OperationResult result = parentResult.createSubresult(OPERATION_HANDLE_DELETE_ERROR);
    result.addParam("exception", cause.getMessage());
    try {
        failedOperationResult.setStatus(OperationResultStatus.IN_PROGRESS);
        return postponeDelete(ctx, repoShadow, opState, failedOperationResult, result);
    } catch (Throwable t) {
        result.recordFatalError(t);
        throw t;
    } finally {
        result.computeStatusIfUnknown();
    }
}
Also used : OperationResult(com.evolveum.midpoint.schema.result.OperationResult) AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult)

Aggregations

AsynchronousOperationResult (com.evolveum.midpoint.schema.result.AsynchronousOperationResult)17 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)10 GenericFrameworkException (com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException)6 CommunicationException (com.evolveum.midpoint.util.exception.CommunicationException)3 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)3 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)3 ObjectDeltaType (com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType)3 ArrayList (java.util.ArrayList)3 Duration (javax.xml.datatype.Duration)3 XMLGregorianCalendar (javax.xml.datatype.XMLGregorianCalendar)3 EncryptionException (com.evolveum.midpoint.prism.crypto.EncryptionException)2 ItemDelta (com.evolveum.midpoint.prism.delta.ItemDelta)2 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)2 ConnectorOperationOptions (com.evolveum.midpoint.provisioning.ucf.api.ConnectorOperationOptions)2 AsynchronousOperationReturnValue (com.evolveum.midpoint.schema.result.AsynchronousOperationReturnValue)2 ConfigurationException (com.evolveum.midpoint.util.exception.ConfigurationException)2 GuardedString (org.identityconnectors.common.security.GuardedString)2 PrismObject (com.evolveum.midpoint.prism.PrismObject)1 PrismPropertyValue (com.evolveum.midpoint.prism.PrismPropertyValue)1 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)1