http://git-wip-us.apache.org/repos/asf/syncope/blob/b47d4328/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
index 267a6a2..fe826f4 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
@@ -19,12 +19,10 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.core.provisioning.api.data.PolicyDataBinder;
 import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
 import org.apache.syncope.common.lib.policy.AccountPolicyTO;
 import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
-import org.apache.syncope.common.lib.policy.PullPolicySpec;
 import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
@@ -39,6 +37,7 @@ import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.policy.CorrelationRule;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -133,24 +132,35 @@ public class PolicyDataBinderImpl implements 
PolicyDataBinder {
             PullPolicy pullPolicy = PullPolicy.class.cast(result);
             PullPolicyTO pullPolicyTO = PullPolicyTO.class.cast(policyTO);
 
-            PullPolicySpec pullPolicySpec = 
SerializationUtils.clone(pullPolicyTO.getSpecification());
-            pullPolicySpec.getCorrelationRules().clear();
-            
pullPolicyTO.getSpecification().getCorrelationRules().entrySet().forEach(entry 
-> {
+            
pullPolicy.setConflictResolutionAction(pullPolicyTO.getConflictResolutionAction());
+
+            pullPolicyTO.getCorrelationRules().entrySet().forEach(entry -> {
                 AnyType anyType = anyTypeDAO.find(entry.getKey());
                 if (anyType == null) {
-                    LOG.debug("Invalid " + AnyType.class.getSimpleName() + " 
{}, ignoring...",
-                            entry.getKey());
+                    LOG.debug("Invalid AnyType {} specified, ignoring...", 
entry.getKey());
                 } else {
-                    Implementation rule = 
implementationDAO.find(entry.getValue());
-                    if (rule == null) {
+                    CorrelationRule correlationRule = 
pullPolicy.getCorrelationRule(anyType).orElse(null);
+                    if (correlationRule == null) {
+                        correlationRule = 
entityFactory.newEntity(CorrelationRule.class);
+                        
correlationRule.setAnyType(anyTypeDAO.find(entry.getKey()));
+                        correlationRule.setPullPolicy(pullPolicy);
+                        pullPolicy.add(correlationRule);
+                    }
+
+                    Implementation implementation = 
implementationDAO.find(entry.getValue());
+                    if (implementation == null) {
                         LOG.debug("Invalid " + 
Implementation.class.getSimpleName() + " {}, ignoring...",
                                 entry.getValue());
                     } else {
-                        
pullPolicySpec.getCorrelationRules().put(anyType.getKey(), rule.getKey());
+                        correlationRule.setImplementation(implementation);
                     }
                 }
             });
-            pullPolicy.setSpecification(pullPolicySpec);
+            // remove all rules not contained in the TO
+            pullPolicy.getCorrelationRules().removeAll(
+                    pullPolicy.getCorrelationRules().stream().filter(anyFilter
+                            -> 
!pullPolicyTO.getCorrelationRules().containsKey(anyFilter.getAnyType().getKey())).
+                            collect(Collectors.toList()));
         }
 
         if (result != null) {
@@ -199,8 +209,14 @@ public class PolicyDataBinderImpl implements 
PolicyDataBinder {
             accountPolicyTO.getPassthroughResources().addAll(
                     
accountPolicy.getResources().stream().map(Entity::getKey).collect(Collectors.toList()));
         } else if (policy instanceof PullPolicy) {
-            policyTO = (T) new PullPolicyTO();
-            ((PullPolicyTO) policyTO).setSpecification(((PullPolicy) 
policy).getSpecification());
+            PullPolicy pullPolicy = PullPolicy.class.cast(policy);
+            PullPolicyTO pullPolicyTO = new PullPolicyTO();
+            policyTO = (T) pullPolicyTO;
+
+            pullPolicyTO.setConflictResolutionAction(((PullPolicy) 
policy).getConflictResolutionAction());
+            pullPolicy.getCorrelationRules().forEach(rule -> {
+                
pullPolicyTO.getCorrelationRules().put(rule.getAnyType().getKey(), 
rule.getImplementation().getKey());
+            });
         }
 
         if (policyTO != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/b47d4328/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
index 8f3ee71..05d7112 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java
@@ -28,7 +28,7 @@ import java.util.Optional;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.collections.IteratorChain;
-import org.apache.syncope.common.lib.policy.PullPolicySpec;
+import org.apache.syncope.common.lib.types.ConflictResolutionAction;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -38,7 +38,6 @@ import 
org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 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.task.ProvisioningTask;
 import org.apache.syncope.core.provisioning.api.Connector;
 import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
 import org.quartz.JobExecutionException;
@@ -182,7 +181,9 @@ public class PullJobDelegate extends 
AbstractProvisioningJobDelegate<PullTask> i
         profile = new ProvisioningProfile<>(connector, pullTask);
         profile.getActions().addAll(actions);
         profile.setDryRun(dryRun);
-        
profile.setResAct(getPullPolicySpec(pullTask).getConflictResolutionAction());
+        profile.setResAct(pullTask.getResource().getPullPolicy() == null
+                ? ConflictResolutionAction.IGNORE
+                : 
pullTask.getResource().getPullPolicy().getConflictResolutionAction());
 
         latestSyncTokens.clear();
 
@@ -327,19 +328,4 @@ public class PullJobDelegate extends 
AbstractProvisioningJobDelegate<PullTask> i
         LOG.debug("Pull result: {}", result);
         return result;
     }
-
-    protected PullPolicySpec getPullPolicySpec(final ProvisioningTask task) {
-        PullPolicySpec pullPolicySpec;
-
-        if (task instanceof PullTask) {
-            pullPolicySpec = task.getResource().getPullPolicy() == null
-                    ? null
-                    : task.getResource().getPullPolicy().getSpecification();
-        } else {
-            pullPolicySpec = null;
-        }
-
-        // step required because the call <policy>.getSpecification() could 
return a null value
-        return pullPolicySpec == null ? new PullPolicySpec() : pullPolicySpec;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b47d4328/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
index 44c80bd..32e2118 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullUtils.java
@@ -24,7 +24,6 @@ import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.policy.PullPolicySpec;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import 
org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
@@ -40,12 +39,12 @@ import 
org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.Entity;
-import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.policy.CorrelationRule;
 import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
@@ -274,31 +273,6 @@ public class PullUtils {
                 map(Entity::getKey).collect(Collectors.toList());
     }
 
-    private PullCorrelationRule getCorrelationRule(final Provision provision, 
final PullPolicySpec policySpec) {
-        PullCorrelationRule rule = null;
-
-        String pullCorrelationRule = 
policySpec.getCorrelationRules().get(provision.getAnyType().getKey());
-        if (pullCorrelationRule != null) {
-            if (pullCorrelationRule.charAt(0) == '[') {
-                rule = new PlainAttrsPullCorrelationRule(
-                        POJOHelper.deserialize(pullCorrelationRule, 
String[].class), provision);
-            } else {
-                Implementation impl = 
implementationDAO.find(pullCorrelationRule);
-                if (impl == null) {
-                    LOG.error("Could not find any Implementation matching 
'{}'", pullCorrelationRule);
-                } else {
-                    try {
-                        rule = ImplementationManager.build(impl);
-                    } catch (Exception e) {
-                        LOG.error("While building {}", impl, e);
-                    }
-                }
-            }
-        }
-
-        return rule;
-    }
-
     /**
      * Find any objects based on mapped uid value (or previous uid value, if 
updated).
      *
@@ -314,20 +288,28 @@ public class PullUtils {
             final Provision provision,
             final AnyUtils anyUtils) {
 
-        PullPolicySpec pullPolicySpec = null;
-        if (provision.getResource().getPullPolicy() != null) {
-            pullPolicySpec = 
provision.getResource().getPullPolicy().getSpecification();
-        }
+        Optional<? extends CorrelationRule> correlationRule = 
provision.getResource().getPullPolicy() == null
+                ? Optional.empty()
+                : 
provision.getResource().getPullPolicy().getCorrelationRule(provision.getAnyType());
 
-        PullCorrelationRule pullRule = null;
-        if (pullPolicySpec != null) {
-            pullRule = getCorrelationRule(provision, pullPolicySpec);
+        PullCorrelationRule rule = null;
+        if (correlationRule.isPresent()) {
+            if (correlationRule.get().getImplementation().getBody().charAt(0) 
== '[') {
+                rule = new 
PlainAttrsPullCorrelationRule(POJOHelper.deserialize(
+                        correlationRule.get().getImplementation().getBody(), 
String[].class), provision);
+            } else {
+                try {
+                    rule = 
ImplementationManager.build(correlationRule.get().getImplementation());
+                } catch (Exception e) {
+                    LOG.error("While building {}", 
correlationRule.get().getImplementation(), e);
+                }
+            }
         }
 
         try {
-            return pullRule == null
+            return rule == null
                     ? findByConnObjectKeyItem(uid, provision, anyUtils)
-                    : findByCorrelationRule(connObj, pullRule, 
anyUtils.getAnyTypeKind());
+                    : findByCorrelationRule(connObj, rule, 
anyUtils.getAnyTypeKind());
         } catch (RuntimeException e) {
             return Collections.<String>emptyList();
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b47d4328/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java
index fe8968e..b4e243d 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java
@@ -26,10 +26,10 @@ import java.util.UUID;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ImplementationTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.ImplementationEngine;
 import org.apache.syncope.common.lib.types.ImplementationType;
-import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ImplementationService;
 import org.apache.syncope.fit.AbstractITCase;
 import org.apache.syncope.fit.core.reference.TestPullActions;
@@ -65,9 +65,45 @@ public class ImplementationITCase extends AbstractITCase {
         ImplementationTO actual =
                 getObject(response.getLocation(), ImplementationService.class, 
ImplementationTO.class);
         assertNotNull(actual);
-
-        
implementationTO.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY));
         assertEquals(actual, implementationTO);
     }
 
+    @Test
+    public void delete() {
+        ImplementationTO implementationTO = new ImplementationTO();
+        implementationTO.setKey(UUID.randomUUID().toString());
+        implementationTO.setEngine(ImplementationEngine.JAVA);
+        implementationTO.setType(ImplementationType.PULL_ACTIONS);
+        implementationTO.setBody(TestPullActions.class.getName());
+
+        implementationService.create(implementationTO);
+
+        PullTaskTO pullTask = 
taskService.read(AbstractTaskITCase.PULL_TASK_KEY, false);
+        assertNotNull(pullTask);
+
+        int before = pullTask.getActions().size();
+
+        pullTask.getActions().add(implementationTO.getKey());
+        taskService.update(pullTask);
+
+        pullTask = taskService.read(AbstractTaskITCase.PULL_TASK_KEY, false);
+        assertNotNull(pullTask);
+
+        int after = pullTask.getActions().size();
+        assertEquals(before + 1, after);
+
+        // fails because the implementation is used
+        try {
+            implementationService.delete(implementationTO.getKey());
+            fail("Unexpected");
+        } catch (SyncopeClientException e) {
+            assertEquals(e.getType(), ClientExceptionType.InUse);
+        }
+
+        pullTask.getActions().remove(implementationTO.getKey());
+        taskService.update(pullTask);
+
+        implementationService.delete(implementationTO.getKey());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/b47d4328/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
index 052cc3d..a077358 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java
@@ -38,10 +38,8 @@ import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
 import org.apache.syncope.common.lib.policy.PullPolicyTO;
 import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
 import org.apache.syncope.common.lib.types.PolicyType;
-import org.apache.syncope.common.lib.policy.PullPolicySpec;
 import org.apache.syncope.common.lib.to.ImplementationTO;
 import org.apache.syncope.common.lib.types.ImplementationEngine;
 import org.apache.syncope.common.lib.types.ImplementationType;
@@ -72,11 +70,8 @@ public class PolicyITCase extends AbstractITCase {
         }
         assertNotNull(corrRule);
 
-        PullPolicySpec spec = new PullPolicySpec();
-        spec.getCorrelationRules().put(AnyTypeKind.USER.name(), 
corrRule.getKey());
-
         PullPolicyTO policy = new PullPolicyTO();
-        policy.setSpecification(spec);
+        policy.getCorrelationRules().put(AnyTypeKind.USER.name(), 
corrRule.getKey());
         policy.setDescription("Pull policy");
 
         return policy;
@@ -117,26 +112,10 @@ public class PolicyITCase extends AbstractITCase {
     }
 
     @Test
-    public void createMissingDescription() {
-        PullPolicyTO policy = new PullPolicyTO();
-        policy.setSpecification(new PullPolicySpec());
-
-        try {
-            createPolicy(policy);
-            fail("This should not happen");
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
-        }
-    }
-
-    @Test
     public void create() throws IOException {
-        PullPolicyTO policy = buildPullPolicyTO();
-
-        PullPolicyTO policyTO = createPolicy(policy);
-
+        PullPolicyTO policyTO = createPolicy(buildPullPolicyTO());
         assertNotNull(policyTO);
-        assertEquals("TestPullRule", 
policyTO.getSpecification().getCorrelationRules().get(AnyTypeKind.USER.name()));
+        assertEquals("TestPullRule", 
policyTO.getCorrelationRules().get(AnyTypeKind.USER.name()));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/b47d4328/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
index 848b97c..273509a 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
@@ -772,7 +772,7 @@ public class PullTaskITCase extends AbstractTaskITCase {
         assertNotNull(corrRule);
 
         PullPolicyTO policyTO = 
policyService.read("9454b0d7-2610-400a-be82-fc23cf553dd6");
-        
policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), 
corrRule.getKey());
+        policyTO.getCorrelationRules().put(AnyTypeKind.USER.name(), 
corrRule.getKey());
         policyService.update(policyTO);
         // -----------------------------
 

Reply via email to