[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/44a5e1da Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/44a5e1da Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/44a5e1da Branch: refs/heads/master Commit: 44a5e1da7adf8aa6519fea8410b82ea0ac6b425e Parents: 24f7899 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:53:15 2018 +0200 ---------------------------------------------------------------------- .../common/lib/to/ReconciliationRequest.java | 100 ------------------- .../common/lib/types/ReconciliationAction.java | 28 ------ .../rest/api/service/ReconciliationService.java | 40 +++++++- .../syncope/core/logic/ReconciliationLogic.java | 73 ++++++++------ .../api/pushpull/SyncopeSinglePullExecutor.java | 4 +- .../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, 165 insertions(+), 200 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/44a5e1da/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 2ebf699..0000000 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReconciliationRequest.java +++ /dev/null @@ -1,100 +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 boolean remediation; - - private final List<String> actions = 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; - } - - public boolean isRemediation() { - return remediation; - } - - public void setRemediation(final boolean remediation) { - this.remediation = remediation; - } - - @XmlElementWrapper(name = "actions") - @XmlElement(name = "action") - @JsonProperty("actions") - public List<String> getActions() { - return actions; - } -} http://git-wip-us.apache.org/repos/asf/syncope/blob/44a5e1da/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/44a5e1da/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 77eb840..068f840 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 @@ -32,7 +32,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; @@ -64,15 +65,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(responseCode = "204", description = "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(responseCode = "204", description = "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/44a5e1da/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 a36c159..a686215 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.SyncopeClientException; import org.apache.syncope.common.lib.collections.IteratorChain; 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; @@ -76,9 +76,6 @@ public class ReconciliationLogic extends AbstractTransactionalLogic<AbstractBase private VirSchemaDAO virSchemaDAO; @Autowired - private RealmDAO realmDAO; - - @Autowired private MappingManager mappingManager; @Autowired @@ -180,38 +177,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.getActions()); - break; - - case PULL: - results = singlePullExecutor.pull( - init.getRight(), - connFactory.getConnector(init.getRight().getResource()), - init.getRight().getMapping().getConnObjectKeyItem().get().getExtAttrName(), - mappingManager.getConnObjectKeyValue(init.getLeft(), init.getRight()).get(), - realmDAO.findByFullPath(init.getLeft().getRealm().getFullPath()), - request.isRemediation(), - request.getActions()); - 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().get().getExtAttrName(), + mappingManager.getConnObjectKeyValue(init.getLeft(), init.getRight()).get(), + 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/44a5e1da/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 bbf8430..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,6 +33,5 @@ public interface SyncopeSinglePullExecutor { String connObjectKey, String connObjectValue, Realm realm, - boolean remediation, - List<String> actions) throws JobExecutionException; + PullTaskTO pullTaskTO) throws JobExecutionException; } http://git-wip-us.apache.org/repos/asf/syncope/blob/44a5e1da/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 9068301..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> actions) throws JobExecutionException; + PushTaskTO pushTaskTO) throws JobExecutionException; } http://git-wip-us.apache.org/repos/asf/syncope/blob/44a5e1da/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/44a5e1da/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 f4f57b4..bb410f9 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 @@ -24,6 +24,8 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.apache.syncope.common.lib.collections.IteratorChain; +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.ImplementationType; import org.apache.syncope.common.lib.types.MatchingRule; @@ -31,9 +33,11 @@ import org.apache.syncope.common.lib.types.PullMode; import org.apache.syncope.common.lib.types.UnmatchingRule; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.entity.Implementation; +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.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; @@ -45,6 +49,7 @@ import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandle import org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePullExecutor; import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.apache.syncope.core.spring.ImplementationManager; +import org.apache.syncope.core.provisioning.java.utils.TemplateUtils; import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.OperationOptions; import org.identityconnectors.framework.common.objects.filter.Filter; @@ -59,6 +64,9 @@ public class SinglePullJobDelegate extends PullJobDelegate implements SyncopeSin @Autowired private ImplementationDAO implementationDAO; + @Autowired + private TemplateUtils templateUtils; + @Override public List<ProvisioningReport> pull( final Provision provision, @@ -66,13 +74,12 @@ public class SinglePullJobDelegate extends PullJobDelegate implements SyncopeSin final String connObjectKey, final String connObjectValue, final Realm realm, - final boolean remediation, - final List<String> actionKeys) throws JobExecutionException { + final PullTaskTO pullTaskTO) throws JobExecutionException { LOG.debug("Executing pull on {}", provision.getResource()); List<PullActions> actions = new ArrayList<>(); - actionKeys.forEach(key -> { + pullTaskTO.getActions().forEach(key -> { Implementation impl = implementationDAO.find(key); if (impl == null || impl.getType() != ImplementationType.PULL_ACTIONS) { LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", key); @@ -95,13 +102,34 @@ 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.setRemediation(remediation); + pullTask.setPerformCreate(pullTaskTO.isPerformCreate()); + pullTask.setPerformUpdate(pullTaskTO.isPerformUpdate()); + pullTask.setPerformDelete(pullTaskTO.isPerformDelete()); pullTask.setDestinationRealm(realm); + pullTask.setRemediation(pullTaskTO.isRemediation()); + // validate JEXL expressions from templates and proceed if fine + templateUtils.check(pullTaskTO.getTemplates(), ClientExceptionType.InvalidPullTask); + pullTaskTO.getTemplates().forEach((type, template) -> { + AnyType anyType = anyTypeDAO.find(type); + if (anyType == null) { + LOG.debug("Invalid AnyType {} specified, ignoring...", type); + } else { + AnyTemplatePullTask anyTemplate = pullTask.getTemplate(anyType).orElse(null); + if (anyTemplate == null) { + anyTemplate = entityFactory.newEntity(AnyTemplatePullTask.class); + anyTemplate.setAnyType(anyType); + anyTemplate.setPullTask(pullTask); + + pullTask.add(anyTemplate); + } + anyTemplate.set(template); + } + }); profile = new ProvisioningProfile<>(connector, pullTask); profile.setDryRun(false); http://git-wip-us.apache.org/repos/asf/syncope/blob/44a5e1da/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 76bdc16..90b8f08 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.ImplementationType; import org.apache.syncope.common.lib.types.MatchingRule; import org.apache.syncope.common.lib.types.UnmatchingRule; @@ -51,12 +52,12 @@ public class SinglePushJobDelegate extends PushJobDelegate implements SyncopeSin final Provision provision, final Connector connector, final Any<?> any, - final List<String> actionKeys) throws JobExecutionException { + final PushTaskTO pushTaskTO) throws JobExecutionException { LOG.debug("Executing push on {}", provision.getResource()); List<PushActions> actions = new ArrayList<>(); - actionKeys.forEach(key -> { + pushTaskTO.getActions().forEach(key -> { Implementation impl = implementationDAO.find(key); if (impl == null || impl.getType() != ImplementationType.PUSH_ACTIONS) { LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", key); @@ -72,10 +73,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/44a5e1da/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/44a5e1da/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 172e69c..703799f 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.jupiter.api.Test; @@ -66,12 +67,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( @@ -119,12 +118,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());