Repository: syncope Updated Branches: refs/heads/2_0_X 5c8975f02 -> 379e3e45c refs/heads/master 5cab8afc9 -> f1d294d6f
[SYNCOPE-980] Fix parenthesis for some subqueries, including memberships Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/c4ed6e98 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/c4ed6e98 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/c4ed6e98 Branch: refs/heads/2_0_X Commit: c4ed6e9838d2d174b684b414ca2310f3de6533a4 Parents: 5c8975f Author: Francesco Chicchiriccò <ilgro...@apache.org> Authored: Wed Dec 7 13:26:55 2016 +0100 Committer: Francesco Chicchiriccò <ilgro...@apache.org> Committed: Wed Dec 7 13:26:55 2016 +0100 ---------------------------------------------------------------------- .../persistence/api/dao/search/SearchCond.java | 91 +++++++------- .../persistence/jpa/dao/JPAAnySearchDAO.java | 123 +++++++++---------- .../persistence/jpa/inner/AnySearchTest.java | 69 ++++++++++- .../apache/syncope/fit/core/SearchITCase.java | 43 +++++++ 4 files changed, 216 insertions(+), 110 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/c4ed6e98/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java ---------------------------------------------------------------------- diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java index 61cc664..e87df92 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java @@ -55,9 +55,9 @@ public class SearchCond extends AbstractSearchCond { private MemberCond memberCond; - private SearchCond leftNodeCond; + private SearchCond leftSearchCond; - private SearchCond rightNodeCond; + private SearchCond rightSearchCond; public static SearchCond getLeafCond(final AnyTypeCond anyTypeCond) { SearchCond nodeCond = new SearchCond(); @@ -189,8 +189,8 @@ public class SearchCond extends AbstractSearchCond { SearchCond nodeCond = new SearchCond(); nodeCond.type = Type.AND; - nodeCond.leftNodeCond = leftCond; - nodeCond.rightNodeCond = rightCond; + nodeCond.leftSearchCond = leftCond; + nodeCond.rightSearchCond = rightCond; return nodeCond; } @@ -208,8 +208,8 @@ public class SearchCond extends AbstractSearchCond { SearchCond nodeCond = new SearchCond(); nodeCond.type = Type.OR; - nodeCond.leftNodeCond = leftCond; - nodeCond.rightNodeCond = rightCond; + nodeCond.leftSearchCond = leftCond; + nodeCond.rightSearchCond = rightCond; return nodeCond; } @@ -231,6 +231,42 @@ public class SearchCond extends AbstractSearchCond { this.anyTypeCond = anyTypeCond; } + /** + * Not a simple getter: recursively scans the search condition tree. + * + * @return the AnyType key or {@code NULL} if no type condition was found + */ + public String hasAnyTypeCond() { + String anyTypeName = null; + + if (type == null) { + return anyTypeName; + } + + switch (type) { + case LEAF: + case NOT_LEAF: + if (anyTypeCond != null) { + anyTypeName = anyTypeCond.getAnyTypeKey(); + } + break; + + case AND: + case OR: + if (leftSearchCond != null) { + anyTypeName = leftSearchCond.hasAnyTypeCond(); + } + if (anyTypeName == null && rightSearchCond != null) { + anyTypeName = rightSearchCond.hasAnyTypeCond(); + } + break; + + default: + } + + return anyTypeName; + } + public AnyCond getAnyCond() { return anyCond; } @@ -267,49 +303,18 @@ public class SearchCond extends AbstractSearchCond { return memberCond; } - public SearchCond getLeftNodeCond() { - return leftNodeCond; + public SearchCond getLeftSearchCond() { + return leftSearchCond; } - public SearchCond getRightNodeCond() { - return rightNodeCond; + public SearchCond getRightSearchCond() { + return rightSearchCond; } public Type getType() { return type; } - public String hasAnyTypeCond() { - String anyTypeName = null; - - if (type == null) { - return anyTypeName; - } - - switch (type) { - case LEAF: - case NOT_LEAF: - if (anyTypeCond != null) { - anyTypeName = anyTypeCond.getAnyTypeKey(); - } - break; - - case AND: - case OR: - if (leftNodeCond != null) { - anyTypeName = leftNodeCond.hasAnyTypeCond(); - } - if (anyTypeName == null && rightNodeCond != null) { - anyTypeName = rightNodeCond.hasAnyTypeCond(); - } - break; - - default: - } - - return anyTypeName; - } - @Override public boolean isValid() { boolean isValid = false; @@ -335,9 +340,9 @@ public class SearchCond extends AbstractSearchCond { case AND: case OR: - isValid = (leftNodeCond == null || rightNodeCond == null) + isValid = (leftSearchCond == null || rightSearchCond == null) ? false - : leftNodeCond.isValid() && rightNodeCond.isValid(); + : leftSearchCond.isValid() && rightSearchCond.isValid(); break; default: http://git-wip-us.apache.org/repos/asf/syncope/blob/c4ed6e98/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java index 3f8e5bd..9554f9a 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java @@ -135,12 +135,12 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO } @Override - public int count(final Set<String> adminRealms, final SearchCond searchCondition, final AnyTypeKind typeKind) { + public int count(final Set<String> adminRealms, final SearchCond cond, final AnyTypeKind typeKind) { List<Object> parameters = Collections.synchronizedList(new ArrayList<>()); // 1. get the query string from the search condition SearchSupport svs = new SearchSupport(typeKind); - StringBuilder queryString = getQuery(searchCondition, parameters, svs); + StringBuilder queryString = getQuery(cond, parameters, svs); // 2. take into account administrative realms queryString.insert(0, "SELECT u.any_id FROM ("); @@ -166,35 +166,35 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO } @Override - public <T extends Any<?>> List<T> search(final SearchCond searchCondition, final AnyTypeKind typeKind) { - return search(searchCondition, Collections.<OrderByClause>emptyList(), typeKind); + public <T extends Any<?>> List<T> search(final SearchCond cond, final AnyTypeKind typeKind) { + return search(cond, Collections.<OrderByClause>emptyList(), typeKind); } @Override public <T extends Any<?>> List<T> search( - final SearchCond searchCondition, final List<OrderByClause> orderBy, final AnyTypeKind typeKind) { + final SearchCond cond, final List<OrderByClause> orderBy, final AnyTypeKind typeKind) { - return search(SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, -1, -1, orderBy, typeKind); + return search(SyncopeConstants.FULL_ADMIN_REALMS, cond, -1, -1, orderBy, typeKind); } @Override public <T extends Any<?>> List<T> search( - final Set<String> adminRealms, final SearchCond searchCondition, final int page, final int itemsPerPage, + final Set<String> adminRealms, final SearchCond cond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy, final AnyTypeKind typeKind) { List<T> result = Collections.<T>emptyList(); if (adminRealms != null && !adminRealms.isEmpty()) { - LOG.debug("Search condition:\n{}", searchCondition); + LOG.debug("Search condition:\n{}", cond); - if (searchCondition != null && searchCondition.isValid()) { + if (cond != null && cond.isValid()) { try { - result = doSearch(adminRealms, searchCondition, page, itemsPerPage, orderBy, typeKind); + result = doSearch(adminRealms, cond, page, itemsPerPage, orderBy, typeKind); } catch (Exception e) { LOG.error("While searching for {}", typeKind, e); } } else { - LOG.error("Invalid search condition:\n{}", searchCondition); + LOG.error("Invalid search condition:\n{}", cond); } } @@ -203,13 +203,13 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO @Override public <T extends Any<?>> boolean matches( - final T any, final SearchCond searchCondition, final AnyTypeKind typeKind) { + final T any, final SearchCond cond, final AnyTypeKind typeKind) { List<Object> parameters = Collections.synchronizedList(new ArrayList<>()); // 1. get the query string from the search condition SearchSupport svs = new SearchSupport(typeKind); - StringBuilder queryString = getQuery(searchCondition, parameters, svs); + StringBuilder queryString = getQuery(cond, parameters, svs); boolean matches; if (queryString.length() == 0) { @@ -369,14 +369,14 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO @SuppressWarnings("unchecked") private <T extends Any<?>> List<T> doSearch(final Set<String> adminRealms, - final SearchCond nodeCond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy, + final SearchCond cond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy, final AnyTypeKind typeKind) { List<Object> parameters = Collections.synchronizedList(new ArrayList<>()); // 1. get the query string from the search condition SearchSupport svs = new SearchSupport(typeKind); - StringBuilder queryString = getQuery(nodeCond, parameters, svs); + StringBuilder queryString = getQuery(cond, parameters, svs); // 2. take into account administrative groups and ordering OrderBySupport orderBySupport = parseOrderBy(typeKind, svs, orderBy); @@ -428,68 +428,67 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO return result; } - private StringBuilder getQuery(final SearchCond nodeCond, final List<Object> parameters, final SearchSupport svs) { + private StringBuilder getQuery(final SearchCond cond, final List<Object> parameters, final SearchSupport svs) { StringBuilder query = new StringBuilder(); - switch (nodeCond.getType()) { - + switch (cond.getType()) { case LEAF: case NOT_LEAF: - if (nodeCond.getAnyTypeCond() != null && AnyTypeKind.ANY_OBJECT == svs.anyTypeKind()) { - query.append(getQuery(nodeCond.getAnyTypeCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } else if (nodeCond.getRelationshipTypeCond() != null + if (cond.getAnyTypeCond() != null && AnyTypeKind.ANY_OBJECT == svs.anyTypeKind()) { + query.append(getQuery(cond.getAnyTypeCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + } else if (cond.getRelationshipTypeCond() != null && (AnyTypeKind.USER == svs.anyTypeKind() || AnyTypeKind.ANY_OBJECT == svs.anyTypeKind())) { - query.append(getQuery(nodeCond.getRelationshipTypeCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } else if (nodeCond.getRelationshipCond() != null + query.append(getQuery(cond.getRelationshipTypeCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + } else if (cond.getRelationshipCond() != null && (AnyTypeKind.USER == svs.anyTypeKind() || AnyTypeKind.ANY_OBJECT == svs.anyTypeKind())) { - query.append(getQuery(nodeCond.getRelationshipCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } else if (nodeCond.getMembershipCond() != null + query.append(getQuery(cond.getRelationshipCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + } else if (cond.getMembershipCond() != null && (AnyTypeKind.USER == svs.anyTypeKind() || AnyTypeKind.ANY_OBJECT == svs.anyTypeKind())) { - query.append(getQuery(nodeCond.getMembershipCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } else if (nodeCond.getAssignableCond() != null) { - query.append(getQuery(nodeCond.getAssignableCond(), parameters, svs)); - } else if (nodeCond.getRoleCond() != null && AnyTypeKind.USER == svs.anyTypeKind()) { - query.append(getQuery(nodeCond.getRoleCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } else if (nodeCond.getMemberCond() != null && AnyTypeKind.GROUP == svs.anyTypeKind()) { - query.append(getQuery(nodeCond.getMemberCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } else if (nodeCond.getResourceCond() != null) { - query.append(getQuery(nodeCond.getResourceCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } else if (nodeCond.getAttributeCond() != null) { - query.append(getQuery(nodeCond.getAttributeCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); - } else if (nodeCond.getAnyCond() != null) { - query.append(getQuery(nodeCond.getAnyCond(), - nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + query.append(getQuery(cond.getMembershipCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + } else if (cond.getAssignableCond() != null) { + query.append(getQuery(cond.getAssignableCond(), parameters, svs)); + } else if (cond.getRoleCond() != null && AnyTypeKind.USER == svs.anyTypeKind()) { + query.append(getQuery(cond.getRoleCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + } else if (cond.getMemberCond() != null && AnyTypeKind.GROUP == svs.anyTypeKind()) { + query.append(getQuery(cond.getMemberCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + } else if (cond.getResourceCond() != null) { + query.append(getQuery(cond.getResourceCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + } else if (cond.getAttributeCond() != null) { + query.append(getQuery(cond.getAttributeCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); + } else if (cond.getAnyCond() != null) { + query.append(getQuery(cond.getAnyCond(), + cond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs)); } break; case AND: - String andSubQuery = getQuery(nodeCond.getLeftNodeCond(), parameters, svs).toString(); + String andSubQuery = getQuery(cond.getLeftSearchCond(), parameters, svs).toString(); // Add extra parentheses andSubQuery = andSubQuery.replaceFirst("WHERE ", "WHERE ("); query.append(andSubQuery). append(" AND any_id IN ( "). - append(getQuery(nodeCond.getRightNodeCond(), parameters, svs)). + append(getQuery(cond.getRightSearchCond(), parameters, svs)). append("))"); break; case OR: - String orSubQuery = getQuery(nodeCond.getLeftNodeCond(), parameters, svs).toString(); + String orSubQuery = getQuery(cond.getLeftSearchCond(), parameters, svs).toString(); // Add extra parentheses orSubQuery = orSubQuery.replaceFirst("WHERE ", "WHERE ("); query.append(orSubQuery). append(" OR any_id IN ( "). - append(getQuery(nodeCond.getRightNodeCond(), parameters, svs)). + append(getQuery(cond.getRightSearchCond(), parameters, svs)). append("))"); break; @@ -585,7 +584,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO } StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM "). - append(svs.field().name).append(" WHERE "); + append(svs.field().name).append(" WHERE ("); if (not) { query.append("any_id NOT IN ("); @@ -596,7 +595,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO query.append("SELECT DISTINCT any_id FROM "). append(svs.membership().name).append(" WHERE "). append("group_id=?").append(setParameter(parameters, groupKey)). - append(')'); + append(") "); if (not) { query.append("AND any_id NOT IN ("); @@ -607,7 +606,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO query.append("SELECT DISTINCT any_id FROM "). append(svs.dyngroupmembership().name).append(" WHERE "). append("group_id=?").append(setParameter(parameters, groupKey)). - append(')'); + append("))"); return query.toString(); } @@ -616,7 +615,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO final SearchSupport svs) { StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM "). - append(svs.field().name).append(" WHERE "); + append(svs.field().name).append(" WHERE ("); if (not) { query.append("any_id NOT IN ("); @@ -627,7 +626,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO query.append("SELECT DISTINCT any_id FROM "). append(svs.role().name).append(" WHERE "). append("role_id=?").append(setParameter(parameters, cond.getRoleKey())). - append(')'); + append(") "); if (not) { query.append("AND any_id NOT IN ("); @@ -638,7 +637,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO query.append("SELECT DISTINCT any_id FROM "). append(svs.dynrolemembership().name).append(" WHERE "). append("role_id=?").append(setParameter(parameters, cond.getRoleKey())). - append(')'); + append("))"); return query.toString(); } @@ -723,20 +722,20 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO } query.append("SELECT DISTINCT group_id AS any_id FROM "). - append(new SearchSupport(AnyTypeKind.USER).membership().name).append(" WHERE "). + append(new SearchSupport(AnyTypeKind.USER).membership().name).append(" WHERE ("). append("any_id=?").append(setParameter(parameters, memberKey)). - append(')'); + append(") "); if (not) { - query.append(" AND any_id NOT IN ("); + query.append("AND any_id NOT IN ("); } else { - query.append(" OR any_id IN ("); + query.append("OR any_id IN ("); } query.append("SELECT DISTINCT group_id AS any_id FROM "). append(new SearchSupport(AnyTypeKind.ANY_OBJECT).membership().name).append(" WHERE "). append("any_id=?").append(setParameter(parameters, memberKey)). - append(')'); + append("))"); return query.toString(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/c4ed6e98/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java index 1e59280..429dfb5 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java @@ -35,6 +35,8 @@ import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; +import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; +import org.apache.syncope.core.persistence.api.dao.RealmDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.dao.search.AttributeCond; import org.apache.syncope.core.persistence.api.dao.search.MembershipCond; @@ -49,6 +51,8 @@ import org.apache.syncope.core.persistence.api.dao.search.MemberCond; import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond; import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond; import org.apache.syncope.core.persistence.api.entity.Any; +import org.apache.syncope.core.persistence.api.entity.AnyType; +import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; import org.apache.syncope.core.persistence.api.entity.user.User; @@ -72,6 +76,12 @@ public class AnySearchTest extends AbstractTest { @Autowired private AnySearchDAO searchDAO; + @Autowired + private AnyTypeDAO anyTypeDAO; + + @Autowired + private RealmDAO realmDAO; + @Test public void anyObjectMatch() { AnyObject anyObject = anyObjectDAO.find("fc6dbc3a-6c07-4965-8781-921e7401a4a5"); @@ -474,20 +484,20 @@ public class AnySearchTest extends AbstractTest { SearchCond.getLeafCond(relationshipTypeCond), SearchCond.getLeafCond(tcond)); assertTrue(searchCondition.isValid()); - List<Any<?>> matching = searchDAO.search(searchCondition, AnyTypeKind.ANY_OBJECT); + List<AnyObject> matching = searchDAO.search(searchCondition, AnyTypeKind.ANY_OBJECT); assertNotNull(matching); assertEquals(2, matching.size()); - assertTrue(IterableUtils.matchesAny(matching, new Predicate<Any<?>>() { + assertTrue(IterableUtils.matchesAny(matching, new Predicate<AnyObject>() { @Override - public boolean evaluate(final Any<?> any) { + public boolean evaluate(final AnyObject any) { return "fc6dbc3a-6c07-4965-8781-921e7401a4a5".equals(any.getKey()); } })); - assertTrue(IterableUtils.matchesAny(matching, new Predicate<Any<?>>() { + assertTrue(IterableUtils.matchesAny(matching, new Predicate<AnyObject>() { @Override - public boolean evaluate(final Any<?> any) { + public boolean evaluate(final AnyObject any) { return "8559d14d-58c2-46eb-a2d4-a7d35161e8f8".equals(any.getKey()); } })); @@ -696,4 +706,53 @@ public class AnySearchTest extends AbstractTest { assertNotNull(users); assertEquals(1, users.size()); } + + @Test + public void issueSYNCOPE980() { + AnyType service = entityFactory.newEntity(AnyType.class); + service.setKey("SERVICE"); + service.setKind(AnyTypeKind.ANY_OBJECT); + service = anyTypeDAO.save(service); + + Group citizen = groupDAO.findByName("citizen"); + assertNotNull(citizen); + + AnyObject anyObject = entityFactory.newEntity(AnyObject.class); + anyObject.setName("one"); + anyObject.setType(service); + anyObject.setRealm(realmDAO.findByFullPath(SyncopeConstants.ROOT_REALM)); + + AMembership membership = entityFactory.newEntity(AMembership.class); + membership.setRightEnd(citizen); + membership.setLeftEnd(anyObject); + + anyObject.add(membership); + anyObjectDAO.save(anyObject); + + anyObject = anyObjectDAO.find("fc6dbc3a-6c07-4965-8781-921e7401a4a5"); + membership = entityFactory.newEntity(AMembership.class); + membership.setRightEnd(citizen); + membership.setLeftEnd(anyObject); + anyObject.add(membership); + anyObjectDAO.save(anyObject); + + anyObjectDAO.flush(); + + MembershipCond groupCond = new MembershipCond(); + groupCond.setGroup("citizen"); + + SearchCond searchCondition = SearchCond.getLeafCond(groupCond); + + List<AnyObject> matching = searchDAO.search(searchCondition, AnyTypeKind.ANY_OBJECT); + assertEquals(2, matching.size()); + + AnyTypeCond anyTypeCond = new AnyTypeCond(); + anyTypeCond.setAnyTypeKey(service.getKey()); + + searchCondition = SearchCond.getAndCond( + SearchCond.getLeafCond(groupCond), SearchCond.getLeafCond(anyTypeCond)); + + matching = searchDAO.search(searchCondition, AnyTypeKind.ANY_OBJECT); + assertEquals(1, matching.size()); + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/c4ed6e98/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java index b7f6558..c652cde 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java @@ -30,11 +30,16 @@ import org.apache.commons.collections4.IterableUtils; import org.apache.commons.collections4.Predicate; import org.apache.syncope.client.lib.SyncopeClient; import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.common.lib.patch.AnyObjectPatch; +import org.apache.syncope.common.lib.patch.MembershipPatch; import org.apache.syncope.common.lib.to.AnyObjectTO; +import org.apache.syncope.common.lib.to.AnyTypeTO; import org.apache.syncope.common.lib.to.PagedResult; import org.apache.syncope.common.lib.to.GroupTO; +import org.apache.syncope.common.lib.to.MembershipTO; import org.apache.syncope.common.lib.to.RoleTO; import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.rest.api.beans.AnyQuery; import org.apache.syncope.common.rest.api.service.RoleService; import org.apache.syncope.fit.AbstractITCase; @@ -478,4 +483,42 @@ public class SearchITCase extends AbstractITCase { assertTrue(user.getUsername().startsWith("bellini")); } } + + @Test + public void issueSYNCOPE980() { + AnyTypeTO service = new AnyTypeTO(); + service.setKey("SERVICE"); + service.setKind(AnyTypeKind.ANY_OBJECT); + Response response = anyTypeService.create(service); + assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode()); + + String serviceKey = null; + try { + AnyObjectTO anyObjectTO = new AnyObjectTO(); + anyObjectTO.setName("one"); + anyObjectTO.setRealm(SyncopeConstants.ROOT_REALM); + anyObjectTO.setType(service.getKey()); + anyObjectTO.getMemberships().add( + new MembershipTO.Builder().group("29f96485-729e-4d31-88a1-6fc60e4677f3").build()); + serviceKey = createAnyObject(anyObjectTO).getEntity().getKey(); + + AnyObjectPatch anyObjectPatch = new AnyObjectPatch(); + anyObjectPatch.setKey("fc6dbc3a-6c07-4965-8781-921e7401a4a5"); + anyObjectPatch.getMemberships().add( + new MembershipPatch.Builder().group("29f96485-729e-4d31-88a1-6fc60e4677f3").build()); + updateAnyObject(anyObjectPatch); + + PagedResult<AnyObjectTO> matching = anyObjectService.search(new AnyQuery.Builder().fiql( + SyncopeClient.getAnyObjectSearchConditionBuilder(service.getKey()). + inGroups("29f96485-729e-4d31-88a1-6fc60e4677f3"). + query()).build()); + assertEquals(1, matching.getSize()); + assertEquals(serviceKey, matching.getResult().get(0).getKey()); + } finally { + if (serviceKey != null) { + anyObjectService.delete(serviceKey); + } + anyTypeService.delete(service.getKey()); + } + } }