http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java ---------------------------------------------------------------------- diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java index 98a23a6..2d6c6e4 100644 --- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java +++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GroupServiceImpl.java @@ -19,98 +19,23 @@ package org.apache.syncope.core.rest.cxf.service; import java.util.List; -import javax.ws.rs.core.Response; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.Transformer; -import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.mod.GroupMod; -import org.apache.syncope.common.lib.to.BulkAction; -import org.apache.syncope.common.lib.to.BulkActionResult; -import org.apache.syncope.common.lib.to.PagedResult; -import org.apache.syncope.common.lib.to.PropagationStatus; import org.apache.syncope.common.lib.to.GroupTO; -import org.apache.syncope.common.lib.types.ResourceAssociationActionType; -import org.apache.syncope.common.lib.types.ResourceDeassociationActionType; -import org.apache.syncope.common.lib.wrap.ResourceKey; -import org.apache.syncope.common.rest.api.CollectionWrapper; -import org.apache.syncope.common.rest.api.beans.AnyListQuery; -import org.apache.syncope.common.rest.api.beans.AnySearchQuery; import org.apache.syncope.common.rest.api.service.GroupService; +import org.apache.syncope.core.logic.AbstractAnyLogic; import org.apache.syncope.core.logic.GroupLogic; -import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service -public class GroupServiceImpl extends AbstractServiceImpl implements GroupService { +public class GroupServiceImpl extends AbstractAnyService<GroupTO, GroupMod> implements GroupService { @Autowired private GroupLogic logic; @Override - public Response create(final GroupTO groupTO) { - GroupTO created = logic.create(groupTO); - return createResponse(created.getKey(), created); - } - - @Override - public Response delete(final Long groupKey) { - GroupTO group = logic.read(groupKey); - - checkETag(group.getETagValue()); - - GroupTO deleted = logic.delete(groupKey); - return modificationResponse(deleted); - } - - @Override - public PagedResult<GroupTO> list(final AnyListQuery listQuery) { - CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() { - - @Override - public String transform(final String input) { - return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM); - } - }); - - return buildPagedResult( - logic.list( - listQuery.getPage(), - listQuery.getSize(), - getOrderByClauses(listQuery.getOrderBy()), - listQuery.getRealms()), - listQuery.getPage(), - listQuery.getSize(), - logic.count(listQuery.getRealms())); - } - - @Override - public GroupTO read(final Long groupKey) { - return logic.read(groupKey); - } - - @Override - public PagedResult<GroupTO> search(final AnySearchQuery searchQuery) { - CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() { - - @Override - public String transform(final String input) { - return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM); - } - }); - - SearchCond cond = getSearchCond(searchQuery.getFiql()); - return buildPagedResult( - logic.search( - cond, - searchQuery.getPage(), - searchQuery.getSize(), - getOrderByClauses(searchQuery.getOrderBy()), - searchQuery.getRealms()), - searchQuery.getPage(), - searchQuery.getSize(), - logic.searchCount(cond, searchQuery.getRealms())); + protected AbstractAnyLogic<GroupTO, GroupMod> getAnyLogic() { + return logic; } @Override @@ -118,126 +43,4 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic return logic.own(); } - @Override - public Response update(final Long groupKey, final GroupMod groupMod) { - GroupTO group = logic.read(groupKey); - - checkETag(group.getETagValue()); - - groupMod.setKey(groupKey); - GroupTO updated = logic.update(groupMod); - return modificationResponse(updated); - } - - @Override - public Response bulkDeassociation( - final Long groupKey, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) { - - GroupTO group = logic.read(groupKey); - - checkETag(group.getETagValue()); - - GroupTO updated; - switch (type) { - case UNLINK: - updated = logic.unlink(groupKey, CollectionWrapper.unwrap(resourceNames)); - break; - - case UNASSIGN: - updated = logic.unassign(groupKey, CollectionWrapper.unwrap(resourceNames)); - break; - - case DEPROVISION: - updated = logic.deprovision(groupKey, CollectionWrapper.unwrap(resourceNames)); - break; - - default: - updated = logic.read(groupKey); - } - - BulkActionResult result = new BulkActionResult(); - - if (type == ResourceDeassociationActionType.UNLINK) { - for (ResourceKey resourceName : resourceNames) { - result.getResults().put(resourceName.getElement(), - updated.getResources().contains(resourceName.getElement()) - ? BulkActionResult.Status.FAILURE - : BulkActionResult.Status.SUCCESS); - } - } else { - for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) { - result.getResults().put(propagationStatusTO.getResource(), - BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString())); - } - } - - return modificationResponse(result); - } - - @Override - public Response bulkAssociation( - final Long groupKey, final ResourceAssociationActionType type, final List<ResourceKey> resourceNames) { - - GroupTO group = logic.read(groupKey); - - checkETag(group.getETagValue()); - - GroupTO updated; - switch (type) { - case LINK: - updated = logic.link(groupKey, CollectionWrapper.unwrap(resourceNames)); - break; - - case ASSIGN: - updated = logic.assign(groupKey, CollectionWrapper.unwrap(resourceNames), false, null); - break; - - case PROVISION: - updated = logic.provision(groupKey, CollectionWrapper.unwrap(resourceNames), false, null); - break; - - default: - updated = logic.read(groupKey); - } - - BulkActionResult result = new BulkActionResult(); - - if (type == ResourceAssociationActionType.LINK) { - for (ResourceKey resourceName : resourceNames) { - result.getResults().put(resourceName.getElement(), - updated.getResources().contains(resourceName.getElement()) - ? BulkActionResult.Status.FAILURE - : BulkActionResult.Status.SUCCESS); - } - } else { - for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) { - result.getResults().put(propagationStatusTO.getResource(), - BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString())); - } - } - - return modificationResponse(result); - } - - @Override - public BulkActionResult bulk(final BulkAction bulkAction) { - BulkActionResult result = new BulkActionResult(); - - if (bulkAction.getOperation() == BulkAction.Type.DELETE) { - for (String groupKey : bulkAction.getTargets()) { - try { - result.getResults().put( - String.valueOf(logic.delete(Long.valueOf(groupKey)).getKey()), - BulkActionResult.Status.SUCCESS); - } catch (Exception e) { - LOG.error("Error performing delete for group {}", groupKey, e); - result.getResults().put(groupKey, BulkActionResult.Status.FAILURE); - } - } - } else { - LOG.warn("Unsupported bulk action: {}", bulkAction.getOperation()); - } - - return result; - } }
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java ---------------------------------------------------------------------- diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java index 192b4e0..391aea8 100644 --- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java +++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserServiceImpl.java @@ -18,44 +18,33 @@ */ package org.apache.syncope.core.rest.cxf.service; -import java.util.List; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.Transformer; -import org.apache.commons.lang3.StringUtils; -import org.apache.syncope.common.lib.SyncopeConstants; -import org.apache.syncope.common.lib.mod.ResourceAssociationMod; import org.apache.syncope.common.lib.mod.StatusMod; import org.apache.syncope.common.lib.mod.UserMod; -import org.apache.syncope.common.lib.to.BulkAction; -import org.apache.syncope.common.lib.to.BulkActionResult; -import org.apache.syncope.common.lib.to.PagedResult; -import org.apache.syncope.common.lib.to.PropagationStatus; import org.apache.syncope.common.lib.to.UserTO; -import org.apache.syncope.common.lib.types.ResourceAssociationActionType; -import org.apache.syncope.common.lib.types.ResourceDeassociationActionType; -import org.apache.syncope.common.lib.wrap.ResourceKey; -import org.apache.syncope.common.rest.api.CollectionWrapper; import org.apache.syncope.common.rest.api.RESTHeaders; -import org.apache.syncope.common.rest.api.beans.AnyListQuery; -import org.apache.syncope.common.rest.api.beans.AnySearchQuery; import org.apache.syncope.common.rest.api.service.UserService; +import org.apache.syncope.core.logic.AbstractAnyLogic; import org.apache.syncope.core.logic.UserLogic; -import org.apache.syncope.core.persistence.api.dao.search.SearchCond; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service -public class UserServiceImpl extends AbstractServiceImpl implements UserService { +public class UserServiceImpl extends AbstractAnyService<UserTO, UserMod> implements UserService { @Autowired private UserLogic logic; @Override - public Response getUsername(final Long userKey) { + protected AbstractAnyLogic<UserTO, UserMod> getAnyLogic() { + return logic; + } + + @Override + public Response getUsername(final Long key) { return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW). - header(RESTHeaders.USERNAME, logic.getUsername(userKey)). + header(RESTHeaders.USERNAME, logic.getUsername(key)). build(); } @@ -73,237 +62,13 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService } @Override - public Response delete(final Long userKey) { - UserTO user = logic.read(userKey); - - checkETag(user.getETagValue()); - - UserTO deleted = logic.delete(userKey); - return modificationResponse(deleted); - } - - @Override - public PagedResult<UserTO> list(final AnyListQuery listQuery) { - CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() { - - @Override - public String transform(final String input) { - return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM); - } - }); - - return buildPagedResult( - logic.list( - listQuery.getPage(), - listQuery.getSize(), - getOrderByClauses(listQuery.getOrderBy()), - listQuery.getRealms()), - listQuery.getPage(), - listQuery.getSize(), - logic.count(listQuery.getRealms())); - } - - @Override - public UserTO read(final Long userKey) { - return logic.read(userKey); - } - - @Override - public PagedResult<UserTO> search(final AnySearchQuery searchQuery) { - CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() { - - @Override - public String transform(final String input) { - return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM); - } - }); - - SearchCond cond = getSearchCond(searchQuery.getFiql()); - return buildPagedResult( - logic.search( - cond, - searchQuery.getPage(), - searchQuery.getSize(), - getOrderByClauses(searchQuery.getOrderBy()), - searchQuery.getRealms()), - searchQuery.getPage(), - searchQuery.getSize(), - logic.searchCount(cond, searchQuery.getRealms())); - } - - @Override - public Response update(final Long userKey, final UserMod userMod) { - UserTO user = logic.read(userKey); - - checkETag(user.getETagValue()); - - userMod.setKey(userKey); - UserTO updated = logic.update(userMod); - return modificationResponse(updated); - } - - @Override - public Response status(final Long userKey, final StatusMod statusMod) { - UserTO user = logic.read(userKey); + public Response status(final Long key, final StatusMod statusMod) { + UserTO user = logic.read(key); checkETag(user.getETagValue()); - statusMod.setKey(userKey); + statusMod.setKey(key); UserTO updated = logic.status(statusMod); return modificationResponse(updated); } - - @Override - public Response bulkDeassociation( - final Long userKey, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) { - - final UserTO user = logic.read(userKey); - - checkETag(user.getETagValue()); - - UserTO updated; - switch (type) { - case UNLINK: - updated = logic.unlink(userKey, CollectionWrapper.unwrap(resourceNames)); - break; - - case UNASSIGN: - updated = logic.unassign(userKey, CollectionWrapper.unwrap(resourceNames)); - break; - - case DEPROVISION: - updated = logic.deprovision(userKey, CollectionWrapper.unwrap(resourceNames)); - break; - - default: - updated = logic.read(userKey); - } - - BulkActionResult result = new BulkActionResult(); - - if (type == ResourceDeassociationActionType.UNLINK) { - for (ResourceKey resourceName : resourceNames) { - result.getResults().put( - resourceName.getElement(), updated.getResources().contains(resourceName.getElement()) - ? BulkActionResult.Status.FAILURE - : BulkActionResult.Status.SUCCESS); - } - } else { - for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) { - result.getResults().put(propagationStatusTO.getResource(), - BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString())); - } - } - - return modificationResponse(result); - } - - @Override - public Response bulkAssociation( - final Long userKey, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) { - - final UserTO user = logic.read(userKey); - - checkETag(user.getETagValue()); - - UserTO updated; - switch (type) { - case LINK: - updated = logic.link( - userKey, - CollectionWrapper.unwrap(associationMod.getTargetResources())); - break; - - case ASSIGN: - updated = logic.assign( - userKey, - CollectionWrapper.unwrap(associationMod.getTargetResources()), - associationMod.isChangePwd(), - associationMod.getPassword()); - break; - - case PROVISION: - updated = logic.provision( - userKey, - CollectionWrapper.unwrap(associationMod.getTargetResources()), - associationMod.isChangePwd(), - associationMod.getPassword()); - break; - - default: - updated = logic.read(userKey); - } - - BulkActionResult result = new BulkActionResult(); - - if (type == ResourceAssociationActionType.LINK) { - for (ResourceKey resourceName : associationMod.getTargetResources()) { - result.getResults().put(resourceName.getElement(), - updated.getResources().contains(resourceName.getElement()) - ? BulkActionResult.Status.FAILURE - : BulkActionResult.Status.SUCCESS); - } - } else { - for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) { - result.getResults().put(propagationStatusTO.getResource(), - BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString())); - } - } - - return modificationResponse(result); - } - - @Override - public BulkActionResult bulk(final BulkAction bulkAction) { - BulkActionResult result = new BulkActionResult(); - - switch (bulkAction.getOperation()) { - case DELETE: - for (String key : bulkAction.getTargets()) { - try { - result.getResults().put( - String.valueOf(logic.delete(Long.valueOf(key)).getKey()), - BulkActionResult.Status.SUCCESS); - } catch (Exception e) { - LOG.error("Error performing delete for user {}", key, e); - result.getResults().put(key, BulkActionResult.Status.FAILURE); - } - } - break; - - case SUSPEND: - for (String key : bulkAction.getTargets()) { - StatusMod statusMod = new StatusMod(); - statusMod.setKey(Long.valueOf(key)); - statusMod.setType(StatusMod.ModType.SUSPEND); - try { - result.getResults().put( - String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS); - } catch (Exception e) { - LOG.error("Error performing suspend for user {}", key, e); - result.getResults().put(key, BulkActionResult.Status.FAILURE); - } - } - break; - - case REACTIVATE: - for (String key : bulkAction.getTargets()) { - StatusMod statusMod = new StatusMod(); - statusMod.setKey(Long.valueOf(key)); - statusMod.setType(StatusMod.ModType.REACTIVATE); - try { - result.getResults().put( - String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS); - } catch (Exception e) { - LOG.error("Error performing reactivate for user {}", key, e); - result.getResults().put(key, BulkActionResult.Status.FAILURE); - } - } - break; - - default: - } - - return result; - } } http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java ---------------------------------------------------------------------- diff --git a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java index 3520a4a..4359e7b 100644 --- a/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java +++ b/ext/camel/logic/src/main/java/org/apache/syncope/core/logic/init/CamelRouteLoader.java @@ -56,6 +56,9 @@ public class CamelRouteLoader implements SyncopeLoader { @javax.annotation.Resource(name = "groupRoutes") private ResourceWithFallbackLoader groupRoutesLoader; + @javax.annotation.Resource(name = "anyObjectRoutes") + private ResourceWithFallbackLoader anyObjectRoutesLoader; + @Autowired private DataSource dataSource; @@ -76,6 +79,7 @@ public class CamelRouteLoader implements SyncopeLoader { if (!loaded) { loadRoutes(userRoutesLoader.getResource(), AnyTypeKind.USER); loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.GROUP); + loadRoutes(anyObjectRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT); loaded = true; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java new file mode 100644 index 0000000..ae29501 --- /dev/null +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java @@ -0,0 +1,163 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.camel; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.camel.Exchange; +import org.apache.camel.PollingConsumer; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.syncope.common.lib.mod.AnyObjectMod; +import org.apache.syncope.common.lib.to.PropagationStatus; +import org.apache.syncope.common.lib.to.AnyObjectTO; +import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager; + +public class CamelAnyObjectProvisioningManager + extends AbstractCamelProvisioningManager implements AnyObjectProvisioningManager { + + @Override + public Pair<Long, List<PropagationStatus>> create(final AnyObjectTO any) { + return create(any, Collections.<String>emptySet()); + } + + @Override + @SuppressWarnings("unchecked") + public Pair<Long, List<PropagationStatus>> create( + final AnyObjectTO anyObjectTO, final Set<String> excludedResources) { + + PollingConsumer pollingConsumer = getConsumer("direct:createAnyObjectPort"); + + Map<String, Object> props = new HashMap<>(); + props.put("excludedResources", excludedResources); + + sendMessage("direct:createAnyObject", anyObjectTO, props); + + Exchange exchange = pollingConsumer.receive(); + + if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) { + throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT); + } + + return exchange.getIn().getBody(Pair.class); + } + + @Override + public Pair<Long, List<PropagationStatus>> update(final AnyObjectMod anyMod) { + return update(anyMod, Collections.<String>emptySet()); + } + + @Override + @SuppressWarnings("unchecked") + public Pair<Long, List<PropagationStatus>> update( + final AnyObjectMod anyMod, final Set<String> excludedResources) { + + PollingConsumer pollingConsumer = getConsumer("direct:updateAnyObjectPort"); + + Map<String, Object> props = new HashMap<>(); + props.put("excludedResources", excludedResources); + + sendMessage("direct:updateAnyObject", anyMod, props); + + Exchange exchange = pollingConsumer.receive(); + + if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) { + throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT); + } + + return exchange.getIn().getBody(Pair.class); + } + + @Override + public List<PropagationStatus> delete(final Long anyObjectObjectKey) { + return delete(anyObjectObjectKey, Collections.<String>emptySet()); + } + + @Override + @SuppressWarnings("unchecked") + public List<PropagationStatus> delete(final Long anyObjectKey, final Set<String> excludedResources) { + PollingConsumer pollingConsumer = getConsumer("direct:deleteAnyObjectPort"); + + Map<String, Object> props = new HashMap<>(); + props.put("excludedResources", excludedResources); + + sendMessage("direct:deleteAnyObject", anyObjectKey, props); + + Exchange exchange = pollingConsumer.receive(); + + if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) { + throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT); + } + + return exchange.getIn().getBody(List.class); + } + + @Override + public Long unlink(final AnyObjectMod anyObjectMod) { + PollingConsumer pollingConsumer = getConsumer("direct:unlinkAnyObjectPort"); + + sendMessage("direct:unlinkAnyObject", anyObjectMod); + + Exchange exchange = pollingConsumer.receive(); + + if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) { + throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT); + } + + return exchange.getIn().getBody(Long.class); + } + + @Override + public Long link(final AnyObjectMod anyObjectMod) { + PollingConsumer pollingConsumer = getConsumer("direct:linkAnyObjectPort"); + + sendMessage("direct:linkAnyObject", anyObjectMod); + + Exchange exchange = pollingConsumer.receive(); + + if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) { + throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT); + } + + return exchange.getIn().getBody(Long.class); + } + + @Override + @SuppressWarnings("unchecked") + public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) { + PollingConsumer pollingConsumer = getConsumer("direct:deprovisionAnyObjectPort"); + + Map<String, Object> props = new HashMap<>(); + props.put("resources", resources); + + sendMessage("direct:deprovisionAnyObject", anyObjectKey, props); + + Exchange exchange = pollingConsumer.receive(); + + if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) { + throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT); + } + + return exchange.getIn().getBody(List.class); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java new file mode 100644 index 0000000..2f2e41e --- /dev/null +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.camel.processor; + +import java.util.List; +import java.util.Set; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.syncope.common.lib.to.AnyObjectTO; +import org.apache.syncope.core.misc.spring.ApplicationContextProvider; +import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.provisioning.api.propagation.PropagationException; +import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; +import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; +import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class AnyObjectCreateProcessor implements Processor { + + private static final Logger LOG = LoggerFactory.getLogger(AnyObjectCreateProcessor.class); + + @Autowired + protected PropagationManager propagationManager; + + @Autowired + protected PropagationTaskExecutor taskExecutor; + + @SuppressWarnings("unchecked") + @Override + public void process(final Exchange exchange) { + WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody(); + AnyObjectTO any = exchange.getProperty("any", AnyObjectTO.class); + Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class); + + List<PropagationTask> tasks = + propagationManager.getAnyObjectCreateTasks(created, any.getVirAttrs(), excludedResource); + PropagationReporter propagationReporter = + ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + + exchange.getOut().setBody(new ImmutablePair<>(created.getResult(), propagationReporter.getStatuses())); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java new file mode 100644 index 0000000..d1c9243 --- /dev/null +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.camel.processor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.syncope.core.misc.spring.ApplicationContextProvider; +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; +import org.apache.syncope.core.provisioning.api.propagation.PropagationException; +import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; +import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; +import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; +import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class AnyObjectDeleteProcessor implements Processor { + + private static final Logger LOG = LoggerFactory.getLogger(AnyObjectDeleteProcessor.class); + + @Autowired + protected AnyObjectWorkflowAdapter gwfAdapter; + + @Autowired + protected PropagationManager propagationManager; + + @Autowired + protected PropagationTaskExecutor taskExecutor; + + @Autowired + protected AnyObjectDAO anyObjectDAO; + + @Override + public void process(final Exchange exchange) throws Exception { + Long anyKey = exchange.getIn().getBody(Long.class); + AnyObject anyObject = anyObjectDAO.find(anyKey); + @SuppressWarnings("unchecked") + Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class); + + List<PropagationTask> tasks = new ArrayList<>(); + + if (anyObject != null) { + // Generate propagation tasks for deleting this anyObject from resources + tasks.addAll(propagationManager.getAnyObjectDeleteTasks(anyObject.getKey(), excludedResources)); + } + + PropagationReporter propagationReporter = + ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + + exchange.setProperty("statuses", propagationReporter.getStatuses()); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java new file mode 100644 index 0000000..c56ab90 --- /dev/null +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.camel.processor; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.syncope.core.misc.spring.ApplicationContextProvider; +import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; +import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; +import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; +import org.apache.syncope.core.provisioning.api.propagation.PropagationException; +import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; +import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; +import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class AnyObjectDeprovisionProcessor implements Processor { + + private static final Logger LOG = LoggerFactory.getLogger(UserDeprovisionProcessor.class); + + @Autowired + protected PropagationManager propagationManager; + + @Autowired + protected PropagationTaskExecutor taskExecutor; + + @Autowired + protected AnyObjectDAO anyObjectDAO; + + @SuppressWarnings("unchecked") + @Override + public void process(final Exchange exchange) { + Long anyObjectKey = exchange.getIn().getBody(Long.class); + List<String> resources = exchange.getProperty("resources", List.class); + + AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey); + + Collection<String> noPropResourceNames = CollectionUtils.removeAll(anyObject.getResourceNames(), resources); + + List<PropagationTask> tasks = + propagationManager.getAnyObjectDeleteTasks(anyObjectKey, new HashSet<>(resources), noPropResourceNames); + PropagationReporter propagationReporter = + ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + + exchange.getOut().setBody(propagationReporter.getStatuses()); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java new file mode 100644 index 0000000..2979e97 --- /dev/null +++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.camel.processor; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.syncope.common.lib.mod.AnyObjectMod; +import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.syncope.common.lib.types.PropagationByResource; +import org.apache.syncope.core.misc.spring.ApplicationContextProvider; +import org.apache.syncope.core.persistence.api.entity.task.PropagationTask; +import org.apache.syncope.core.provisioning.api.VirAttrHandler; +import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.provisioning.api.propagation.PropagationException; +import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; +import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; +import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class AnyObjectUpdateProcessor implements Processor { + + private static final Logger LOG = LoggerFactory.getLogger(UserUpdateProcessor.class); + + @Autowired + protected PropagationManager propagationManager; + + @Autowired + protected PropagationTaskExecutor taskExecutor; + + @Autowired + protected VirAttrHandler virtAttrHandler; + + @SuppressWarnings("unchecked") + @Override + public void process(final Exchange exchange) { + WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody(); + AnyObjectMod anyObjectMod = exchange.getProperty("anyMod", AnyObjectMod.class); + Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class); + + List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(updated, + anyObjectMod.getVirAttrsToRemove(), anyObjectMod.getVirAttrsToUpdate(), excludedResources); + if (tasks.isEmpty()) { + // SYNCOPE-459: take care of user virtual attributes ... + PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual( + updated.getResult(), + AnyTypeKind.GROUP, + anyObjectMod.getVirAttrsToRemove(), + anyObjectMod.getVirAttrsToUpdate()); + tasks.addAll(!propByResVirAttr.isEmpty() + ? propagationManager.getAnyObjectUpdateTasks(updated, null, null, null) + : Collections.<PropagationTask>emptyList()); + } + + PropagationReporter propagationReporter = + ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); + try { + taskExecutor.execute(tasks, propagationReporter); + } catch (PropagationException e) { + LOG.error("Error propagation primary resource", e); + propagationReporter.onPrimaryResourceFailure(tasks); + } + + exchange.getOut().setBody(new ImmutablePair<>(updated.getResult(), propagationReporter.getStatuses())); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml new file mode 100644 index 0000000..de4df0b --- /dev/null +++ b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> +<routes> + + <route id="createAnyObject"> + <from uri="direct:createAnyObject"/> + <setProperty propertyName="any"> + <simple>${body}</simple> + </setProperty> + <doTry> + <bean ref="awfAdapter" method="create(${body})"/> + <process ref="anyObjectCreateProcessor"/> + <to uri="direct:createAnyObjectPort"/> + <doCatch> + <exception>java.lang.RuntimeException</exception> + <handled> + <constant>false</constant> + </handled> + <to uri="direct:createAnyObjectPort"/> + </doCatch> + </doTry> + </route> + + <route id="updateAnyObject"> + <from uri="direct:updateAnyObject"/> + <setProperty propertyName="anyMod"> + <simple>${body}</simple> + </setProperty> + <doTry> + <bean ref="awfAdapter" method="update(${body})"/> + <process ref="anyObjectUpdateProcessor"/> + <to uri="direct:updateAnyObjectPort"/> + <doCatch> + <exception>java.lang.RuntimeException</exception> + <handled> + <constant>false</constant> + </handled> + <to uri="direct:updateAnyObjectPort"/> + </doCatch> + </doTry> + </route> + + <route id="deleteAnyObject"> + <from uri="direct:deleteAnyObject"/> + <doTry> + <process ref="anyObjectDeleteProcessor"/> + <bean ref="awfAdapter" method="delete(${body})"/> + <setBody> + <simple>${property.statuses}</simple> + </setBody> + <to uri="direct:deleteAnyObjectPort"/> + <doCatch> + <exception>java.lang.RuntimeException</exception> + <handled> + <constant>false</constant> + </handled> + <to uri="direct:deleteAnyObjectPort"/> + </doCatch> + </doTry> + </route> + + <route id="unlinkAnyObject"> + <from uri="direct:unlinkAnyObject"/> + <doTry> + <bean ref="awfAdapter" method="update(${body})"/> + <setBody> + <simple>${body.getResult}</simple> + </setBody> + <to uri="direct:unlinkAnyObjectPort"/> + <doCatch> + <exception>java.lang.RuntimeException</exception> + <handled> + <constant>false</constant> + </handled> + <to uri="direct:unlinkAnyObjectPort"/> + </doCatch> + </doTry> + </route> + + <route id="linkAnyObject"> + <from uri="direct:linkAnyObject"/> + <doTry> + <bean ref="awfAdapter" method="update(${body})"/> + <setBody> + <simple>${body.getResult}</simple> + </setBody> + <to uri="direct:linkAnyObjectPort"/> + <doCatch> + <exception>java.lang.RuntimeException</exception> + <handled> + <constant>false</constant> + </handled> + <to uri="direct:linkAnyObjectPort"/> + </doCatch> + </doTry> + </route> + + <route id="deprovisionAnyObject"> + <from uri="direct:deprovisionAnyObject"/> + <process ref="anyObjectDeprovisionProcessor"/> + <to uri="direct:deprovisionAnyObjectPort"/> + </route> + +</routes> http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/provisioning.properties ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties index 5061502..aa843ca 100644 --- a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties +++ b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties @@ -17,5 +17,5 @@ camel.directory=${conf.directory} userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager -anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager +anyObjectProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelAnObjectProvisioningManager virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml ---------------------------------------------------------------------- diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml index 8eec14d..d334d75 100644 --- a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml +++ b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml @@ -33,7 +33,11 @@ under the License. <property name="primary" value="file:${camel.directory}/groupRoutes.xml"/> <property name="fallback" value="classpath:groupRoutes.xml"/> </bean> - + <bean id="anyObjectRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader"> + <property name="primary" value="file:${camel.directory}/anyObjectRoutes.xml"/> + <property name="fallback" value="classpath:anyObjectRoutes.xml"/> + </bean> + <context:component-scan base-package="org.apache.syncope.core.provisioning.camel"/> </beans> http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/pom.xml ---------------------------------------------------------------------- diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml index bfae2f4..679eee6 100644 --- a/fit/build-tools/pom.xml +++ b/fit/build-tools/pom.xml @@ -85,10 +85,16 @@ under the License. <dependency> <groupId>net.tirasa.connid.bundles.db</groupId> <artifactId>net.tirasa.connid.bundles.db.table</artifactId> - <version>${connid.db.table.version}</version> + <version>${connid.database.version}</version> <scope>runtime</scope> </dependency> - + <dependency> + <groupId>net.tirasa.connid.bundles.db</groupId> + <artifactId>net.tirasa.connid.bundles.db.scriptedsql</artifactId> + <version>${connid.database.version}</version> + <scope>runtime</scope> + </dependency> + <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java index 37adbd3..67567ec 100644 --- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java @@ -49,7 +49,8 @@ public class ConnIdStartStopListener implements ServletContextListener { for (String bundleFile : new String[] { "testconnectorserver.soap.bundle", - "testconnectorserver.db.bundle", + "testconnectorserver.dbtable.bundle", + "testconnectorserver.scriptedsql.bundle", "testconnectorserver.csvdir.bundle", "testconnectorserver.ldap.bundle" }) { http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/resources/buildToolsContext.xml ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/resources/buildToolsContext.xml b/fit/build-tools/src/main/resources/buildToolsContext.xml index 2b63ed6..e0f5678 100644 --- a/fit/build-tools/src/main/resources/buildToolsContext.xml +++ b/fit/build-tools/src/main/resources/buildToolsContext.xml @@ -45,8 +45,11 @@ under the License. <bean id="testconnectorserver.soap.bundle" class="java.lang.String"> <constructor-arg value="net.tirasa.connid.bundles.soap-${connid.soap.version}.jar"/> </bean> - <bean id="testconnectorserver.db.bundle" class="java.lang.String"> - <constructor-arg value="net.tirasa.connid.bundles.db.table-${connid.db.table.version}.jar"/> + <bean id="testconnectorserver.dbtable.bundle" class="java.lang.String"> + <constructor-arg value="net.tirasa.connid.bundles.db.table-${connid.database.version}.jar"/> + </bean> + <bean id="testconnectorserver.scriptedsql.bundle" class="java.lang.String"> + <constructor-arg value="net.tirasa.connid.bundles.db.scriptedsql-${connid.database.version}.jar"/> </bean> <bean id="testconnectorserver.csvdir.bundle" class="java.lang.String"> <constructor-arg value="net.tirasa.connid.bundles.csvdir-${connid.csvdir.version}.jar"/> http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/resources/testdb.sql ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/resources/testdb.sql b/fit/build-tools/src/main/resources/testdb.sql index ff4dd47..9202a87 100644 --- a/fit/build-tools/src/main/resources/testdb.sql +++ b/fit/build-tools/src/main/resources/testdb.sql @@ -37,10 +37,16 @@ INSERT INTO test2 VALUES ('verdi', 'password321', 'true'); -- this table is for issueSYNCOPE230 DROP TABLE testsync IF EXISTS; -CREATE TABLE TESTSYNC ( +CREATE TABLE testsync ( id NUMBER(10) PRIMARY KEY, username VARCHAR(80), surname VARCHAR(80), email VARCHAR(80)); INSERT INTO testsync VALUES (965, 'issuesyncope230', 'Surname', '[email protected]'); + +DROP TABLE testPRINTER IF EXISTS; +CREATE TABLE testPRINTER ( +id NUMBER(10) PRIMARY KEY, +location VARCHAR(80), +lastModification TIMESTAMP); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/connid.properties ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/resources/connid.properties b/fit/core-reference/src/main/resources/connid.properties index a18252f..22ed0a8 100644 --- a/fit/core-reference/src/main/resources/connid.properties +++ b/fit/core-reference/src/main/resources/connid.properties @@ -20,5 +20,5 @@ connid://${testconnectorserver.key}@localhost:${testconnectorserver.port} ## for test only testdb.url=${testdb.url} connid.soap.version=${connid.soap.version} -connid.db.table.version=${connid.db.table.version} +connid.database.version=${connid.database.version} http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy new file mode 100644 index 0000000..52c10f9 --- /dev/null +++ b/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy @@ -0,0 +1,52 @@ +/* + * 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. + */ +import groovy.sql.Sql; +import groovy.sql.DataSet; + +// Parameters: +// The connector sends us the following: +// connection : SQL connection +// action: String correponding to the action ("CREATE" here) +// log: a handler to the Log facility +// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) +// id: The entry identifier (OpenICF "Name" atribute. (most often matches the uid) +// attributes: an Attribute Map, containg the <String> attribute name as a key +// and the <List> attribute value(s) as value. +// password: password string, clear text +// options: a handler to the OperationOptions Map + +log.info("Entering " + action + " Script"); + +def sql = new Sql(connection); + +switch ( objectClass ) { +case "__PRINTER__": + sql.execute("INSERT INTO TESTPRINTER (id, location, lastmodification) values (?,?,?)", + [ + id, + attributes.get("location").get(0), + new Date() + ]) + break + +default: + id; +} + +return id; http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy new file mode 100644 index 0000000..cdd7f5b --- /dev/null +++ b/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy @@ -0,0 +1,43 @@ +/* + * 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. + */ +import groovy.sql.Sql; +import groovy.sql.DataSet; + +// Parameters: +// The connector sends the following: +// connection: handler to the SQL connection +// action: a string describing the action ("DELETE" here) +// log: a handler to the Log facility +// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) +// options: a handler to the OperationOptions Map +// uid: String for the unique id that specifies the object to delete + +log.info("Entering " + action + " Script"); +def sql = new Sql(connection); + +assert uid != null + +switch ( objectClass ) { +case "__PRINTER__": + sql.execute("DELETE FROM TESTPRINTER where id= ?",[uid]) + break + +default: + uid; +} http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy new file mode 100644 index 0000000..50f8a8a --- /dev/null +++ b/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy @@ -0,0 +1,50 @@ +/* + * 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. + */ +import org.identityconnectors.framework.common.objects.AttributeInfo; +import org.identityconnectors.framework.common.objects.AttributeInfo.Flags; +import org.identityconnectors.framework.common.objects.AttributeInfoBuilder; +import org.identityconnectors.framework.common.objects.ObjectClassInfo; +import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder; + +// Parameters: +// The connector sends the following: +// action: a string describing the action ("SCHEMA" here) +// log: a handler to the Log facility +// builder: SchemaBuilder instance for the connector +// +// The connector will make the final call to builder.build() +// so the scipt just need to declare the different object types. + +// This sample shows how to create 3 basic ObjectTypes: __ACCOUNT__, __GROUP__ and organization. +// Each of them contains one required attribute and normal String attributes + + +log.info("Entering " + action + " Script"); + +idAIB = new AttributeInfoBuilder("id", String.class); +idAIB.setRequired(true); + +orgAttrsInfo = new HashSet<AttributeInfo>(); +orgAttrsInfo.add(idAIB.build()); +orgAttrsInfo.add(AttributeInfoBuilder.build("location", String.class)); +// Create the organization Object class +ObjectClassInfo ociOrg = new ObjectClassInfoBuilder().setType("__PRINTER__").addAllAttributeInfo(orgAttrsInfo).build(); +builder.defineObjectClass(ociOrg); + +log.info("Schema script done"); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy new file mode 100644 index 0000000..cc0dd65 --- /dev/null +++ b/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy @@ -0,0 +1,94 @@ +/* + * 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. + */ +import groovy.sql.Sql; +import groovy.sql.DataSet; + +// Parameters: +// The connector sends the following: +// connection: handler to the SQL connection +// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) +// action: a string describing the action ("SEARCH" here) +// log: a handler to the Log facility +// options: a handler to the OperationOptions Map +// query: a handler to the Query Map +// +// The Query map describes the filter used. +// +// query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ] +// query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ] +// query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ] +// query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ] +// query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ] +// query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ] +// query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ] +// query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ] +// query = null : then we assume we fetch everything +// +// AND and OR filter just embed a left/right couple of queries. +// query = [ operation: "AND", left: query1, right: query2 ] +// query = [ operation: "OR", left: query1, right: query2 ] +// +// Returns: A list of Maps. Each map describing one row. +// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute. +// This is required to build a ConnectorObject. + +log.info("Entering " + action + " Script"); + +def sql = new Sql(connection); +def result = [] +def where = ""; + +if (query != null) { + // Need to handle the __UID__ in queries + if (query.get("left").equalsIgnoreCase("__UID__") && objectClass.equalsIgnoreCase("__PRINTER__")) { + query.put("left","id") + } + + // We can use Groovy template engine to generate our custom SQL queries + def engine = new groovy.text.SimpleTemplateEngine(); + + def whereTemplates = [ + CONTAINS:' WHERE $left ${not ? "NOT " : ""}LIKE "%$right%"', + ENDSWITH:' WHERE $left ${not ? "NOT " : ""}LIKE "%$right"', + STARTSWITH:' WHERE $left ${not ? "NOT " : ""}LIKE "$right%"', + EQUALS:' WHERE $left ${not ? "<>" : "="} \'$right\'', + GREATERTHAN:' WHERE $left ${not ? "<=" : ">"} "$right"', + GREATERTHANOREQUAL:' WHERE $left ${not ? "<" : ">="} "$right"', + LESSTHAN:' WHERE $left ${not ? ">=" : "<"} "$right"', + LESSTHANOREQUAL:' WHERE $left ${not ? ">" : "<="} "$right"' + ] + + def wt = whereTemplates.get(query.get("operation")); + def binding = [left:query.get("left"),right:query.get("right"),not:query.get("not")]; + def template = engine.createTemplate(wt).make(binding); + where = template.toString(); + log.ok("Search WHERE clause is: "+ where) +} + +switch ( objectClass ) { +case "__PRINTER__": + sql.eachRow("SELECT * FROM TESTPRINTER " + where, + {result.add([__UID__:it.id, __NAME__:it.id, location:it.location])} ); + break + +default: + result; +} + +return result; http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy new file mode 100644 index 0000000..6060870 --- /dev/null +++ b/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy @@ -0,0 +1,98 @@ +/* + * 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. + */ +import groovy.sql.Sql; +import groovy.sql.DataSet; + +// Parameters: +// The connector sends the following: +// connection: handler to the SQL connection +// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) +// action: a string describing the action ("SYNC" or "GET_LATEST_SYNC_TOKEN" here) +// log: a handler to the Log facility +// options: a handler to the OperationOptions Map (null if action = "GET_LATEST_SYNC_TOKEN") +// token: a handler to an Object representing the sync token (null if action = "GET_LATEST_SYNC_TOKEN") +// +// +// Returns: +// if action = "GET_LATEST_SYNC_TOKEN", it must return an object representing the last known +// sync token for the corresponding ObjectClass +// +// if action = "SYNC": +// A list of Maps . Each map describing one update: +// Map should look like the following: +// +// [ +// "token": <Object> token object (could be Integer, Date, String) , [!! could be null] +// "operation":<String> ("CREATE_OR_UPDATE"|"DELETE") will always default to CREATE_OR_DELETE , +// "uid":<String> uid (uid of the entry) , +// "previousUid":<String> prevuid (This is for rename ops) , +// "password":<String> password (optional... allows to pass clear text password if needed), +// "attributes":Map<String,List> of attributes name/values +// ] + +log.info("Entering " + action + " Script"); +def sql = new Sql(connection); + +if (action.equalsIgnoreCase("GET_LATEST_SYNC_TOKEN")) { + switch (objectClass) { + case "__PRINTER__": + row = sql.firstRow("SELECT lastmodification FROM TESTPRINTER ORDER BY lastmodification DESC"); + log.ok("Get Latest Sync Token script: last token is: " + row["lastmodification"]) + break; + + default: + row = null; + } + + return row == null ? null : row["lastmodification"].getTime(); +} else if (action.equalsIgnoreCase("SYNC")) { + def result = []; + def lastmodification = null; + if (token != null) { + lastmodification = new Date(token); + } else { + lastmodification = new Date(0); + } + + switch (objectClass) { + case "__PRINTER__": + sql.eachRow("SELECT * FROM TESTPRINTER WHERE lastmodification > ${lastmodification}", + { + result.add([ + operation:"CREATE_OR_UPDATE", + uid:it.id.toString(), + token:it.lastmodification.getTime(), + attributes:[ + __UID__:it.id.toString(), + __NAME__:it.id.toString(), + id:it.id.toString(), + location:it.location + ] + ]); + } + ) + break; + } + + log.ok("Sync script: found " + result.size() + " events to sync"); + return result; +} else { + log.error("Sync script: action '" + action + "' is not implemented in this script"); + return null; +} http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy new file mode 100644 index 0000000..5b8f4b5 --- /dev/null +++ b/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy @@ -0,0 +1,31 @@ +/* + * 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. + */ +import groovy.sql.Sql; +import groovy.sql.DataSet; + +// Parameters: +// The connector sends the following: +// connection: handler to the SQL connection +// action: a string describing the action ("TEST" here) +// log: a handler to the Log facility + +log.info("Entering " + action + " Script"); +def sql = new Sql(connection); + +sql.eachRow("select * from TESTPRINTER", { println it.uid} ); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy new file mode 100644 index 0000000..f3155cb --- /dev/null +++ b/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy @@ -0,0 +1,67 @@ +/* + * 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. + */ +import groovy.sql.Sql; +import groovy.sql.DataSet; + +// Parameters: +// The connector sends us the following: +// connection : SQL connection +// +// action: String correponding to the action (UPDATE/ADD_ATTRIBUTE_VALUES/REMOVE_ATTRIBUTE_VALUES) +// - UPDATE : For each input attribute, replace all of the current values of that attribute +// in the target object with the values of that attribute. +// - ADD_ATTRIBUTE_VALUES: For each attribute that the input set contains, add to the current values +// of that attribute in the target object all of the values of that attribute in the input set. +// - REMOVE_ATTRIBUTE_VALUES: For each attribute that the input set contains, remove from the current values +// of that attribute in the target object any value that matches one of the values of the attribute from the input set. + +// log: a handler to the Log facility +// +// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) +// +// uid: a String representing the entry uid +// +// attributes: an Attribute Map, containg the <String> attribute name as a key +// and the <List> attribute value(s) as value. +// +// password: password string, clear text (only for UPDATE) +// +// options: a handler to the OperationOptions Map + +log.info("Entering " + action + " Script"); +def sql = new Sql(connection); + + +switch (action) { +case "UPDATE": + if (attributes.get("location").get(0) != null) { + sql.executeUpdate("UPDATE TESTPRINTER SET location = ?, lastmodification = ? where id = ?", + [attributes.get("location").get(0), new Date(), attributes.get("__NAME__").get(0)]) + + return attributes.get("__NAME__").get(0); + } + break + +case "ADD_ATTRIBUTE_VALUES": + break + + +default: + sql +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java index 8cfec8b..efe1b16 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractITCase.java @@ -35,11 +35,13 @@ import org.apache.commons.lang3.StringUtils; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.client.lib.SyncopeClientFactoryBean; +import org.apache.syncope.common.lib.mod.AnyObjectMod; import org.apache.syncope.common.lib.mod.AttrMod; import org.apache.syncope.common.lib.mod.GroupMod; import org.apache.syncope.common.lib.mod.UserMod; import org.apache.syncope.common.lib.to.AbstractPolicyTO; import org.apache.syncope.common.lib.to.AbstractSchemaTO; +import org.apache.syncope.common.lib.to.AnyObjectTO; import org.apache.syncope.common.lib.to.AttrTO; import org.apache.syncope.common.lib.to.ResourceTO; import org.apache.syncope.common.lib.to.GroupTO; @@ -48,6 +50,7 @@ import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.ConnConfProperty; import org.apache.syncope.common.lib.types.SchemaType; import org.apache.syncope.common.rest.api.RESTHeaders; +import org.apache.syncope.common.rest.api.service.AnyObjectService; import org.apache.syncope.common.rest.api.service.AnyTypeClassService; import org.apache.syncope.common.rest.api.service.AnyTypeService; import org.apache.syncope.common.rest.api.service.CamelRouteService; @@ -141,6 +144,8 @@ public abstract class AbstractITCase { protected static final String RESOURCE_NAME_CREATE_NONE = "ws-target-resource-create-none"; + protected static final String RESOURCE_NAME_DBSCRIPTED = "resource-db-scripted"; + protected static String ANONYMOUS_UNAME; protected static String ANONYMOUS_KEY; @@ -155,6 +160,8 @@ public abstract class AbstractITCase { protected static RealmService realmService; + protected static AnyObjectService anyObjectService; + protected static RoleService roleService; protected static UserService userService; @@ -226,6 +233,7 @@ public abstract class AbstractITCase { anyTypeClassService = adminClient.getService(AnyTypeClassService.class); anyTypeService = adminClient.getService(AnyTypeService.class); realmService = adminClient.getService(RealmService.class); + anyObjectService = adminClient.getService(AnyObjectService.class); roleService = adminClient.getService(RoleService.class); userService = adminClient.getService(UserService.class); userSelfService = adminClient.getService(UserSelfService.class); @@ -287,8 +295,8 @@ public abstract class AbstractITCase { return userService.update(userMod.getKey(), userMod).readEntity(UserTO.class); } - protected UserTO deleteUser(final Long id) { - return userService.delete(id).readEntity(UserTO.class); + protected UserTO deleteUser(final Long key) { + return userService.delete(key).readEntity(UserTO.class); } public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) { @@ -322,6 +330,25 @@ public abstract class AbstractITCase { return getObject(response.getLocation(), RoleService.class, RoleTO.class); } + protected AnyObjectTO createAnyObject(final AnyObjectTO anyObjectTO) { + Response response = anyObjectService.create(anyObjectTO); + if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) { + Exception ex = clientFactory.getExceptionMapper().fromResponse(response); + if (ex != null) { + throw (RuntimeException) ex; + } + } + return getObject(response.getLocation(), AnyObjectService.class, AnyObjectTO.class); + } + + protected AnyObjectTO updateAnyObject(final AnyObjectMod anyObjectMod) { + return anyObjectService.update(anyObjectMod.getKey(), anyObjectMod).readEntity(AnyObjectTO.class); + } + + protected AnyObjectTO deleteAnyObject(final Long key) { + return anyObjectService.delete(key).readEntity(AnyObjectTO.class); + } + protected GroupTO createGroup(final GroupTO groupTO) { Response response = groupService.create(groupTO); if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) { @@ -337,8 +364,8 @@ public abstract class AbstractITCase { return groupService.update(groupMod.getKey(), groupMod).readEntity(GroupTO.class); } - protected GroupTO deleteGroup(final Long id) { - return groupService.delete(id).readEntity(GroupTO.class); + protected GroupTO deleteGroup(final Long key) { + return groupService.delete(key).readEntity(GroupTO.class); } @SuppressWarnings("unchecked")
