Search in sources :

Example 1 with SyncDelta

use of org.identityconnectors.framework.common.objects.SyncDelta in project CzechIdMng by bcvsolutions.

the class ConnIdIcConnectorService method synchronization.

@Override
public IcSyncToken synchronization(IcConnectorInstance connectorInstance, IcConnectorConfiguration connectorConfiguration, IcObjectClass objectClass, IcSyncToken token, IcSyncResultsHandler handler) {
    Assert.notNull(connectorInstance, "Connector instance is required.");
    Assert.notNull(connectorInstance.getConnectorKey(), "Connector key is required.");
    Assert.notNull(connectorConfiguration, "Configuration is required.");
    Assert.notNull(objectClass, "Object class is required.");
    Assert.notNull(handler, "Handler is required.");
    LOG.debug("Start synchronization for connector {} and objectClass {} - ConnId", connectorInstance.getConnectorKey().toString(), objectClass.getDisplayName());
    ConnectorFacade conn = facadeFactory.getConnectorFacade(connectorInstance, connectorConfiguration);
    ObjectClass objectClassConnId = ConnIdIcConvertUtil.convertIcObjectClass(objectClass);
    if (objectClassConnId == null) {
        objectClassConnId = ObjectClass.ACCOUNT;
    }
    SyncToken syncToken = ConnIdIcConvertUtil.convertIcSyncToken(token);
    SyncResultsHandler handlerConnId = new SyncResultsHandler() {

        @Override
        public boolean handle(SyncDelta delta) {
            return handler.handle(ConnIdIcConvertUtil.convertConnIdSyncDelta(delta));
        }
    };
    SyncToken resultToken = conn.sync(objectClassConnId, syncToken, handlerConnId, new OperationOptions(connectorConfiguration.getSystemOperationOptions()));
    return ConnIdIcConvertUtil.convertConnIdSyncToken(resultToken);
}
Also used : OperationOptions(org.identityconnectors.framework.common.objects.OperationOptions) SyncToken(org.identityconnectors.framework.common.objects.SyncToken) IcSyncToken(eu.bcvsolutions.idm.ic.api.IcSyncToken) IcObjectClass(eu.bcvsolutions.idm.ic.api.IcObjectClass) ObjectClass(org.identityconnectors.framework.common.objects.ObjectClass) SyncDelta(org.identityconnectors.framework.common.objects.SyncDelta) IcConnectorFacade(eu.bcvsolutions.idm.ic.service.api.IcConnectorFacade) ConnectorFacade(org.identityconnectors.framework.api.ConnectorFacade) IcSyncResultsHandler(eu.bcvsolutions.idm.ic.api.IcSyncResultsHandler) SyncResultsHandler(org.identityconnectors.framework.common.objects.SyncResultsHandler)

Example 2 with SyncDelta

use of org.identityconnectors.framework.common.objects.SyncDelta in project midpoint by Evolveum.

the class ConnectorInstanceConnIdImpl method fetchChanges.

@Override
public List<Change> fetchChanges(ObjectClassComplexTypeDefinition objectClass, PrismProperty<?> lastToken, AttributesToReturn attrsToReturn, StateReporter reporter, OperationResult parentResult) throws CommunicationException, GenericFrameworkException, SchemaException, ConfigurationException {
    OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".fetchChanges");
    result.addContext("objectClass", objectClass);
    result.addParam("lastToken", lastToken);
    // create sync token from the property last token
    SyncToken syncToken = null;
    try {
        syncToken = getSyncToken(lastToken);
        LOGGER.trace("Sync token created from the property last token: {}", syncToken == null ? null : syncToken.getValue());
    } catch (SchemaException ex) {
        result.recordFatalError(ex.getMessage(), ex);
        throw new SchemaException(ex.getMessage(), ex);
    }
    final List<SyncDelta> syncDeltas = new ArrayList<SyncDelta>();
    // get icf object class
    ObjectClass icfObjectClass;
    if (objectClass == null) {
        icfObjectClass = ObjectClass.ALL;
    } else {
        icfObjectClass = connIdNameMapper.objectClassToIcf(objectClass, getSchemaNamespace(), connectorType, legacySchema);
    }
    OperationOptionsBuilder optionsBuilder = new OperationOptionsBuilder();
    if (objectClass != null) {
        convertToIcfAttrsToGet(objectClass, attrsToReturn, optionsBuilder);
    }
    OperationOptions options = optionsBuilder.build();
    SyncResultsHandler syncHandler = new SyncResultsHandler() {

        @Override
        public boolean handle(SyncDelta delta) {
            LOGGER.trace("Detected sync delta: {}", delta);
            return syncDeltas.add(delta);
        }
    };
    OperationResult connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".sync");
    connIdResult.addContext("connector", connIdConnectorFacade.getClass());
    connIdResult.addArbitraryObjectAsParam("connIdObjectClass", icfObjectClass);
    connIdResult.addArbitraryObjectAsParam("syncToken", syncToken);
    connIdResult.addArbitraryObjectAsParam("syncHandler", syncHandler);
    SyncToken lastReceivedToken;
    try {
        InternalMonitor.recordConnectorOperation("sync");
        recordIcfOperationStart(reporter, ProvisioningOperation.ICF_SYNC, objectClass);
        lastReceivedToken = connIdConnectorFacade.sync(icfObjectClass, syncToken, syncHandler, options);
        recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SYNC, objectClass);
        connIdResult.recordSuccess();
        connIdResult.addReturn(OperationResult.RETURN_COUNT, syncDeltas.size());
    } catch (Throwable ex) {
        recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SYNC, objectClass, ex);
        Throwable midpointEx = processIcfException(ex, this, connIdResult);
        result.computeStatus();
        // exception
        if (midpointEx instanceof CommunicationException) {
            throw (CommunicationException) midpointEx;
        } else if (midpointEx instanceof GenericFrameworkException) {
            throw (GenericFrameworkException) midpointEx;
        } else if (midpointEx instanceof SchemaException) {
            throw (SchemaException) 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);
        }
    }
    // convert changes from icf to midpoint Change
    List<Change> changeList;
    try {
        changeList = getChangesFromSyncDeltas(icfObjectClass, syncDeltas, resourceSchema, result);
    } catch (SchemaException ex) {
        result.recordFatalError(ex.getMessage(), ex);
        throw new SchemaException(ex.getMessage(), ex);
    }
    if (lastReceivedToken != null) {
        Change lastChange = new Change((ObjectDelta) null, getToken(lastReceivedToken));
        LOGGER.trace("Adding last change: {}", lastChange);
        changeList.add(lastChange);
    }
    result.recordSuccess();
    result.addReturn(OperationResult.RETURN_COUNT, changeList == null ? 0 : changeList.size());
    return changeList;
}
Also used : OperationOptions(org.identityconnectors.framework.common.objects.OperationOptions) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) ObjectClass(org.identityconnectors.framework.common.objects.ObjectClass) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) GenericFrameworkException(com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) AsynchronousOperationResult(com.evolveum.midpoint.schema.result.AsynchronousOperationResult) Change(com.evolveum.midpoint.provisioning.ucf.api.Change) OperationOptionsBuilder(org.identityconnectors.framework.common.objects.OperationOptionsBuilder) SyncToken(org.identityconnectors.framework.common.objects.SyncToken) SyncDelta(org.identityconnectors.framework.common.objects.SyncDelta) SystemException(com.evolveum.midpoint.util.exception.SystemException) SyncResultsHandler(org.identityconnectors.framework.common.objects.SyncResultsHandler)

Example 3 with SyncDelta

use of org.identityconnectors.framework.common.objects.SyncDelta in project midpoint by Evolveum.

the class ConnectorInstanceConnIdImpl method getChangesFromSyncDeltas.

private List<Change> getChangesFromSyncDeltas(ObjectClass connIdObjClass, Collection<SyncDelta> connIdDeltas, PrismSchema schema, OperationResult parentResult) throws SchemaException, GenericFrameworkException {
    List<Change> changeList = new ArrayList<Change>();
    QName objectClass = connIdNameMapper.objectClassToQname(connIdObjClass, getSchemaNamespace(), legacySchema);
    ObjectClassComplexTypeDefinition objClassDefinition = null;
    if (objectClass != null) {
        objClassDefinition = (ObjectClassComplexTypeDefinition) schema.findComplexTypeDefinition(objectClass);
    }
    Validate.notNull(connIdDeltas, "Sync result must not be null.");
    for (SyncDelta icfDelta : connIdDeltas) {
        ObjectClass deltaIcfObjClass = connIdObjClass;
        QName deltaObjectClass = objectClass;
        ObjectClassComplexTypeDefinition deltaObjClassDefinition = objClassDefinition;
        if (objectClass == null) {
            deltaIcfObjClass = icfDelta.getObjectClass();
            deltaObjectClass = connIdNameMapper.objectClassToQname(deltaIcfObjClass, getSchemaNamespace(), legacySchema);
            if (deltaIcfObjClass != null) {
                deltaObjClassDefinition = (ObjectClassComplexTypeDefinition) schema.findComplexTypeDefinition(deltaObjectClass);
            }
        }
        if (deltaObjClassDefinition == null) {
            if (icfDelta.getDeltaType() == SyncDeltaType.DELETE) {
            // tolerate this. E.g. LDAP changelogs do not have objectclass in delete deltas.
            } else {
                throw new SchemaException("Got delta with object class " + deltaObjectClass + " (" + deltaIcfObjClass + ") that has no definition in resource schema");
            }
        }
        SyncDeltaType icfDeltaType = icfDelta.getDeltaType();
        if (SyncDeltaType.DELETE.equals(icfDeltaType)) {
            LOGGER.trace("START creating delta of type DELETE");
            ObjectDelta<ShadowType> objectDelta = new ObjectDelta<ShadowType>(ShadowType.class, ChangeType.DELETE, prismContext);
            Collection<ResourceAttribute<?>> identifiers = ConnIdUtil.convertToIdentifiers(icfDelta.getUid(), deltaObjClassDefinition, resourceSchema);
            Change change = new Change(identifiers, objectDelta, getToken(icfDelta.getToken()));
            change.setObjectClassDefinition(deltaObjClassDefinition);
            changeList.add(change);
            LOGGER.trace("END creating delta of type DELETE");
        } else if (SyncDeltaType.CREATE.equals(icfDeltaType)) {
            PrismObjectDefinition<ShadowType> objectDefinition = toShadowDefinition(deltaObjClassDefinition);
            LOGGER.trace("Object definition: {}", objectDefinition);
            LOGGER.trace("START creating delta of type CREATE");
            PrismObject<ShadowType> currentShadow = connIdConvertor.convertToResourceObject(icfDelta.getObject(), objectDefinition, false, caseIgnoreAttributeNames, legacySchema);
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Got current shadow: {}", currentShadow.debugDump());
            }
            Collection<ResourceAttribute<?>> identifiers = ShadowUtil.getAllIdentifiers(currentShadow);
            ObjectDelta<ShadowType> objectDelta = new ObjectDelta<ShadowType>(ShadowType.class, ChangeType.ADD, prismContext);
            objectDelta.setObjectToAdd(currentShadow);
            Change change = new Change(identifiers, objectDelta, getToken(icfDelta.getToken()));
            change.setObjectClassDefinition(deltaObjClassDefinition);
            changeList.add(change);
            LOGGER.trace("END creating delta of type CREATE");
        } else if (SyncDeltaType.CREATE_OR_UPDATE.equals(icfDeltaType) || SyncDeltaType.UPDATE.equals(icfDeltaType)) {
            PrismObjectDefinition<ShadowType> objectDefinition = toShadowDefinition(deltaObjClassDefinition);
            LOGGER.trace("Object definition: {}", objectDefinition);
            LOGGER.trace("START creating delta of type {}", icfDeltaType);
            PrismObject<ShadowType> currentShadow = connIdConvertor.convertToResourceObject(icfDelta.getObject(), objectDefinition, false, caseIgnoreAttributeNames, legacySchema);
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Got current shadow: {}", currentShadow.debugDump());
            }
            Collection<ResourceAttribute<?>> identifiers = ShadowUtil.getAllIdentifiers(currentShadow);
            Change change = new Change(identifiers, currentShadow, getToken(icfDelta.getToken()));
            change.setObjectClassDefinition(deltaObjClassDefinition);
            changeList.add(change);
            LOGGER.trace("END creating delta of type {}:\n{}", icfDeltaType, change.debugDump());
        } else {
            throw new GenericFrameworkException("Unexpected sync delta type " + icfDeltaType);
        }
    }
    return changeList;
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) ObjectClass(org.identityconnectors.framework.common.objects.ObjectClass) SyncDeltaType(org.identityconnectors.framework.common.objects.SyncDeltaType) GenericFrameworkException(com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException) QName(javax.xml.namespace.QName) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) Change(com.evolveum.midpoint.provisioning.ucf.api.Change) SyncDelta(org.identityconnectors.framework.common.objects.SyncDelta) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta)

Example 4 with SyncDelta

use of org.identityconnectors.framework.common.objects.SyncDelta in project syncope by apache.

the class DefaultRealmPullResultHandler method doHandle.

private void doHandle(final SyncDelta delta, final OrgUnit orgUnit) throws JobExecutionException {
    LOG.debug("Process {} for {} as {}", delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
    SyncDelta processed = delta;
    for (PullActions action : profile.getActions()) {
        processed = action.preprocess(profile, processed);
    }
    LOG.debug("Transformed {} for {} as {}", processed.getDeltaType(), processed.getUid().getUidValue(), processed.getObject().getObjectClass());
    List<String> keys = pullUtils.match(processed.getObject(), orgUnit);
    LOG.debug("Match found for {} as {}: {}", processed.getUid().getUidValue(), processed.getObject().getObjectClass(), keys);
    if (keys.size() > 1) {
        switch(profile.getResAct()) {
            case IGNORE:
                throw new IllegalStateException("More than one match " + keys);
            case FIRSTMATCH:
                keys = keys.subList(0, 1);
                break;
            case LASTMATCH:
                keys = keys.subList(keys.size() - 1, keys.size());
                break;
            default:
        }
    }
    try {
        if (SyncDeltaType.CREATE_OR_UPDATE == processed.getDeltaType()) {
            if (keys.isEmpty()) {
                switch(profile.getTask().getUnmatchingRule()) {
                    case ASSIGN:
                        profile.getResults().addAll(assign(processed, orgUnit));
                        break;
                    case PROVISION:
                        profile.getResults().addAll(provision(processed, orgUnit));
                        break;
                    case IGNORE:
                        profile.getResults().add(ignore(processed, false));
                        break;
                    default:
                }
            } else {
                switch(profile.getTask().getMatchingRule()) {
                    case UPDATE:
                        profile.getResults().addAll(update(processed, keys));
                        break;
                    case DEPROVISION:
                        profile.getResults().addAll(deprovision(processed, keys, false));
                        break;
                    case UNASSIGN:
                        profile.getResults().addAll(deprovision(processed, keys, true));
                        break;
                    case LINK:
                        profile.getResults().addAll(link(processed, keys, false));
                        break;
                    case UNLINK:
                        profile.getResults().addAll(link(processed, keys, true));
                        break;
                    case IGNORE:
                        profile.getResults().add(ignore(processed, true));
                        break;
                    default:
                }
            }
        } else if (SyncDeltaType.DELETE == processed.getDeltaType()) {
            if (keys.isEmpty()) {
                finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, processed);
                LOG.debug("No match found for deletion");
            } else {
                profile.getResults().addAll(delete(processed, keys));
            }
        }
    } catch (IllegalStateException | IllegalArgumentException e) {
        LOG.warn(e.getMessage());
    }
}
Also used : SyncDelta(org.identityconnectors.framework.common.objects.SyncDelta) PullActions(org.apache.syncope.core.provisioning.api.pushpull.PullActions)

Example 5 with SyncDelta

use of org.identityconnectors.framework.common.objects.SyncDelta in project syncope by apache.

the class AbstractPullResultHandler method doHandle.

/**
 * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on any object(s).
 *
 * @param delta returned by the underlying profile.getConnector()
 * @param provision provisioning info
 * @throws JobExecutionException in case of pull failure.
 */
protected void doHandle(final SyncDelta delta, final Provision provision) throws JobExecutionException {
    AnyUtils anyUtils = getAnyUtils();
    LOG.debug("Process {} for {} as {}", delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
    SyncDelta processed = delta;
    for (PullActions action : profile.getActions()) {
        processed = action.preprocess(profile, processed);
    }
    LOG.debug("Transformed {} for {} as {}", processed.getDeltaType(), processed.getUid().getUidValue(), processed.getObject().getObjectClass());
    try {
        List<String> anyKeys = pullUtils.match(processed.getObject(), provision, anyUtils);
        LOG.debug("Match(es) found for {} as {}: {}", processed.getUid().getUidValue(), processed.getObject().getObjectClass(), anyKeys);
        if (anyKeys.size() > 1) {
            switch(profile.getResAct()) {
                case IGNORE:
                    throw new IllegalStateException("More than one match " + anyKeys);
                case FIRSTMATCH:
                    anyKeys = anyKeys.subList(0, 1);
                    break;
                case LASTMATCH:
                    anyKeys = anyKeys.subList(anyKeys.size() - 1, anyKeys.size());
                    break;
                default:
            }
        }
        if (SyncDeltaType.CREATE_OR_UPDATE == processed.getDeltaType()) {
            if (anyKeys.isEmpty()) {
                switch(profile.getTask().getUnmatchingRule()) {
                    case ASSIGN:
                        profile.getResults().addAll(assign(processed, provision, anyUtils));
                        break;
                    case PROVISION:
                        profile.getResults().addAll(provision(processed, provision, anyUtils));
                        break;
                    case IGNORE:
                        profile.getResults().addAll(ignore(processed, null, provision, false));
                        break;
                    default:
                }
            } else {
                // update VirAttrCache
                for (VirSchema virSchema : virSchemaDAO.findByProvision(provision)) {
                    Attribute attr = processed.getObject().getAttributeByName(virSchema.getExtAttrName());
                    for (String anyKey : anyKeys) {
                        if (attr == null) {
                            virAttrCache.expire(provision.getAnyType().getKey(), anyKey, virSchema.getKey());
                        } else {
                            VirAttrCacheValue cacheValue = new VirAttrCacheValue();
                            cacheValue.setValues(attr.getValue());
                            virAttrCache.put(provision.getAnyType().getKey(), anyKey, virSchema.getKey(), cacheValue);
                        }
                    }
                }
                switch(profile.getTask().getMatchingRule()) {
                    case UPDATE:
                        profile.getResults().addAll(update(processed, anyKeys, provision));
                        break;
                    case DEPROVISION:
                        profile.getResults().addAll(deprovision(processed, anyKeys, provision, false));
                        break;
                    case UNASSIGN:
                        profile.getResults().addAll(deprovision(processed, anyKeys, provision, true));
                        break;
                    case LINK:
                        profile.getResults().addAll(link(processed, anyKeys, provision, false));
                        break;
                    case UNLINK:
                        profile.getResults().addAll(link(processed, anyKeys, provision, true));
                        break;
                    case IGNORE:
                        profile.getResults().addAll(ignore(processed, anyKeys, provision, true));
                        break;
                    default:
                }
            }
        } else if (SyncDeltaType.DELETE == processed.getDeltaType()) {
            if (anyKeys.isEmpty()) {
                finalize(ResourceOperation.DELETE.name().toLowerCase(), Result.SUCCESS, null, null, processed);
                LOG.debug("No match found for deletion");
            } else {
                profile.getResults().addAll(delete(processed, anyKeys, provision));
            }
        }
    } catch (IllegalStateException | IllegalArgumentException e) {
        LOG.warn(e.getMessage());
    }
}
Also used : SyncDelta(org.identityconnectors.framework.common.objects.SyncDelta) VirSchema(org.apache.syncope.core.persistence.api.entity.VirSchema) Attribute(org.identityconnectors.framework.common.objects.Attribute) PullActions(org.apache.syncope.core.provisioning.api.pushpull.PullActions) VirAttrCacheValue(org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue) AnyUtils(org.apache.syncope.core.persistence.api.entity.AnyUtils)

Aggregations

SyncDelta (org.identityconnectors.framework.common.objects.SyncDelta)6 ObjectClass (org.identityconnectors.framework.common.objects.ObjectClass)4 Change (com.evolveum.midpoint.provisioning.ucf.api.Change)2 GenericFrameworkException (com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException)2 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)2 PullActions (org.apache.syncope.core.provisioning.api.pushpull.PullActions)2 Attribute (org.identityconnectors.framework.common.objects.Attribute)2 OperationOptions (org.identityconnectors.framework.common.objects.OperationOptions)2 OperationOptionsBuilder (org.identityconnectors.framework.common.objects.OperationOptionsBuilder)2 SyncResultsHandler (org.identityconnectors.framework.common.objects.SyncResultsHandler)2 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)1 AsynchronousOperationResult (com.evolveum.midpoint.schema.result.AsynchronousOperationResult)1 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)1 CommunicationException (com.evolveum.midpoint.util.exception.CommunicationException)1 SystemException (com.evolveum.midpoint.util.exception.SystemException)1 ShadowType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType)1 IcObjectClass (eu.bcvsolutions.idm.ic.api.IcObjectClass)1 IcSyncResultsHandler (eu.bcvsolutions.idm.ic.api.IcSyncResultsHandler)1 IcSyncToken (eu.bcvsolutions.idm.ic.api.IcSyncToken)1 IcConnectorFacade (eu.bcvsolutions.idm.ic.service.api.IcConnectorFacade)1