Search in sources :

Example 11 with AsynchronousOperationResult

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

the class AsyncProvisioningConnectorInstance method deleteObject.

@Override
public AsynchronousOperationResult deleteObject(ResourceObjectDefinition objectDefinition, PrismObject<ShadowType> shadow, Collection<? extends ResourceAttribute<?>> identifiers, UcfExecutionContext ctx, OperationResult parentResult) throws SchemaException {
    InternalMonitor.recordConnectorOperation("deleteObject");
    OperationResult result = parentResult.createSubresult(OP_DELETE_OBJECT);
    try {
        OperationRequested operation = new OperationRequested.Delete(objectDefinition, asObjectable(shadow), identifiers, getPrismContext());
        return createAndSendRequest(operation, ctx.getTask(), 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)

Example 12 with AsynchronousOperationResult

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

the class PropagateHelper method propagateOperations.

public void propagateOperations(PrismObject<ResourceType> resource, PrismObject<ShadowType> shadow, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException, GenericFrameworkException, ObjectAlreadyExistsException, SecurityViolationException, PolicyViolationException, EncryptionException {
    ResourceConsistencyType resourceConsistencyType = resource.asObjectable().getConsistency();
    if (resourceConsistencyType == null) {
        LOGGER.warn("Skipping propagation of {} because no there is no consistency definition in resource", shadow);
        return;
    }
    Duration operationGroupingInterval = resourceConsistencyType.getOperationGroupingInterval();
    if (operationGroupingInterval == null) {
        LOGGER.warn("Skipping propagation of {} because no there is no operationGroupingInterval defined in resource", shadow);
        return;
    }
    XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar();
    List<PendingOperationType> pendingExecutionOperations = new ArrayList<>();
    boolean triggered = false;
    for (PendingOperationType pendingOperation : shadow.asObjectable().getPendingOperation()) {
        PendingOperationExecutionStatusType executionStatus = pendingOperation.getExecutionStatus();
        if (executionStatus == PendingOperationExecutionStatusType.EXECUTION_PENDING) {
            pendingExecutionOperations.add(pendingOperation);
            if (isPropagationTriggered(pendingOperation, operationGroupingInterval, now)) {
                triggered = true;
            }
        }
    }
    if (!triggered) {
        LOGGER.debug("Skipping propagation of {} because no pending operation triggered propagation", shadow);
        return;
    }
    if (pendingExecutionOperations.isEmpty()) {
        LOGGER.debug("Skipping propagation of {} because there are no pending executions", shadow);
        return;
    }
    LOGGER.debug("Propagating {} pending operations in {} ", pendingExecutionOperations.size(), shadow);
    ObjectDelta<ShadowType> operationDelta = null;
    List<PendingOperationType> sortedOperations = shadowCaretaker.sortPendingOperations(pendingExecutionOperations);
    for (PendingOperationType pendingOperation : sortedOperations) {
        ObjectDeltaType pendingDeltaType = pendingOperation.getDelta();
        ObjectDelta<ShadowType> pendingDelta = DeltaConvertor.createObjectDelta(pendingDeltaType, prismContext);
        definitionsHelper.applyDefinition(pendingDelta, shadow.asObjectable(), task, result);
        if (operationDelta == null) {
            operationDelta = pendingDelta;
        } else {
            operationDelta.merge(pendingDelta);
        }
    }
    // there is at least one pending operation
    assert operationDelta != null;
    ProvisioningContext ctx = ctxFactory.createForShadow(shadow, task, result);
    ctx.setPropagation(true);
    shadowCaretaker.applyAttributesDefinition(ctx, shadow);
    shadowCaretaker.applyAttributesDefinition(ctx, operationDelta);
    LOGGER.trace("Merged operation for {}:\n{} ", shadow, operationDelta.debugDumpLazily(1));
    if (operationDelta.isAdd()) {
        PrismObject<ShadowType> shadowToAdd = operationDelta.getObjectToAdd();
        ProvisioningOperationState<AsynchronousOperationReturnValue<PrismObject<ShadowType>>> opState = ProvisioningOperationState.fromPendingOperations(shadow, sortedOperations);
        shadowToAdd.setOid(shadow.getOid());
        addHelper.addShadowAttempt(ctx, shadowToAdd, null, opState, null, task, result);
        opState.determineExecutionStatusFromResult();
        shadowManager.updatePendingOperations(ctx, shadow, opState, pendingExecutionOperations, now, result);
        addHelper.notifyAfterAdd(ctx, opState.getAsyncResult().getReturnValue(), opState, task, result);
    } else if (operationDelta.isModify()) {
        Collection<? extends ItemDelta<?, ?>> modifications = operationDelta.getModifications();
        ProvisioningOperationState<AsynchronousOperationReturnValue<Collection<PropertyDelta<PrismPropertyValue>>>> opState = modifyHelper.executeResourceModify(ctx, shadow, modifications, null, null, now, task, result);
        opState.determineExecutionStatusFromResult();
        shadowManager.updatePendingOperations(ctx, shadow, opState, pendingExecutionOperations, now, result);
        modifyHelper.notifyAfterModify(ctx, shadow, modifications, opState, task, result);
    } else if (operationDelta.isDelete()) {
        ProvisioningOperationState<AsynchronousOperationResult> opState = deleteHelper.executeResourceDelete(ctx, shadow, null, null, task, result);
        opState.determineExecutionStatusFromResult();
        shadowManager.updatePendingOperations(ctx, shadow, opState, pendingExecutionOperations, now, result);
        deleteHelper.notifyAfterDelete(ctx, shadow, opState, task, result);
    } else {
        throw new IllegalStateException("Delta from outer space: " + operationDelta);
    }
// do we need to modify exists/dead flags?
}
Also used : ArrayList(java.util.ArrayList) AsynchronousOperationReturnValue(com.evolveum.midpoint.schema.result.AsynchronousOperationReturnValue) Duration(javax.xml.datatype.Duration) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) ProvisioningContext(com.evolveum.midpoint.provisioning.impl.ProvisioningContext) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult) Collection(java.util.Collection) ProvisioningOperationState(com.evolveum.midpoint.provisioning.impl.ProvisioningOperationState) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue)

Example 13 with AsynchronousOperationResult

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

the class RefreshHelper method refreshShadowAsyncStatus.

/**
 * Refresh status of asynchronous operation, e.g. status of manual connector ticket.
 * This method will get new status from resourceObjectConverter and it will process the
 * status in case that it has changed.
 */
private void refreshShadowAsyncStatus(ProvisioningContext ctx, PrismObject<ShadowType> repoShadow, List<PendingOperationType> sortedOperations, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
    Duration gracePeriod = ProvisioningUtil.getGracePeriod(ctx);
    List<ObjectDelta<ShadowType>> notificationDeltas = new ArrayList<>();
    boolean shadowInception = false;
    OperationResultStatusType shadowInceptionOutcome = null;
    ObjectDelta<ShadowType> shadowDelta = repoShadow.createModifyDelta();
    for (PendingOperationType pendingOperation : sortedOperations) {
        if (!needsRefresh(pendingOperation)) {
            continue;
        }
        ItemPath containerPath = pendingOperation.asPrismContainerValue().getPath();
        String asyncRef = pendingOperation.getAsynchronousOperationReference();
        if (asyncRef == null) {
            continue;
        }
        AsynchronousOperationResult refreshAsyncResult;
        try {
            refreshAsyncResult = resourceObjectConverter.refreshOperationStatus(ctx, repoShadow, asyncRef, parentResult);
        } catch (CommunicationException e) {
            LOGGER.debug("Communication error while trying to refresh pending operation of {}. Skipping refresh of this operation.", repoShadow, e);
            parentResult.recordPartialError(e);
            continue;
        }
        OperationResultStatus newStatus = refreshAsyncResult.getOperationResult().getStatus();
        if (newStatus == null) {
            continue;
        }
        OperationResultStatusType newStatusType = newStatus.createStatusType();
        if (newStatusType.equals(pendingOperation.getResultStatus())) {
            continue;
        }
        boolean operationCompleted = ProvisioningUtil.isCompleted(newStatusType) && pendingOperation.getCompletionTimestamp() == null;
        if (operationCompleted && gracePeriod == null) {
            LOGGER.trace("Deleting pending operation because it is completed (no grace): {}", pendingOperation);
            shadowDelta.addModificationDeleteContainer(ShadowType.F_PENDING_OPERATION, pendingOperation.clone());
            ObjectDeltaType pendingDeltaType = pendingOperation.getDelta();
            ObjectDelta<ShadowType> pendingDelta = DeltaConvertor.createObjectDelta(pendingDeltaType, prismContext);
            if (pendingDelta.isAdd()) {
                shadowInception = true;
                shadowInceptionOutcome = newStatusType;
            }
            if (pendingDelta.isDelete()) {
                shadowInception = false;
                shadowManager.addDeadShadowDeltas(repoShadow, (List) shadowDelta.getModifications());
            }
            continue;
        } else {
            PropertyDelta<OperationResultStatusType> resultStatusDelta = shadowDelta.createPropertyModification(containerPath.append(PendingOperationType.F_RESULT_STATUS));
            resultStatusDelta.setRealValuesToReplace(newStatusType);
            shadowDelta.addModification(resultStatusDelta);
        }
        if (operationCompleted) {
            // Operation completed
            PropertyDelta<PendingOperationExecutionStatusType> executionStatusDelta = shadowDelta.createPropertyModification(containerPath.append(PendingOperationType.F_EXECUTION_STATUS));
            executionStatusDelta.setRealValuesToReplace(PendingOperationExecutionStatusType.COMPLETED);
            shadowDelta.addModification(executionStatusDelta);
            PropertyDelta<XMLGregorianCalendar> completionTimestampDelta = shadowDelta.createPropertyModification(containerPath.append(PendingOperationType.F_COMPLETION_TIMESTAMP));
            completionTimestampDelta.setRealValuesToReplace(clock.currentTimeXMLGregorianCalendar());
            shadowDelta.addModification(completionTimestampDelta);
            ObjectDeltaType pendingDeltaType = pendingOperation.getDelta();
            ObjectDelta<ShadowType> pendingDelta = DeltaConvertor.createObjectDelta(pendingDeltaType, prismContext);
            if (pendingDelta.isAdd()) {
                shadowInception = true;
                shadowInceptionOutcome = newStatusType;
            }
            if (pendingDelta.isModify()) {
                // Apply shadow naming attribute modification
                PrismContainer<ShadowAttributesType> shadowAttributesContainer = repoShadow.findContainer(ItemPath.create(ShadowType.F_ATTRIBUTES));
                ResourceAttributeContainer resourceAttributeContainer = ResourceAttributeContainer.convertFromContainer(shadowAttributesContainer, ctx.getObjectDefinitionRequired());
                ResourceAttributeContainerDefinition resourceAttrDefinition = resourceAttributeContainer.getDefinition();
                if (resourceAttrDefinition != null) {
                    // If naming attribute is present in delta...
                    ResourceAttributeDefinition<?> namingAttribute = resourceAttrDefinition.getNamingAttribute();
                    if (namingAttribute != null) {
                        if (pendingDelta.hasItemDelta(ItemPath.create(ShadowType.F_ATTRIBUTES, namingAttribute.getItemName()))) {
                            // Retrieve a possible changed name per the defined naming attribute for the resource
                            ItemDelta namingAttributeDelta = pendingDelta.findItemDelta(ItemPath.create(ShadowType.F_ATTRIBUTES, namingAttribute.getItemName()));
                            Collection<?> valuesToReplace = namingAttributeDelta.getValuesToReplace();
                            Optional<?> valueToReplace = valuesToReplace.stream().findFirst();
                            if (valueToReplace.isPresent()) {
                                Object valueToReplaceObj = ((PrismPropertyValue) valueToReplace.get()).getValue();
                                if (valueToReplaceObj instanceof String) {
                                    // Apply the new naming attribute value to the shadow name by adding the change to the modification set for shadow delta
                                    PropertyDelta<PolyString> nameDelta = shadowDelta.createPropertyModification(ItemPath.create(ShadowType.F_NAME));
                                    Collection<PolyString> modificationSet = new ArrayList<>();
                                    PolyString nameAttributeReplacement = new PolyString((String) valueToReplaceObj);
                                    modificationSet.add(nameAttributeReplacement);
                                    nameDelta.setValuesToReplace(PrismValueCollectionsUtil.createCollection(prismContext, modificationSet));
                                    shadowDelta.addModification(nameDelta);
                                }
                            }
                        }
                    }
                }
                // Apply shadow attribute modifications
                for (ItemDelta<?, ?> pendingModification : pendingDelta.getModifications()) {
                    shadowDelta.addModification(pendingModification.clone());
                }
            }
            if (pendingDelta.isDelete()) {
                shadowInception = false;
                shadowManager.addDeadShadowDeltas(repoShadow, (List) shadowDelta.getModifications());
            }
            notificationDeltas.add(pendingDelta);
        }
    }
    if (shadowInception) {
        // We do not need to care about attributes in add deltas here. The add operation is already applied to
        // attributes. We need this to "allocate" the identifiers, so iteration mechanism in the
        // model can find unique values while taking pending create operations into consideration.
        PropertyDelta<Boolean> existsDelta = shadowDelta.createPropertyModification(ShadowType.F_EXISTS);
        if (OperationResultUtil.isSuccessful(shadowInceptionOutcome)) {
            existsDelta.setRealValuesToReplace(true);
        } else {
            existsDelta.setRealValuesToReplace(false);
        }
        shadowDelta.addModification(existsDelta);
    }
    XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar();
    expirePendingOperations(ctx, repoShadow, shadowDelta, now);
    if (!shadowDelta.isEmpty()) {
        shadowCaretaker.applyAttributesDefinition(ctx, shadowDelta);
        shadowManager.modifyShadowAttributes(ctx, repoShadow, shadowDelta.getModifications(), parentResult);
    }
    for (ObjectDelta<ShadowType> notificationDelta : notificationDeltas) {
        ResourceOperationDescription operationDescription = createSuccessOperationDescription(ctx, repoShadow, notificationDelta, parentResult);
        operationListener.notifySuccess(operationDescription, task, parentResult);
    }
    if (!shadowDelta.isEmpty()) {
        shadowDelta.applyTo(repoShadow);
    }
}
Also used : ArrayList(java.util.ArrayList) ResourceAttributeContainer(com.evolveum.midpoint.schema.processor.ResourceAttributeContainer) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) OperationResultStatus(com.evolveum.midpoint.schema.result.OperationResultStatus) ResourceOperationDescription(com.evolveum.midpoint.provisioning.api.ResourceOperationDescription) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) ResourceAttributeContainerDefinition(com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition) Duration(javax.xml.datatype.Duration) ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 14 with AsynchronousOperationResult

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

the class RefreshHelper method retryOperation.

private void retryOperation(ProvisioningContext ctx, ObjectDelta<ShadowType> pendingDelta, ProvisioningOperationState<? extends AsynchronousOperationResult> opState, Task task, OperationResult result) throws CommunicationException, GenericFrameworkException, ObjectAlreadyExistsException, SchemaException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, PolicyViolationException, ExpressionEvaluationException, EncryptionException {
    ProvisioningOperationOptions options = ProvisioningOperationOptions.createForceRetry(false);
    // TODO
    OperationProvisioningScriptsType scripts = null;
    if (pendingDelta.isAdd()) {
        PrismObject<ShadowType> resourceObjectToAdd = pendingDelta.getObjectToAdd();
        addHelper.addShadowAttempt(ctx, resourceObjectToAdd, scripts, (ProvisioningOperationState<AsynchronousOperationReturnValue<PrismObject<ShadowType>>>) opState, options, task, result);
    }
    if (pendingDelta.isModify()) {
        if (opState.objectExists()) {
            modifyHelper.modifyShadowAttempt(ctx, pendingDelta.getModifications(), scripts, options, (ProvisioningOperationState<AsynchronousOperationReturnValue<Collection<PropertyDelta<PrismPropertyValue>>>>) opState, true, task, result);
        } else {
            result.recordFatalError("Object does not exist on the resource yet, modification attempt was skipped");
        }
    }
    if (pendingDelta.isDelete()) {
        if (opState.objectExists()) {
            deleteHelper.deleteShadowAttempt(ctx, options, scripts, (ProvisioningOperationState<AsynchronousOperationResult>) opState, task, result);
        } else {
            result.recordFatalError("Object does not exist on the resource yet, deletion attempt was skipped");
        }
    }
}
Also used : AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult) AsynchronousOperationReturnValue(com.evolveum.midpoint.schema.result.AsynchronousOperationReturnValue) ProvisioningOperationOptions(com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta)

Example 15 with AsynchronousOperationResult

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

the class ErrorHandler method postponeDelete.

protected OperationResultStatus postponeDelete(ProvisioningContext ctx, PrismObject<ShadowType> repoShadow, ProvisioningOperationState<AsynchronousOperationResult> opState, OperationResult failedOperationResult, OperationResult result) {
    LOGGER.trace("Postponing DELETE operation for {}", repoShadow);
    opState.setExecutionStatus(PendingOperationExecutionStatusType.EXECUTING);
    AsynchronousOperationResult asyncResult = new AsynchronousOperationResult();
    asyncResult.setOperationResult(failedOperationResult);
    asyncResult.setOperationType(PendingOperationTypeType.RETRY);
    opState.setAsyncResult(asyncResult);
    if (opState.getAttemptNumber() == null) {
        opState.setAttemptNumber(1);
    }
    result.setInProgress();
    return OperationResultStatus.IN_PROGRESS;
}
Also used : 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