This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 4_0_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/4_0_X by this push:
new 7a5c6978d8 Adjusting Realm propagation
7a5c6978d8 is described below
commit 7a5c6978d812dea219eef355aff086529347b059
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Mon Dec 1 15:46:32 2025 +0100
Adjusting Realm propagation
---
.../api/rules/PushCorrelationRule.java | 8 +--
.../core/provisioning/java/data/AnyDataBinder.java | 28 ----------
.../java/data/AttributableDataBinder.java | 31 +++++++++++
.../java/data/RealmDataBinderImpl.java | 60 +++++++++++++++++-----
.../java/pushpull/DefaultPushCorrelationRule.java | 4 +-
.../java/pushpull/OutboundMatcher.java | 2 +-
.../core/provisioning/java/utils/MappingUtils.java | 6 +--
7 files changed, 87 insertions(+), 52 deletions(-)
diff --git
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PushCorrelationRule.java
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PushCorrelationRule.java
index 8700509985..a614b50990 100644
---
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PushCorrelationRule.java
+++
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/rules/PushCorrelationRule.java
@@ -18,7 +18,7 @@
*/
package org.apache.syncope.core.provisioning.api.rules;
-import java.util.function.BiFunction;
+import java.util.function.Function;
import org.apache.syncope.common.lib.policy.PushCorrelationRuleConf;
import org.apache.syncope.common.lib.to.Provision;
import org.apache.syncope.core.persistence.api.entity.Any;
@@ -36,8 +36,8 @@ public interface PushCorrelationRule {
/**
* Default FIQL builder using __UID__.
*/
- BiFunction<ConnectorObject, Provision, String> DEFAULT_FIQL_BUILDER =
- (connectorObject, provision) -> Uid.NAME + "==" +
connectorObject.getUid().getUidValue();
+ Function<ConnectorObject, String> DEFAULT_FIQL_BUILDER =
+ connectorObject -> Uid.NAME + "==" +
connectorObject.getUid().getUidValue();
default void setConf(PushCorrelationRuleConf conf) {
}
@@ -62,6 +62,6 @@ public interface PushCorrelationRule {
* @return fiql
*/
default String getFIQL(ConnectorObject connectorObject, Provision
provision) {
- return DEFAULT_FIQL_BUILDER.apply(connectorObject, provision);
+ return DEFAULT_FIQL_BUILDER.apply(connectorObject);
}
}
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java
index e46db5fe01..c14fcec373 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyDataBinder.java
@@ -47,7 +47,6 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.ResourceOperation;
import
org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager;
import org.apache.syncope.core.persistence.api.dao.AllowedSchemas;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
@@ -82,7 +81,6 @@ import org.apache.syncope.core.provisioning.api.IntAttrName;
import org.apache.syncope.core.provisioning.api.IntAttrNameParser;
import org.apache.syncope.core.provisioning.api.MappingManager;
import org.apache.syncope.core.provisioning.api.PlainAttrGetter;
-import org.apache.syncope.core.provisioning.api.PropagationByResource;
import org.apache.syncope.core.provisioning.api.jexl.JexlTools;
import org.apache.syncope.core.provisioning.java.pushpull.OutboundMatcher;
import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
@@ -505,32 +503,6 @@ abstract class AnyDataBinder extends
AttributableDataBinder {
}
}
- protected PropagationByResource<String> propByRes(
- final Map<String, ConnObject> before,
- final Map<String, ConnObject> after) {
-
- PropagationByResource<String> propByRes = new
PropagationByResource<>();
-
- after.forEach((resource, connObject) -> {
- if (before.containsKey(resource)) {
- ConnObject beforeObject = before.get(resource);
- if (!beforeObject.equals(connObject)) {
- propByRes.add(ResourceOperation.UPDATE, resource);
-
- beforeObject.getAttr(Uid.NAME).map(attr ->
attr.getValues().getFirst()).
- ifPresent(value ->
propByRes.addOldConnObjectKey(resource, value));
- }
- } else {
- propByRes.add(ResourceOperation.CREATE, resource);
- }
- });
- propByRes.addAll(
- ResourceOperation.DELETE,
- before.keySet().stream().filter(resource ->
!after.containsKey(resource)).collect(Collectors.toSet()));
-
- return propByRes;
- }
-
protected void fill(
final AnyTO anyTO,
final Any any,
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java
index eac3acf877..8480cade31 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AttributableDataBinder.java
@@ -22,9 +22,12 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AttributableTO;
+import org.apache.syncope.common.lib.to.ConnObject;
+import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.core.persistence.api.attrvalue.DropdownValueProvider;
import
org.apache.syncope.core.persistence.api.attrvalue.InvalidPlainAttrValueException;
import
org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager;
@@ -35,8 +38,10 @@ import
org.apache.syncope.core.persistence.api.entity.PlainSchema;
import org.apache.syncope.core.provisioning.api.DerAttrHandler;
import org.apache.syncope.core.provisioning.api.IntAttrNameParser;
import org.apache.syncope.core.provisioning.api.MappingManager;
+import org.apache.syncope.core.provisioning.api.PropagationByResource;
import org.apache.syncope.core.provisioning.api.jexl.JexlTools;
import org.apache.syncope.core.spring.implementation.ImplementationManager;
+import org.identityconnectors.framework.common.objects.Uid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -169,4 +174,30 @@ abstract class AttributableDataBinder {
}
});
}
+
+ protected PropagationByResource<String> propByRes(
+ final Map<String, ConnObject> before,
+ final Map<String, ConnObject> after) {
+
+ PropagationByResource<String> propByRes = new
PropagationByResource<>();
+
+ after.forEach((resource, connObject) -> {
+ if (before.containsKey(resource)) {
+ ConnObject beforeObject = before.get(resource);
+ if (!beforeObject.equals(connObject)) {
+ propByRes.add(ResourceOperation.UPDATE, resource);
+
+ beforeObject.getAttr(Uid.NAME).map(attr ->
attr.getValues().getFirst()).
+ ifPresent(value ->
propByRes.addOldConnObjectKey(resource, value));
+ }
+ } else {
+ propByRes.add(ResourceOperation.CREATE, resource);
+ }
+ });
+ propByRes.addAll(
+ ResourceOperation.DELETE,
+ before.keySet().stream().filter(resource ->
!after.containsKey(resource)).collect(Collectors.toSet()));
+
+ return propByRes;
+ }
}
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
index 2e3de205da..ab9572e14c 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RealmDataBinderImpl.java
@@ -20,15 +20,18 @@ package org.apache.syncope.core.provisioning.java.data;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.Attr;
import org.apache.syncope.common.lib.SyncopeClientCompositeException;
import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.ConnObject;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.ClientExceptionType;
-import org.apache.syncope.common.lib.types.ResourceOperation;
import
org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager;
import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
@@ -59,7 +62,13 @@ import
org.apache.syncope.core.provisioning.api.PropagationByResource;
import org.apache.syncope.core.provisioning.api.data.RealmDataBinder;
import org.apache.syncope.core.provisioning.api.jexl.JexlTools;
import org.apache.syncope.core.provisioning.api.jexl.TemplateUtils;
+import org.apache.syncope.core.provisioning.api.rules.PushCorrelationRule;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ConnectorObjectBuilder;
+import org.identityconnectors.framework.common.objects.Uid;
public class RealmDataBinderImpl extends AttributableDataBinder implements
RealmDataBinder {
@@ -281,36 +290,59 @@ public class RealmDataBinderImpl extends
AttributableDataBinder implements Realm
return realm;
}
+ protected Map<String, ConnObject> onResources(final Realm realm) {
+ Map<String, ConnObject> onResources = new HashMap<>();
+
+ realm.getResources().forEach(resource ->
Optional.ofNullable(resource.getOrgUnit()).
+ ifPresent(orgUnit ->
orgUnit.getConnObjectKeyItem().ifPresent(keyItem -> {
+
+ MappingManager.PreparedAttrs prepared =
mappingManager.prepareAttrsFromRealm(realm, resource);
+
+ ConnObject connObjectTO;
+ if (StringUtils.isBlank(prepared.connObjectLink())) {
+ connObjectTO = ConnObjectUtils.getConnObjectTO(null,
prepared.attributes());
+ } else {
+ ConnectorObject connectorObject = new ConnectorObjectBuilder().
+ addAttributes(prepared.attributes()).
+ addAttribute(new Uid(prepared.connObjectLink())).
+
addAttribute(AttributeBuilder.build(keyItem.getExtAttrName(),
prepared.connObjectLink())).
+ build();
+
+ connObjectTO = ConnObjectUtils.getConnObjectTO(
+
PushCorrelationRule.DEFAULT_FIQL_BUILDER.apply(connectorObject),
+ connectorObject.getAttributes());
+ }
+
+ onResources.put(resource.getKey(), connObjectTO);
+ })));
+
+ return onResources;
+ }
+
@Override
public PropagationByResource<String> update(final Realm realm, final
RealmTO realmTO) {
+ // Save projection on Resources (before update)
+ Map<String, ConnObject> beforeOnResources = onResources(realm);
+
realm.setParent(Optional.ofNullable(realmTO.getParent()).flatMap(realmDAO::findById).orElse(null));
SyncopeClientCompositeException scce =
SyncopeClientException.buildComposite();
bind(realm, realmTO, scce);
- PropagationByResource<String> propByRes = new
PropagationByResource<>();
realmTO.getResources().forEach(key ->
resourceDAO.findById(key).ifPresentOrElse(
- resource -> {
- realm.add(resource);
- propByRes.add(ResourceOperation.CREATE, resource.getKey());
- },
+ realm::add,
() -> LOG.debug("Invalid {} {}, ignoring...",
ExternalResource.class.getSimpleName(), key)));
// remove all resources not contained in the TO
- realm.getResources().removeIf(resource -> {
- boolean contained =
realmTO.getResources().contains(resource.getKey());
- if (!contained) {
- propByRes.add(ResourceOperation.DELETE, resource.getKey());
- }
- return !contained;
- });
+ realm.getResources().removeIf(resource ->
!realmTO.getResources().contains(resource.getKey()));
SyncopeClientException requiredValuesMissing =
checkMandatoryOnResources(realm);
if (!requiredValuesMissing.isEmpty()) {
scce.addException(requiredValuesMissing);
}
- return propByRes;
+ // Build final information for next stage (propagation)
+ return propByRes(beforeOnResources, onResources(realm));
}
@Override
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushCorrelationRule.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushCorrelationRule.java
index 107b96665e..1f6f066c3c 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushCorrelationRule.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultPushCorrelationRule.java
@@ -60,8 +60,8 @@ public class DefaultPushCorrelationRule implements
PushCorrelationRule {
@Override
public void setConf(final PushCorrelationRuleConf conf) {
- if (conf instanceof DefaultPushCorrelationRuleConf) {
- this.conf = DefaultPushCorrelationRuleConf.class.cast(conf);
+ if (conf instanceof final DefaultPushCorrelationRuleConf
defaultPushCorrelationRuleConf) {
+ this.conf = defaultPushCorrelationRuleConf;
} else {
throw new IllegalArgumentException(
DefaultPushCorrelationRuleConf.class.getName() + "
expected, got " + conf.getClass().getName());
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
index c0020ea25e..ebd0157255 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/OutboundMatcher.java
@@ -105,7 +105,7 @@ public class OutboundMatcher {
return rule(resource, provision).
map(rule -> rule.getFIQL(connectorObject, provision)).
- orElseGet(() ->
PushCorrelationRule.DEFAULT_FIQL_BUILDER.apply(connectorObject, provision));
+ orElseGet(() ->
PushCorrelationRule.DEFAULT_FIQL_BUILDER.apply(connectorObject));
}
public List<ConnectorObject> match(
diff --git
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index 79af4dd636..9eb69b097a 100644
---
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -29,7 +29,7 @@ import java.util.stream.Stream;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.to.Item;
-import org.apache.syncope.common.lib.to.Mapping;
+import org.apache.syncope.common.lib.to.ItemContainer;
import org.apache.syncope.common.lib.to.Provision;
import org.apache.syncope.common.lib.types.MappingPurpose;
import org.apache.syncope.core.persistence.api.ApplicationContextProvider;
@@ -55,8 +55,8 @@ public final class MappingUtils {
public static Optional<Item> getConnObjectKeyItem(final Provision
provision) {
return Optional.ofNullable(provision).
flatMap(p -> Optional.ofNullable(p.getMapping())).
- map(Mapping::getConnObjectKeyItem).
- orElseGet(Optional::empty);
+ map(ItemContainer::getConnObjectKeyItem).
+ orElseGet(Optional::empty);
}
public static Stream<Item> getPropagationItems(final Stream<Item> items) {