You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2019/10/24 15:30:08 UTC
[syncope] branch master updated: [SYNCOPE-1501] Now isNullValue /
isNotNullValue are working as well
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new 4d5284f [SYNCOPE-1501] Now isNullValue / isNotNullValue are working as well
4d5284f is described below
commit 4d5284fa7acf9ad4515e62cbc1014997e8a4018b
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Thu Oct 24 17:24:53 2019 +0200
[SYNCOPE-1501] Now isNullValue / isNotNullValue are working as well
---
.../apache/syncope/core/logic/ResourceLogic.java | 6 ++-
.../core/rest/cxf/service/ResourceServiceImpl.java | 5 +++
.../core/persistence/api/search/FilterVisitor.java | 51 +++++++++++++++-------
.../api/search/FilterConverterTest.java | 19 ++++----
.../core/provisioning/java/utils/MappingUtils.java | 11 ++++-
.../org/apache/syncope/fit/core/SearchITCase.java | 39 ++++++++++++-----
pom.xml | 2 +-
7 files changed, 94 insertions(+), 39 deletions(-)
diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
index 29befbf..ca512cb 100644
--- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
+++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ResourceLogic.java
@@ -346,6 +346,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
@Transactional(readOnly = true)
public Pair<SearchResult, List<ConnObjectTO>> searchConnObjects(
final Filter filter,
+ final Set<String> moreAttrsToGet,
final String key,
final String anyTypeKey,
final int size,
@@ -365,7 +366,8 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
}
objectClass = resource.getOrgUnit().getObjectClass();
- options = MappingUtils.buildOperationOptions(resource.getOrgUnit().getItems().stream());
+ options = MappingUtils.buildOperationOptions(
+ resource.getOrgUnit().getItems().stream(), moreAttrsToGet.toArray(new String[0]));
} else {
Provision provision = getProvision(key, anyTypeKey);
resource = provision.getResource();
@@ -374,7 +376,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
Stream<MappingItem> mapItems = Stream.concat(
provision.getMapping().getItems().stream(),
virSchemaDAO.findByProvision(provision).stream().map(VirSchema::asLinkingMappingItem));
- options = MappingUtils.buildOperationOptions(mapItems);
+ options = MappingUtils.buildOperationOptions(mapItems, moreAttrsToGet.toArray(new String[0]));
}
List<ConnObjectTO> connObjects = new ArrayList<>();
diff --git a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
index 3eb8954..beb377a 100644
--- a/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
+++ b/core/idm/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ResourceServiceImpl.java
@@ -19,8 +19,10 @@
package org.apache.syncope.core.rest.cxf.service;
import java.net.URI;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
@@ -102,6 +104,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
final String key, final String anyTypeKey, final ConnObjectTOQuery query) {
Filter filter = null;
+ Set<String> moreAttrsToGet = Collections.emptySet();
if (StringUtils.isNotBlank(query.getFiql())) {
try {
FilterVisitor visitor = new FilterVisitor();
@@ -109,6 +112,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
sc.accept(visitor);
filter = visitor.getQuery();
+ moreAttrsToGet = visitor.getAttrs();
} catch (Exception e) {
LOG.error("Invalid FIQL expression: {}", query.getFiql(), e);
@@ -121,6 +125,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
Pair<SearchResult, List<ConnObjectTO>> list = logic.searchConnObjects(
filter,
+ moreAttrsToGet,
key,
anyTypeKey,
query.getSize(),
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/FilterVisitor.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/FilterVisitor.java
index 8a159d4..c9720e9 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/FilterVisitor.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/search/FilterVisitor.java
@@ -21,8 +21,11 @@ package org.apache.syncope.core.persistence.api.search;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.jaxrs.ext.search.ConditionType;
import org.apache.cxf.jaxrs.ext.search.SearchBean;
import org.apache.cxf.jaxrs.ext.search.SearchCondition;
@@ -40,6 +43,8 @@ public class FilterVisitor extends AbstractSearchConditionVisitor<SearchBean, Fi
private Filter filter;
+ private final Set<String> attrs = new HashSet<>();
+
public FilterVisitor() {
super(null);
}
@@ -72,6 +77,7 @@ public class FilterVisitor extends AbstractSearchConditionVisitor<SearchBean, Fi
}
Attribute attr = AttributeBuilder.build(name, value);
+ attrs.add(name);
Filter leaf;
switch (ct) {
@@ -79,28 +85,37 @@ public class FilterVisitor extends AbstractSearchConditionVisitor<SearchBean, Fi
case NOT_EQUALS:
if (!specialAttrName.isPresent()) {
if (specialAttrValue.isPresent() && specialAttrValue.get() == SpecialAttr.NULL) {
- leaf = FilterBuilder.equalTo(AttributeBuilder.build(name));
- } else if (value.indexOf('%') == -1) {
- leaf = sc.getConditionType() == ConditionType.CUSTOM
- ? FilterBuilder.equalsIgnoreCase(attr)
- : FilterBuilder.equalTo(attr);
- } else if (sc.getConditionType() != ConditionType.CUSTOM && value.startsWith("%")) {
- leaf = FilterBuilder.endsWith(
- AttributeBuilder.build(name, value.substring(1)));
- } else if (sc.getConditionType() != ConditionType.CUSTOM && value.endsWith("%")) {
- leaf = FilterBuilder.startsWith(
- AttributeBuilder.build(name, value.substring(0, value.length() - 1)));
+ Filter empty = FilterBuilder.startsWith(AttributeBuilder.build(name, StringUtils.EMPTY));
+ if (ct == ConditionType.NOT_EQUALS) {
+ leaf = empty;
+ } else {
+ leaf = FilterBuilder.not(empty);
+ attrs.remove(name);
+ }
} else {
- throw new IllegalArgumentException(
- String.format("Unsupported search value %s", value));
+ if (value.indexOf('%') == -1) {
+ leaf = sc.getConditionType() == ConditionType.CUSTOM
+ ? FilterBuilder.equalsIgnoreCase(attr)
+ : FilterBuilder.equalTo(attr);
+ } else if (sc.getConditionType() != ConditionType.CUSTOM && value.startsWith("%")) {
+ leaf = FilterBuilder.endsWith(
+ AttributeBuilder.build(name, value.substring(1)));
+ } else if (sc.getConditionType() != ConditionType.CUSTOM && value.endsWith("%")) {
+ leaf = FilterBuilder.startsWith(
+ AttributeBuilder.build(name, value.substring(0, value.length() - 1)));
+ } else {
+ throw new IllegalArgumentException(
+ String.format("Unsupported search value %s", value));
+ }
+
+ if (ct == ConditionType.NOT_EQUALS) {
+ leaf = FilterBuilder.not(leaf);
+ }
}
} else {
throw new IllegalArgumentException(
String.format("Special attr name %s is not supported", specialAttrName));
}
- if (ct == ConditionType.NOT_EQUALS) {
- leaf = FilterBuilder.not(leaf);
- }
break;
case GREATER_OR_EQUALS:
@@ -163,4 +178,8 @@ public class FilterVisitor extends AbstractSearchConditionVisitor<SearchBean, Fi
public Filter getQuery() {
return filter;
}
+
+ public Set<String> getAttrs() {
+ return attrs;
+ }
}
diff --git a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/FilterConverterTest.java b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/FilterConverterTest.java
index 40c9b69..52834f8 100644
--- a/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/FilterConverterTest.java
+++ b/core/persistence-api/src/test/java/org/apache/syncope/core/persistence/api/search/FilterConverterTest.java
@@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.fail;
import java.util.List;
import java.util.ListIterator;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.search.SpecialAttr;
@@ -152,9 +153,14 @@ public class FilterConverterTest {
String fiql = new ConnObjectTOFiqlSearchConditionBuilder().is("loginDate").nullValue().query();
assertEquals("loginDate==" + SpecialAttr.NULL, fiql);
- Filter filter = FilterBuilder.equalTo(AttributeBuilder.build("loginDate"));
+ Filter filter = FilterBuilder.not(
+ FilterBuilder.startsWith(AttributeBuilder.build("loginDate", StringUtils.EMPTY)));
- assertTrue(equals(filter, FilterConverter.convert(fiql)));
+ Filter converted = FilterConverter.convert(fiql);
+ assertTrue(converted instanceof NotFilter);
+
+ assertTrue(equals(
+ ((NotFilter) filter).getFilter(), ((NotFilter) converted).getFilter()));
}
@Test
@@ -162,14 +168,9 @@ public class FilterConverterTest {
String fiql = new ConnObjectTOFiqlSearchConditionBuilder().is("loginDate").notNullValue().query();
assertEquals("loginDate!=" + SpecialAttr.NULL, fiql);
- Filter filter = FilterBuilder.not(FilterBuilder.equalTo(AttributeBuilder.build("loginDate")));
- assertTrue(filter instanceof NotFilter);
-
- Filter converted = FilterConverter.convert(fiql);
- assertTrue(converted instanceof NotFilter);
+ Filter filter = FilterBuilder.startsWith(AttributeBuilder.build("loginDate", StringUtils.EMPTY));
- assertTrue(equals(
- ((NotFilter) filter).getFilter(), ((NotFilter) converted).getFilter()));
+ assertTrue(equals(filter, FilterConverter.convert(fiql)));
}
@Test
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index c425d6e..cdb8280 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -19,6 +19,7 @@
package org.apache.syncope.core.provisioning.java.utils;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
@@ -26,6 +27,7 @@ import java.util.Set;
import java.util.stream.Stream;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.MappingPurpose;
import org.apache.syncope.core.persistence.api.entity.Any;
@@ -185,16 +187,23 @@ public final class MappingUtils {
* Build options for requesting all mapped connector attributes.
*
* @param items items
+ * @param moreAttrsToGet additional attributes to get
* @return options for requesting all mapped connector attributes
* @see OperationOptions
*/
- public static OperationOptions buildOperationOptions(final Stream<? extends Item> items) {
+ public static OperationOptions buildOperationOptions(
+ final Stream<? extends Item> items,
+ final String... moreAttrsToGet) {
+
OperationOptionsBuilder builder = new OperationOptionsBuilder();
Set<String> attrsToGet = new HashSet<>();
attrsToGet.add(Name.NAME);
attrsToGet.add(Uid.NAME);
attrsToGet.add(OperationalAttributes.ENABLE_NAME);
+ if (!ArrayUtils.isEmpty(moreAttrsToGet)) {
+ attrsToGet.addAll(Arrays.asList(moreAttrsToGet));
+ }
items.filter(item -> item.getPurpose() != MappingPurpose.NONE).
forEach(item -> attrsToGet.add(item.getExtAttrName()));
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 2a5d64f..6940012 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
@@ -45,7 +45,6 @@ import org.apache.syncope.common.lib.request.UserUR;
import org.apache.syncope.common.lib.request.AttrPatch;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.AnyTypeTO;
-import org.apache.syncope.common.lib.to.ConnObjectTO;
import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.to.MembershipTO;
@@ -510,16 +509,14 @@ public class SearchITCase extends AbstractITCase {
@Test
public void searchConnObjectsWithFilter() {
- ConnObjectTO user = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), "pullFromLDAP");
- assertNotNull(user);
-
PagedConnObjectTOResult matches = resourceService.searchConnObjects(
RESOURCE_NAME_LDAP,
AnyTypeKind.USER.name(),
new ConnObjectTOQuery.Builder().size(100).fiql(
SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
is("givenName").equalTo("pullFromLDAP").query()).build());
- assertTrue(matches.getResult().contains(user));
+ assertTrue(matches.getResult().stream().
+ anyMatch(connObject -> connObject.getAttr("givenName").get().getValues().contains("pullFromLDAP")));
matches = resourceService.searchConnObjects(
RESOURCE_NAME_LDAP,
@@ -527,7 +524,8 @@ public class SearchITCase extends AbstractITCase {
new ConnObjectTOQuery.Builder().size(100).fiql(
SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
is("mail").equalTo("pullFromLDAP*").query()).build());
- assertTrue(matches.getResult().contains(user));
+ assertTrue(matches.getResult().stream().
+ anyMatch(connObject -> connObject.getAttr("cn").get().getValues().contains("pullFromLDAP")));
matches = resourceService.searchConnObjects(
RESOURCE_NAME_LDAP,
@@ -535,7 +533,8 @@ public class SearchITCase extends AbstractITCase {
new ConnObjectTOQuery.Builder().size(100).fiql(
SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
is("mail").equalTo("*@syncope.apache.org").query()).build());
- assertTrue(matches.getResult().contains(user));
+ assertTrue(matches.getResult().stream().
+ anyMatch(connObject -> connObject.getAttr("cn").get().getValues().contains("pullFromLDAP")));
matches = resourceService.searchConnObjects(
RESOURCE_NAME_LDAP,
@@ -543,7 +542,8 @@ public class SearchITCase extends AbstractITCase {
new ConnObjectTOQuery.Builder().size(100).fiql(
SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
is("givenName").equalToIgnoreCase("pullfromldap").query()).build());
- assertTrue(matches.getResult().contains(user));
+ assertTrue(matches.getResult().stream().
+ anyMatch(connObject -> connObject.getAttr("givenName").get().getValues().contains("pullFromLDAP")));
matches = resourceService.searchConnObjects(
RESOURCE_NAME_LDAP,
@@ -551,7 +551,8 @@ public class SearchITCase extends AbstractITCase {
new ConnObjectTOQuery.Builder().size(100).fiql(
SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
is(Name.NAME).equalTo("uid=pullFromLDAP%252Cou=people%252Co=isp").query()).build());
- assertTrue(matches.getResult().contains(user));
+ assertTrue(matches.getResult().stream().
+ anyMatch(connObject -> connObject.getAttr("cn").get().getValues().contains("pullFromLDAP")));
matches = resourceService.searchConnObjects(
RESOURCE_NAME_LDAP,
@@ -559,7 +560,25 @@ public class SearchITCase extends AbstractITCase {
new ConnObjectTOQuery.Builder().size(100).fiql(
SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
is("givenName").notEqualTo("pullFromLDAP").query()).build());
- assertFalse(matches.getResult().contains(user));
+ assertFalse(matches.getResult().stream().
+ anyMatch(connObject -> connObject.getAttr("givenName").get().getValues().contains("pullFromLDAP")));
+
+ matches = resourceService.searchConnObjects(
+ RESOURCE_NAME_LDAP,
+ AnyTypeKind.USER.name(),
+ new ConnObjectTOQuery.Builder().size(100).fiql(
+ SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
+ is("homePhone").notNullValue().query()).build());
+ assertTrue(matches.getResult().isEmpty());
+
+ matches = resourceService.searchConnObjects(
+ RESOURCE_NAME_LDAP,
+ AnyTypeKind.USER.name(),
+ new ConnObjectTOQuery.Builder().size(100).fiql(
+ SyncopeClient.getConnObjectTOFiqlSearchConditionBuilder().
+ is("homePhone").nullValue().query()).build());
+ assertTrue(matches.getResult().stream().
+ anyMatch(connObject -> !connObject.getAttr("homePhone").isPresent()));
}
@Test
diff --git a/pom.xml b/pom.xml
index 2d3b3bc..813e15f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -387,7 +387,7 @@ under the License.
<properties>
<syncope.version>${project.version}</syncope.version>
- <connid.version>1.5.0.1</connid.version>
+ <connid.version>1.5.0.2</connid.version>
<connid.soap.version>1.4.3</connid.soap.version>
<connid.rest.version>1.0.5</connid.rest.version>
<connid.database.version>2.2.6</connid.database.version>