| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.syncope.core.provisioning.java.propagation; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Optional; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.commons.lang3.tuple.Pair; |
| import org.apache.syncope.common.lib.Attr; |
| import org.apache.syncope.common.lib.request.AbstractPatchItem; |
| import org.apache.syncope.common.lib.request.UserUR; |
| import org.apache.syncope.common.lib.types.AnyTypeKind; |
| import org.apache.syncope.common.lib.types.ResourceOperation; |
| import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; |
| import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; |
| import org.apache.syncope.core.persistence.api.entity.Any; |
| import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory; |
| import org.apache.syncope.core.persistence.api.entity.EntityFactory; |
| import org.apache.syncope.core.persistence.api.entity.Realm; |
| import org.apache.syncope.core.persistence.api.entity.VirSchema; |
| import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; |
| import org.apache.syncope.core.persistence.api.entity.resource.Item; |
| import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit; |
| import org.apache.syncope.core.persistence.api.entity.resource.Provision; |
| import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; |
| import org.apache.syncope.core.persistence.api.entity.user.User; |
| import org.apache.syncope.core.provisioning.api.DerAttrHandler; |
| import org.apache.syncope.core.provisioning.api.MappingManager; |
| import org.apache.syncope.core.provisioning.api.PropagationByResource; |
| import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; |
| import org.apache.syncope.core.provisioning.api.UserWorkflowResult; |
| import org.apache.syncope.core.provisioning.api.jexl.JexlUtils; |
| import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; |
| import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; |
| import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; |
| import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils; |
| import org.apache.syncope.core.provisioning.java.utils.MappingUtils; |
| import org.identityconnectors.framework.common.objects.Attribute; |
| import org.identityconnectors.framework.common.objects.AttributeBuilder; |
| import org.identityconnectors.framework.common.objects.AttributeUtil; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.transaction.annotation.Transactional; |
| import org.springframework.util.CollectionUtils; |
| |
| /** |
| * Manage the data propagation to external resources. |
| */ |
| @Transactional(rollbackFor = { Throwable.class }) |
| public class PropagationManagerImpl implements PropagationManager { |
| |
| protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class); |
| |
| @Autowired |
| protected VirSchemaDAO virSchemaDAO; |
| |
| @Autowired |
| protected ExternalResourceDAO resourceDAO; |
| |
| @Autowired |
| protected EntityFactory entityFactory; |
| |
| @Autowired |
| protected ConnObjectUtils connObjectUtils; |
| |
| @Autowired |
| protected MappingManager mappingManager; |
| |
| @Autowired |
| protected DerAttrHandler derAttrHandler; |
| |
| @Autowired |
| protected AnyUtilsFactory anyUtilsFactory; |
| |
| @Override |
| public List<PropagationTaskInfo> getCreateTasks( |
| final AnyTypeKind kind, |
| final String key, |
| final Boolean enable, |
| final PropagationByResource<String> propByRes, |
| final Collection<Attr> vAttrs, |
| final Collection<String> noPropResourceKeys) { |
| |
| return getCreateTasks( |
| anyUtilsFactory.getInstance(kind).dao().authFind(key), |
| null, |
| enable, |
| propByRes, |
| null, |
| vAttrs, |
| noPropResourceKeys); |
| } |
| |
| @Override |
| public List<PropagationTaskInfo> getUserCreateTasks( |
| final String key, |
| final String password, |
| final Boolean enable, |
| final PropagationByResource<String> propByRes, |
| final PropagationByResource<Pair<String, String>> propByLinkedAccount, |
| final Collection<Attr> vAttrs, |
| final Collection<String> noPropResourceKeys) { |
| |
| return getCreateTasks( |
| anyUtilsFactory.getInstance(AnyTypeKind.USER).dao().authFind(key), |
| password, |
| enable, |
| propByRes, |
| propByLinkedAccount, |
| vAttrs, |
| noPropResourceKeys); |
| } |
| |
| protected List<PropagationTaskInfo> getCreateTasks( |
| final Any<?> any, |
| final String password, |
| final Boolean enable, |
| final PropagationByResource<String> propByRes, |
| final PropagationByResource<Pair<String, String>> propByLinkedAccount, |
| final Collection<Attr> vAttrs, |
| final Collection<String> noPropResourceKeys) { |
| |
| if ((propByRes == null || propByRes.isEmpty()) |
| && (propByLinkedAccount == null || propByLinkedAccount.isEmpty())) { |
| |
| return List.of(); |
| } |
| |
| if (noPropResourceKeys != null) { |
| if (propByRes != null) { |
| propByRes.get(ResourceOperation.CREATE).removeAll(noPropResourceKeys); |
| } |
| |
| if (propByLinkedAccount != null) { |
| propByLinkedAccount.get(ResourceOperation.CREATE). |
| removeIf(account -> noPropResourceKeys.contains(account.getLeft())); |
| } |
| } |
| |
| return createTasks(any, password, true, enable, propByRes, propByLinkedAccount, vAttrs); |
| } |
| |
| @Override |
| public List<PropagationTaskInfo> getUpdateTasks( |
| final AnyTypeKind kind, |
| final String key, |
| final boolean changePwd, |
| final Boolean enable, |
| final PropagationByResource<String> propByRes, |
| final PropagationByResource<Pair<String, String>> propByLinkedAccount, |
| final Collection<Attr> vAttrs, |
| final Collection<String> noPropResourceKeys) { |
| |
| return getUpdateTasks( |
| anyUtilsFactory.getInstance(kind).dao().authFind(key), |
| null, |
| changePwd, |
| enable, |
| propByRes, |
| propByLinkedAccount, |
| vAttrs, |
| noPropResourceKeys); |
| } |
| |
| @Override |
| public List<PropagationTaskInfo> getUserUpdateTasks( |
| final UserWorkflowResult<Pair<UserUR, Boolean>> wfResult, |
| final boolean changePwd, |
| final Collection<String> noPropResourceKeys) { |
| |
| return getUpdateTasks( |
| anyUtilsFactory.getInstance(AnyTypeKind.USER).dao().authFind(wfResult.getResult().getLeft().getKey()), |
| wfResult.getResult().getLeft().getPassword() == null |
| ? null |
| : wfResult.getResult().getLeft().getPassword().getValue(), |
| changePwd, |
| wfResult.getResult().getRight(), |
| wfResult.getPropByRes(), |
| wfResult.getPropByLinkedAccount(), |
| wfResult.getResult().getLeft().getVirAttrs(), |
| noPropResourceKeys); |
| } |
| |
| @Override |
| public List<PropagationTaskInfo> getUserUpdateTasks(final UserWorkflowResult<Pair<UserUR, Boolean>> wfResult) { |
| UserUR userUR = wfResult.getResult().getLeft(); |
| |
| // Propagate password update only to requested resources |
| List<PropagationTaskInfo> tasks; |
| if (userUR.getPassword() == null) { |
| // a. no specific password propagation request: generate propagation tasks for any resource associated |
| tasks = getUserUpdateTasks(wfResult, false, null); |
| } else { |
| tasks = new ArrayList<>(); |
| |
| // b. generate the propagation task list in two phases: first the ones containing password, |
| // then the rest (with no password) |
| UserWorkflowResult<Pair<UserUR, Boolean>> pwdWFResult = new UserWorkflowResult<>( |
| wfResult.getResult(), |
| new PropagationByResource<>(), |
| wfResult.getPropByLinkedAccount(), |
| wfResult.getPerformedTasks()); |
| |
| Set<String> pwdResourceNames = new HashSet<>(userUR.getPassword().getResources()); |
| Collection<String> allResourceNames = anyUtilsFactory.getInstance(AnyTypeKind.USER). |
| dao().findAllResourceKeys(userUR.getKey()); |
| pwdResourceNames.retainAll(allResourceNames); |
| |
| pwdWFResult.getPropByRes().addAll(ResourceOperation.UPDATE, pwdResourceNames); |
| if (!pwdWFResult.getPropByRes().isEmpty()) { |
| Set<String> toBeExcluded = new HashSet<>(allResourceNames); |
| toBeExcluded.addAll(userUR.getResources().stream(). |
| map(AbstractPatchItem::getValue).collect(Collectors.toList())); |
| toBeExcluded.removeAll(pwdResourceNames); |
| |
| tasks.addAll(getUserUpdateTasks(pwdWFResult, true, toBeExcluded)); |
| } |
| |
| UserWorkflowResult<Pair<UserUR, Boolean>> noPwdWFResult = new UserWorkflowResult<>( |
| wfResult.getResult(), |
| new PropagationByResource<>(), |
| new PropagationByResource<>(), |
| wfResult.getPerformedTasks()); |
| |
| noPwdWFResult.getPropByRes().merge(wfResult.getPropByRes()); |
| noPwdWFResult.getPropByRes().removeAll(pwdResourceNames); |
| noPwdWFResult.getPropByRes().purge(); |
| if (!noPwdWFResult.getPropByRes().isEmpty()) { |
| tasks.addAll(getUserUpdateTasks(noPwdWFResult, false, pwdResourceNames)); |
| } |
| |
| tasks = tasks.stream().distinct().collect(Collectors.toList()); |
| } |
| |
| return tasks; |
| } |
| |
| protected List<PropagationTaskInfo> getUpdateTasks( |
| final Any<?> any, |
| final String password, |
| final boolean changePwd, |
| final Boolean enable, |
| final PropagationByResource<String> propByRes, |
| final PropagationByResource<Pair<String, String>> propByLinkedAccount, |
| final Collection<Attr> vAttrs, |
| final Collection<String> noPropResourceKeys) { |
| |
| if (noPropResourceKeys != null) { |
| if (propByRes != null) { |
| propByRes.removeAll(noPropResourceKeys); |
| } |
| |
| if (propByLinkedAccount != null) { |
| propByLinkedAccount.get(ResourceOperation.CREATE). |
| removeIf(account -> noPropResourceKeys.contains(account.getLeft())); |
| propByLinkedAccount.get(ResourceOperation.UPDATE). |
| removeIf(account -> noPropResourceKeys.contains(account.getLeft())); |
| propByLinkedAccount.get(ResourceOperation.DELETE). |
| removeIf(account -> noPropResourceKeys.contains(account.getLeft())); |
| } |
| } |
| |
| return createTasks( |
| any, |
| password, |
| changePwd, |
| enable, |
| Optional.ofNullable(propByRes).orElseGet(PropagationByResource::new), |
| propByLinkedAccount, |
| vAttrs); |
| } |
| |
| @Override |
| public List<PropagationTaskInfo> getDeleteTasks( |
| final AnyTypeKind kind, |
| final String key, |
| final PropagationByResource<String> propByRes, |
| final PropagationByResource<Pair<String, String>> propByLinkedAccount, |
| final Collection<String> noPropResourceKeys) { |
| |
| return getDeleteTasks( |
| anyUtilsFactory.getInstance(kind).dao().authFind(key), |
| propByRes, propByLinkedAccount, noPropResourceKeys); |
| } |
| |
| protected List<PropagationTaskInfo> getDeleteTasks( |
| final Any<?> any, |
| final PropagationByResource<String> propByRes, |
| final PropagationByResource<Pair<String, String>> propByLinkedAccount, |
| final Collection<String> noPropResourceKeys) { |
| |
| PropagationByResource<String> localPropByRes = new PropagationByResource<>(); |
| |
| if (propByRes == null || propByRes.isEmpty()) { |
| localPropByRes.addAll( |
| ResourceOperation.DELETE, |
| anyUtilsFactory.getInstance(any).dao().findAllResourceKeys(any.getKey())); |
| } else { |
| localPropByRes.merge(propByRes); |
| } |
| |
| if (noPropResourceKeys != null) { |
| localPropByRes.removeAll(noPropResourceKeys); |
| |
| if (propByLinkedAccount != null) { |
| propByLinkedAccount.get(ResourceOperation.CREATE). |
| removeIf(account -> noPropResourceKeys.contains(account.getLeft())); |
| propByLinkedAccount.get(ResourceOperation.UPDATE). |
| removeIf(account -> noPropResourceKeys.contains(account.getLeft())); |
| propByLinkedAccount.get(ResourceOperation.DELETE). |
| removeIf(account -> noPropResourceKeys.contains(account.getLeft())); |
| } |
| } |
| |
| return createTasks(any, null, false, false, localPropByRes, propByLinkedAccount, null); |
| } |
| |
| @Override |
| public PropagationTaskInfo newTask( |
| final DerAttrHandler derAttrHandler, |
| final Any<?> any, |
| final ExternalResource resource, |
| final ResourceOperation operation, |
| final Provision provision, |
| final Stream<? extends Item> mappingItems, |
| final Pair<String, Set<Attribute>> preparedAttrs) { |
| |
| PropagationTaskInfo task = new PropagationTaskInfo(resource); |
| task.setObjectClassName(provision.getObjectClass().getObjectClassValue()); |
| task.setAnyTypeKind(any.getType().getKind()); |
| task.setAnyType(any.getType().getKey()); |
| task.setEntityKey(any.getKey()); |
| task.setOperation(operation); |
| task.setConnObjectKey(preparedAttrs.getLeft()); |
| |
| // Check if any of mandatory attributes (in the mapping) is missing or not received any value: |
| // if so, add special attributes that will be evaluated by PropagationTaskExecutor |
| List<String> mandatoryMissing = new ArrayList<>(); |
| List<String> mandatoryNullOrEmpty = new ArrayList<>(); |
| mappingItems.filter(item -> (!item.isConnObjectKey() |
| && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any, derAttrHandler))). |
| forEach(item -> { |
| |
| Attribute attr = AttributeUtil.find(item.getExtAttrName(), preparedAttrs.getRight()); |
| if (attr == null) { |
| mandatoryMissing.add(item.getExtAttrName()); |
| } else if (CollectionUtils.isEmpty(attr.getValue())) { |
| mandatoryNullOrEmpty.add(item.getExtAttrName()); |
| } |
| }); |
| if (!mandatoryMissing.isEmpty()) { |
| preparedAttrs.getRight().add(AttributeBuilder.build( |
| PropagationTaskExecutor.MANDATORY_MISSING_ATTR_NAME, mandatoryMissing)); |
| } |
| if (!mandatoryNullOrEmpty.isEmpty()) { |
| preparedAttrs.getRight().add(AttributeBuilder.build( |
| PropagationTaskExecutor.MANDATORY_NULL_OR_EMPTY_ATTR_NAME, mandatoryNullOrEmpty)); |
| } |
| |
| task.setAttributes(POJOHelper.serialize(preparedAttrs.getRight())); |
| |
| return task; |
| } |
| |
| /** |
| * Create propagation tasks. |
| * |
| * @param any to be provisioned |
| * @param password clear text password to be provisioned |
| * @param changePwd whether password should be included for propagation attributes or not |
| * @param enable whether user must be enabled or not |
| * @param propByRes operation to be performed per resource |
| * @param propByLinkedAccount operation to be performed on linked accounts |
| * @param vAttrs virtual attributes to be set |
| * @return list of propagation tasks created |
| */ |
| protected List<PropagationTaskInfo> createTasks( |
| final Any<?> any, |
| final String password, |
| final boolean changePwd, |
| final Boolean enable, |
| final PropagationByResource<String> propByRes, |
| final PropagationByResource<Pair<String, String>> propByLinkedAccount, |
| final Collection<Attr> vAttrs) { |
| |
| LOG.debug("Provisioning {}:\n{}", any, propByRes); |
| |
| // Avoid duplicates - see javadoc |
| propByRes.purge(); |
| LOG.debug("After purge {}:\n{}", any, propByRes); |
| |
| // Virtual attributes |
| Set<String> virtualResources = new HashSet<>(); |
| virtualResources.addAll(propByRes.get(ResourceOperation.CREATE)); |
| virtualResources.addAll(propByRes.get(ResourceOperation.UPDATE)); |
| virtualResources.addAll(anyUtilsFactory.getInstance(any).dao().findAllResourceKeys(any.getKey())); |
| |
| Map<String, Set<Attribute>> vAttrMap = new HashMap<>(); |
| if (vAttrs != null) { |
| vAttrs.forEach(vAttr -> { |
| VirSchema schema = virSchemaDAO.find(vAttr.getSchema()); |
| if (schema == null) { |
| LOG.warn("Ignoring invalid {} {}", VirSchema.class.getSimpleName(), vAttr.getSchema()); |
| } else if (schema.isReadonly()) { |
| LOG.warn("Ignoring read-only {} {}", VirSchema.class.getSimpleName(), vAttr.getSchema()); |
| } else if (anyUtilsFactory.getInstance(any).dao(). |
| findAllowedSchemas(any, VirSchema.class).contains(schema) |
| && virtualResources.contains(schema.getProvision().getResource().getKey())) { |
| |
| Set<Attribute> values = vAttrMap.get(schema.getProvision().getResource().getKey()); |
| if (values == null) { |
| values = new HashSet<>(); |
| vAttrMap.put(schema.getProvision().getResource().getKey(), values); |
| } |
| values.add(AttributeBuilder.build(schema.getExtAttrName(), vAttr.getValues())); |
| |
| if (!propByRes.contains(ResourceOperation.CREATE, schema.getProvision().getResource().getKey())) { |
| propByRes.add(ResourceOperation.UPDATE, schema.getProvision().getResource().getKey()); |
| } |
| } else { |
| LOG.warn("{} not owned by or {} not allowed for {}", |
| schema.getProvision().getResource(), schema, any); |
| } |
| }); |
| } |
| LOG.debug("With virtual attributes {}:\n{}\n{}", any, propByRes, vAttrMap); |
| |
| List<PropagationTaskInfo> tasks = new ArrayList<>(); |
| |
| propByRes.asMap().forEach((resourceKey, operation) -> { |
| ExternalResource resource = resourceDAO.find(resourceKey); |
| Provision provision = Optional.ofNullable(resource). |
| flatMap(externalResource -> externalResource.getProvision(any.getType())).orElse(null); |
| Stream<? extends Item> mappingItems = provision == null |
| ? Stream.empty() |
| : MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()); |
| |
| if (resource == null) { |
| LOG.error("Invalid resource name specified: {}, ignoring...", resourceKey); |
| } else if (provision == null) { |
| LOG.error("No provision specified on resource {} for type {}, ignoring...", |
| resource, any.getType()); |
| } else if (provision.getMapping() == null || provision.getMapping().getItems().isEmpty()) { |
| LOG.warn("Requesting propagation for {} but no propagation mapping provided for {}", |
| any.getType(), resource); |
| } else { |
| Pair<String, Set<Attribute>> preparedAttrs = |
| mappingManager.prepareAttrsFromAny(any, password, changePwd, enable, provision); |
| if (vAttrMap.containsKey(resourceKey)) { |
| preparedAttrs.getRight().addAll(vAttrMap.get(resourceKey)); |
| } |
| |
| PropagationTaskInfo task = newTask( |
| derAttrHandler, |
| any, |
| resource, |
| operation, |
| provision, |
| mappingItems, |
| preparedAttrs); |
| task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resourceKey)); |
| tasks.add(task); |
| LOG.debug("PropagationTask created: {}", task); |
| } |
| }); |
| |
| if (any instanceof User && propByLinkedAccount != null) { |
| User user = (User) any; |
| propByLinkedAccount.asMap().forEach((accountInfo, operation) -> { |
| LinkedAccount account = user.getLinkedAccount(accountInfo.getLeft(), accountInfo.getRight()). |
| orElse(null); |
| if (account == null && operation == ResourceOperation.DELETE) { |
| account = new DeletingLinkedAccount( |
| user, resourceDAO.find(accountInfo.getLeft()), accountInfo.getRight()); |
| } |
| |
| Provision provision = account == null || account.getResource() == null |
| ? null |
| : account.getResource().getProvision(AnyTypeKind.USER.name()).orElse(null); |
| Stream<? extends Item> mappingItems = provision == null |
| ? Stream.empty() |
| : MappingUtils.getPropagationItems(provision.getMapping().getItems().stream()); |
| |
| if (account == null) { |
| LOG.error("Invalid operation {} on deleted account {} on resource {}, ignoring...", |
| operation, accountInfo.getRight(), accountInfo.getLeft()); |
| } else if (account.getResource() == null) { |
| LOG.error("Invalid resource name specified: {}, ignoring...", accountInfo.getLeft()); |
| } else if (provision == null) { |
| LOG.error("No provision specified on resource {} for type {}, ignoring...", |
| account.getResource(), AnyTypeKind.USER.name()); |
| } else if (provision.getMapping() == null || provision.getMapping().getItems().isEmpty()) { |
| LOG.warn("Requesting propagation for {} but no propagation mapping provided for {}", |
| AnyTypeKind.USER.name(), account.getResource()); |
| } else { |
| PropagationTaskInfo accountTask = newTask( |
| derAttrHandler, |
| user, |
| account.getResource(), |
| operation, |
| provision, |
| mappingItems, |
| Pair.of(account.getConnObjectKeyValue(), |
| mappingManager.prepareAttrsFromLinkedAccount( |
| user, account, password, true, provision))); |
| tasks.add(accountTask); |
| |
| LOG.debug("PropagationTask created for Linked Account {}: {}", |
| account.getConnObjectKeyValue(), accountTask); |
| } |
| }); |
| } |
| |
| return tasks; |
| } |
| |
| @Override |
| public List<PropagationTaskInfo> createTasks( |
| final Realm realm, |
| final PropagationByResource<String> propByRes, |
| final Collection<String> noPropResourceKeys) { |
| |
| if (noPropResourceKeys != null) { |
| propByRes.removeAll(noPropResourceKeys); |
| } |
| |
| LOG.debug("Provisioning {}:\n{}", realm, propByRes); |
| |
| // Avoid duplicates - see javadoc |
| propByRes.purge(); |
| LOG.debug("After purge {}:\n{}", realm, propByRes); |
| |
| List<PropagationTaskInfo> tasks = new ArrayList<>(); |
| |
| propByRes.asMap().forEach((resourceKey, operation) -> { |
| ExternalResource resource = resourceDAO.find(resourceKey); |
| OrgUnit orgUnit = Optional.ofNullable(resource).map(ExternalResource::getOrgUnit).orElse(null); |
| |
| if (resource == null) { |
| LOG.error("Invalid resource name specified: {}, ignoring...", resourceKey); |
| } else if (orgUnit == null) { |
| LOG.error("No orgUnit specified on resource {}, ignoring...", resource); |
| } else if (StringUtils.isBlank(orgUnit.getConnObjectLink())) { |
| LOG.warn("Requesting propagation for {} but no ConnObjectLink provided for {}", |
| realm.getFullPath(), resource); |
| } else { |
| PropagationTaskInfo task = new PropagationTaskInfo(resource); |
| task.setObjectClassName(orgUnit.getObjectClass().getObjectClassValue()); |
| task.setEntityKey(realm.getKey()); |
| task.setOperation(operation); |
| task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey())); |
| |
| Pair<String, Set<Attribute>> preparedAttrs = mappingManager.prepareAttrsFromRealm(realm, orgUnit); |
| task.setConnObjectKey(preparedAttrs.getLeft()); |
| task.setAttributes(POJOHelper.serialize(preparedAttrs.getRight())); |
| |
| tasks.add(task); |
| |
| LOG.debug("PropagationTask created: {}", task); |
| } |
| }); |
| |
| return tasks; |
| } |
| } |