Repository: syncope
Updated Branches:
  refs/heads/2_0_X 6fd572119 -> a07f3b948
  refs/heads/master 24f789932 -> 44a5e1da7


[SYNCOPE-1299] Reworking REST service definition to allow more flexibility


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/a07f3b94
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/a07f3b94
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/a07f3b94

Branch: refs/heads/2_0_X
Commit: a07f3b948c34222d98509d1f11b20f054b392b02
Parents: 6fd5721
Author: Francesco Chicchiriccò <ilgro...@apache.org>
Authored: Fri Apr 13 11:14:56 2018 +0200
Committer: Francesco Chicchiriccò <ilgro...@apache.org>
Committed: Fri Apr 13 11:14:56 2018 +0200

----------------------------------------------------------------------
 .../common/lib/to/ReconciliationRequest.java    | 90 --------------------
 .../common/lib/types/ReconciliationAction.java  | 28 ------
 .../rest/api/service/ReconciliationService.java | 44 ++++++++--
 .../syncope/core/logic/ReconciliationLogic.java | 72 +++++++++-------
 .../api/pushpull/SyncopeSinglePullExecutor.java |  3 +-
 .../api/pushpull/SyncopeSinglePushExecutor.java |  3 +-
 .../pushpull/AbstractSyncopeResultHandler.java  |  1 +
 .../java/pushpull/SinglePullJobDelegate.java    | 44 ++++++++--
 .../java/pushpull/SinglePushJobDelegate.java    | 16 ++--
 .../cxf/service/ReconciliationServiceImpl.java  | 32 +++++--
 .../syncope/fit/core/ReconciliationITCase.java  | 24 +++---
 11 files changed, 171 insertions(+), 186 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReconciliationRequest.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReconciliationRequest.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReconciliationRequest.java
deleted file mode 100644
index d6cae93..0000000
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReconciliationRequest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.common.lib.to;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ReconciliationAction;
-
-public class ReconciliationRequest extends AbstractBaseBean {
-
-    private static final long serialVersionUID = -2592156800185957182L;
-
-    private AnyTypeKind anyTypeKind;
-
-    private String anyKey;
-
-    private String resourceKey;
-
-    private ReconciliationAction action;
-
-    private final List<String> actionsClassNames = new ArrayList<>();
-
-    @JsonProperty(required = true)
-    @XmlElement(required = true)
-    public AnyTypeKind getAnyTypeKind() {
-        return anyTypeKind;
-    }
-
-    public void setAnyTypeKind(final AnyTypeKind anyTypeKind) {
-        this.anyTypeKind = anyTypeKind;
-    }
-
-    @JsonProperty(required = true)
-    @XmlElement(required = true)
-    public String getAnyKey() {
-        return anyKey;
-    }
-
-    public void setAnyKey(final String anyKey) {
-        this.anyKey = anyKey;
-    }
-
-    @JsonProperty(required = true)
-    @XmlElement(required = true)
-    public String getResourceKey() {
-        return resourceKey;
-    }
-
-    public void setResourceKey(final String resourceKey) {
-        this.resourceKey = resourceKey;
-    }
-
-    @JsonProperty(required = true)
-    @XmlElement(required = true)
-    public ReconciliationAction getAction() {
-        return action;
-    }
-
-    public void setAction(final ReconciliationAction action) {
-        this.action = action;
-    }
-
-    @XmlElementWrapper(name = "actionsClassNames")
-    @XmlElement(name = "actionsClassName")
-    @JsonProperty("actionsClassNames")
-    public List<String> getActionsClassNames() {
-        return actionsClassNames;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/common/lib/src/main/java/org/apache/syncope/common/lib/types/ReconciliationAction.java
----------------------------------------------------------------------
diff --git 
a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ReconciliationAction.java
 
b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ReconciliationAction.java
deleted file mode 100644
index 19b68c2..0000000
--- 
a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ReconciliationAction.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.common.lib.types;
-
-import javax.xml.bind.annotation.XmlEnum;
-
-@XmlEnum
-public enum ReconciliationAction {
-    PUSH,
-    PULL
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReconciliationService.java
----------------------------------------------------------------------
diff --git 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReconciliationService.java
 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReconciliationService.java
index ddbbd5d..bfec63c 100644
--- 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReconciliationService.java
+++ 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReconciliationService.java
@@ -19,6 +19,8 @@
 package org.apache.syncope.common.rest.api.service;
 
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
 import io.swagger.annotations.Authorization;
 import javax.validation.constraints.NotNull;
 import javax.ws.rs.Consumes;
@@ -29,7 +31,8 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.to.ReconciliationRequest;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.ReconciliationStatus;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 
@@ -60,13 +63,44 @@ public interface ReconciliationService extends JAXRSService 
{
             @NotNull @QueryParam("resourceKey") String resourceKey);
 
     /**
-     * Perform the required reconciliation action (PUSH or PULL) to the given 
user, group or any object and
-     * External Resource.
+     * Pushes the given user, group or any object in Syncope onto the External 
Resource.
      *
-     * @param request reconciliation request
+     * @param anyTypeKind anyTypeKind
+     * @param anyKey user, group or any object: if value looks like a UUID 
then it is interpreted as key, otherwise as
+     * a (user)name
+     * @param resourceKey resource key
+     * @param pushTask push specification
      */
+    @ApiResponses(
+            @ApiResponse(code = 204, message = "Operation was successful"))
     @POST
+    @Path("push")
     @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, 
MediaType.APPLICATION_XML })
     @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, 
MediaType.APPLICATION_XML })
-    void reconcile(@NotNull ReconciliationRequest request);
+    void push(
+            @NotNull @QueryParam("anyTypeKind") AnyTypeKind anyTypeKind,
+            @NotNull @QueryParam("anyKey") String anyKey,
+            @NotNull @QueryParam("resourceKey") String resourceKey,
+            @NotNull PushTaskTO pushTask);
+
+    /**
+     * Pulls the given user, group or any object from the External Resource 
into Syncope.
+     *
+     * @param anyTypeKind anyTypeKind
+     * @param anyKey user, group or any object: if value looks like a UUID 
then it is interpreted as key, otherwise as
+     * a (user)name
+     * @param resourceKey resource key
+     * @param pullTask pull specification
+     */
+    @ApiResponses(
+            @ApiResponse(code = 204, message = "Operation was successful"))
+    @POST
+    @Path("pull")
+    @Consumes({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, 
MediaType.APPLICATION_XML })
+    @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, 
MediaType.APPLICATION_XML })
+    void pull(
+            @NotNull @QueryParam("anyTypeKind") AnyTypeKind anyTypeKind,
+            @NotNull @QueryParam("anyKey") String anyKey,
+            @NotNull @QueryParam("resourceKey") String resourceKey,
+            @NotNull PullTaskTO pullTask);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
 
b/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
index 7dee27b..58fd708 100644
--- 
a/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
+++ 
b/core/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java
@@ -29,14 +29,14 @@ import org.apache.syncope.common.lib.AbstractBaseBean;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
-import org.apache.syncope.common.lib.to.ReconciliationRequest;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.ReconciliationStatus;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 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.AnyUtils;
@@ -77,9 +77,6 @@ public class ReconciliationLogic extends 
AbstractTransactionalLogic<AbstractBase
     private VirSchemaDAO virSchemaDAO;
 
     @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
     private MappingManager mappingManager;
 
     @Autowired
@@ -187,37 +184,52 @@ public class ReconciliationLogic extends 
AbstractTransactionalLogic<AbstractBase
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.TASK_EXECUTE + "')")
-    public void reconcile(final ReconciliationRequest request) {
-        Pair<Any<?>, Provision> init = init(request.getAnyTypeKind(), 
request.getAnyKey(), request.getResourceKey());
+    public void push(
+            final AnyTypeKind anyTypeKind,
+            final String anyKey,
+            final String resourceKey,
+            final PushTaskTO pushTask) {
+
+        Pair<Any<?>, Provision> init = init(anyTypeKind, anyKey, resourceKey);
 
         SyncopeClientException sce = 
SyncopeClientException.build(ClientExceptionType.Reconciliation);
         try {
-            List<ProvisioningReport> results = null;
-            switch (request.getAction()) {
-                case PUSH:
-                    results = singlePushExecutor.push(
-                            init.getRight(),
-                            
connFactory.getConnector(init.getRight().getResource()),
-                            init.getLeft(),
-                            request.getActionsClassNames());
-                    break;
-
-                case PULL:
-                    results = singlePullExecutor.pull(
-                            init.getRight(),
-                            
connFactory.getConnector(init.getRight().getResource()),
-                            
init.getRight().getMapping().getConnObjectKeyItem().getExtAttrName(),
-                            
mappingManager.getConnObjectKeyValue(init.getLeft(), init.getRight()),
-                            
realmDAO.findByFullPath(init.getLeft().getRealm().getFullPath()),
-                            request.getActionsClassNames());
-                    break;
-
-                default:
+            List<ProvisioningReport> results = singlePushExecutor.push(
+                    init.getRight(),
+                    connFactory.getConnector(init.getRight().getResource()),
+                    init.getLeft(),
+                    pushTask);
+            if (!results.isEmpty() && results.get(0).getStatus() == 
ProvisioningReport.Status.FAILURE) {
+                sce.getElements().add(results.get(0).getMessage());
             }
+        } catch (JobExecutionException e) {
+            sce.getElements().add(e.getMessage());
+        }
+
+        if (!sce.isEmpty()) {
+            throw sce;
+        }
+    }
 
-            if (results != null && !results.isEmpty()
-                    && results.get(0).getStatus() == 
ProvisioningReport.Status.FAILURE) {
+    @PreAuthorize("hasRole('" + StandardEntitlement.TASK_EXECUTE + "')")
+    public void pull(
+            final AnyTypeKind anyTypeKind,
+            final String anyKey,
+            final String resourceKey,
+            final PullTaskTO pullTask) {
 
+        Pair<Any<?>, Provision> init = init(anyTypeKind, anyKey, resourceKey);
+
+        SyncopeClientException sce = 
SyncopeClientException.build(ClientExceptionType.Reconciliation);
+        try {
+            List<ProvisioningReport> results = singlePullExecutor.pull(
+                    init.getRight(),
+                    connFactory.getConnector(init.getRight().getResource()),
+                    
init.getRight().getMapping().getConnObjectKeyItem().getExtAttrName(),
+                    mappingManager.getConnObjectKeyValue(init.getLeft(), 
init.getRight()),
+                    init.getLeft().getRealm(),
+                    pullTask);
+            if (!results.isEmpty() && results.get(0).getStatus() == 
ProvisioningReport.Status.FAILURE) {
                 sce.getElements().add(results.get(0).getMessage());
             }
         } catch (JobExecutionException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java
index ba4d160..000ee45 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.provisioning.api.pushpull;
 
 import java.util.List;
+import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.Connector;
@@ -32,5 +33,5 @@ public interface SyncopeSinglePullExecutor {
             String connObjectKey,
             String connObjectValue,
             Realm realm,
-            List<String> actionsClassNames) throws JobExecutionException;
+            PullTaskTO pullTaskTO) throws JobExecutionException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java
index eb18f00..a8256cd 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.provisioning.api.pushpull;
 
 import java.util.List;
+import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.provisioning.api.Connector;
@@ -30,5 +31,5 @@ public interface SyncopeSinglePushExecutor {
             Provision provision,
             Connector connector,
             Any<?> any,
-            List<String> actionsClassNames) throws JobExecutionException;
+            PushTaskTO pushTaskTO) throws JobExecutionException;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java
index 76bfe3e..53c4258 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractSyncopeResultHandler.java
@@ -69,6 +69,7 @@ public abstract class AbstractSyncopeResultHandler<T extends 
ProvisioningTask, A
     @Autowired
     protected PropagationTaskExecutor taskExecutor;
 
+    @Autowired
     protected AnyObjectWorkflowAdapter awfAdapter;
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
index 7df7f23..542f92d 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java
@@ -22,16 +22,22 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import org.apache.commons.collections4.IteratorUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.ConflictResolutionAction;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.PullMode;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 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.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.provisioning.api.Connector;
 import 
org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler;
@@ -41,18 +47,23 @@ import 
org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 import 
org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
 import 
org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePullExecutor;
 import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.OperationOptions;
 import org.identityconnectors.framework.common.objects.filter.Filter;
 import org.identityconnectors.framework.common.objects.filter.FilterBuilder;
 import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.stereotype.Component;
 
 @Component
 public class SinglePullJobDelegate extends PullJobDelegate implements 
SyncopeSinglePullExecutor {
 
+    @Autowired
+    private TemplateUtils templateUtils;
+
     @Override
     public List<ProvisioningReport> pull(
             final Provision provision,
@@ -60,12 +71,12 @@ public class SinglePullJobDelegate extends PullJobDelegate 
implements SyncopeSin
             final String connObjectKey,
             final String connObjectValue,
             final Realm realm,
-            final List<String> actionsClassNames) throws JobExecutionException 
{
+            final PullTaskTO pullTaskTO) throws JobExecutionException {
 
         LOG.debug("Executing pull on {}", provision.getResource());
 
         List<PullActions> actions = new ArrayList<>();
-        for (String className : actionsClassNames) {
+        for (String className : pullTaskTO.getActionsClassNames()) {
             try {
                 Class<?> actionsClass = Class.forName(className);
                 PullActions pullActions = (PullActions) 
ApplicationContextProvider.getBeanFactory().
@@ -89,12 +100,33 @@ public class SinglePullJobDelegate extends PullJobDelegate 
implements SyncopeSin
 
             PullTask pullTask = entityFactory.newEntity(PullTask.class);
             pullTask.setResource(provision.getResource());
-            pullTask.setMatchingRule(MatchingRule.UPDATE);
-            pullTask.setUnmatchingRule(UnmatchingRule.PROVISION);
+            pullTask.setMatchingRule(pullTaskTO.getMatchingRule() == null
+                    ? MatchingRule.UPDATE : pullTaskTO.getMatchingRule());
+            pullTask.setUnmatchingRule(pullTaskTO.getUnmatchingRule() == null
+                    ? UnmatchingRule.PROVISION : 
pullTaskTO.getUnmatchingRule());
             pullTask.setPullMode(PullMode.FILTERED_RECONCILIATION);
-            pullTask.setPerformCreate(true);
-            pullTask.setPerformUpdate(true);
+            pullTask.setPerformCreate(pullTaskTO.isPerformCreate());
+            pullTask.setPerformUpdate(pullTaskTO.isPerformUpdate());
+            pullTask.setPerformDelete(pullTaskTO.isPerformDelete());
             pullTask.setDestinationRealm(realm);
+            // validate JEXL expressions from templates and proceed if fine
+            templateUtils.check(pullTaskTO.getTemplates(), 
ClientExceptionType.InvalidPullTask);
+            for (Map.Entry<String, AnyTO> entry : 
pullTaskTO.getTemplates().entrySet()) {
+                AnyType type = anyTypeDAO.find(entry.getKey());
+                if (type == null) {
+                    LOG.debug("Invalid AnyType {} specified, ignoring...", 
entry.getKey());
+                } else {
+                    AnyTemplatePullTask anyTemplate = 
pullTask.getTemplate(type);
+                    if (anyTemplate == null) {
+                        anyTemplate = 
entityFactory.newEntity(AnyTemplatePullTask.class);
+                        anyTemplate.setAnyType(type);
+                        anyTemplate.setPullTask(pullTask);
+
+                        pullTask.add(anyTemplate);
+                    }
+                    anyTemplate.set(entry.getValue());
+                }
+            }
 
             profile = new ProvisioningProfile<>(connector, pullTask);
             profile.setDryRun(false);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
index eceb4fb..3f1e655 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.provisioning.java.pushpull;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.entity.Any;
@@ -45,12 +46,12 @@ public class SinglePushJobDelegate extends PushJobDelegate 
implements SyncopeSin
             final Provision provision,
             final Connector connector,
             final Any<?> any,
-            final List<String> actionsClassNames) throws JobExecutionException 
{
+            final PushTaskTO pushTaskTO) throws JobExecutionException {
 
         LOG.debug("Executing push on {}", provision.getResource());
 
         List<PushActions> actions = new ArrayList<>();
-        for (String className : actionsClassNames) {
+        for (String className : pushTaskTO.getActionsClassNames()) {
             try {
                 Class<?> actionsClass = Class.forName(className);
 
@@ -65,10 +66,13 @@ public class SinglePushJobDelegate extends PushJobDelegate 
implements SyncopeSin
         try {
             PushTask pushTask = entityFactory.newEntity(PushTask.class);
             pushTask.setResource(provision.getResource());
-            pushTask.setMatchingRule(MatchingRule.UPDATE);
-            pushTask.setUnmatchingRule(UnmatchingRule.PROVISION);
-            pushTask.setPerformCreate(true);
-            pushTask.setPerformUpdate(true);
+            pushTask.setMatchingRule(pushTaskTO.getMatchingRule() == null
+                    ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
+            pushTask.setUnmatchingRule(pushTaskTO.getUnmatchingRule() == null
+                    ? UnmatchingRule.ASSIGN : pushTaskTO.getUnmatchingRule());
+            pushTask.setPerformCreate(pushTaskTO.isPerformCreate());
+            pushTask.setPerformUpdate(pushTaskTO.isPerformUpdate());
+            pushTask.setPerformDelete(pushTaskTO.isPerformDelete());
 
             profile = new ProvisioningProfile<>(connector, pushTask);
             profile.getActions().addAll(actions);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java
index 80d89d5..ad460cb 100644
--- 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReconciliationServiceImpl.java
@@ -18,7 +18,8 @@
  */
 package org.apache.syncope.core.rest.cxf.service;
 
-import org.apache.syncope.common.lib.to.ReconciliationRequest;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.ReconciliationStatus;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.rest.api.service.ReconciliationService;
@@ -45,9 +46,30 @@ public class ReconciliationServiceImpl extends 
AbstractServiceImpl implements Re
     }
 
     @Override
-    public void reconcile(final ReconciliationRequest request) {
-        request.setAnyKey(
-                
getActualKey(anyUtilsFactory.getInstance(request.getAnyTypeKind()).dao(), 
request.getAnyKey()));
-        logic.reconcile(request);
+    public void push(
+            final AnyTypeKind anyTypeKind,
+            final String anyKey,
+            final String resourceKey,
+            final PushTaskTO pushTask) {
+
+        logic.push(
+                anyTypeKind,
+                getActualKey(anyUtilsFactory.getInstance(anyTypeKind).dao(), 
anyKey),
+                resourceKey,
+                pushTask);
+    }
+
+    @Override
+    public void pull(
+            final AnyTypeKind anyTypeKind,
+            final String anyKey,
+            final String resourceKey,
+            final PullTaskTO pullTask) {
+
+        logic.pull(
+                anyTypeKind,
+                getActualKey(anyUtilsFactory.getInstance(anyTypeKind).dao(), 
anyKey),
+                resourceKey,
+                pullTask);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a07f3b94/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java
index d6cd241..8fd8680 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ReconciliationITCase.java
@@ -28,10 +28,11 @@ import java.util.Date;
 import javax.sql.DataSource;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.ReconciliationRequest;
+import org.apache.syncope.common.lib.to.PullTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.ReconciliationStatus;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.ReconciliationAction;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.fit.AbstractITCase;
 import org.identityconnectors.framework.common.objects.OperationalAttributes;
 import org.junit.Test;
@@ -69,12 +70,10 @@ public class ReconciliationITCase extends AbstractITCase {
         assertNull(status.getOnResource());
 
         // 4. push
-        ReconciliationRequest request = new ReconciliationRequest();
-        request.setAction(ReconciliationAction.PUSH);
-        request.setAnyKey(printer.getKey());
-        request.setAnyTypeKind(AnyTypeKind.ANY_OBJECT);
-        request.setResourceKey("resource-db-scripted");
-        reconciliationService.reconcile(request);
+        PushTaskTO pushTask = new PushTaskTO();
+        pushTask.setPerformCreate(true);
+        pushTask.setUnmatchingRule(UnmatchingRule.PROVISION);
+        reconciliationService.push(AnyTypeKind.ANY_OBJECT, printer.getKey(), 
"resource-db-scripted", pushTask);
 
         // 5. verify that printer is now propagated
         assertEquals(1, jdbcTemplate.queryForList(
@@ -122,12 +121,9 @@ public class ReconciliationITCase extends AbstractITCase {
         assertNotEquals(status.getOnSyncope().getAttr("LOCATION"), 
status.getOnResource().getAttr("LOCATION"));
 
         // 4. pull
-        ReconciliationRequest request = new ReconciliationRequest();
-        request.setAction(ReconciliationAction.PULL);
-        request.setAnyKey(printer.getKey());
-        request.setAnyTypeKind(AnyTypeKind.ANY_OBJECT);
-        request.setResourceKey("resource-db-scripted");
-        reconciliationService.reconcile(request);
+        PullTaskTO pullTask = new PullTaskTO();
+        pullTask.setPerformUpdate(true);
+        reconciliationService.pull(AnyTypeKind.ANY_OBJECT, printer.getName(), 
"resource-db-scripted", pullTask);
 
         // 5. verify reconciliation result (and resource is still not assigned)
         printer = anyObjectService.read(printer.getKey());

Reply via email to