This is an automated email from the ASF dual-hosted git repository. nixon pushed a commit to branch branch-2.0 in repository https://gitbox.apache.org/repos/asf/atlas.git
commit ed86855dccf8a07cc17fc599fd16809f867a7743 Author: Pinal Shah <[email protected]> AuthorDate: Wed Apr 22 23:29:17 2020 +0530 ATLAS-3753 : Classification Search with wildcard in between strings causes issues. Signed-off-by: nixonrodrigues <[email protected]> (cherry picked from commit 862ba9baed7af208456e59a42466aa0894cd8a6d) --- .../apache/atlas/discovery/SearchProcessor.java | 14 +++++--- .../org/apache/atlas/util/SearchPredicateUtil.java | 41 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java index 5d7c508..11eb7ca 100644 --- a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java +++ b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java @@ -79,7 +79,6 @@ public abstract class SearchProcessor { public static final char CUSTOM_ATTR_SEPARATOR = '='; public static final String CUSTOM_ATTR_SEARCH_FORMAT = "\"\\\"%s\\\":\\\"%s\\\"\""; public static final String CUSTOM_ATTR_SEARCH_FORMAT_GRAPH = "\"%s\":\"%s\""; - public static final String WILDCARD_CHAR = "*"; private static final Map<SearchParameters.Operator, String> OPERATOR_MAP = new HashMap<>(); private static final Map<SearchParameters.Operator, VertexAttributePredicateGenerator> OPERATOR_PREDICATE_MAP = new HashMap<>(); @@ -202,10 +201,11 @@ public abstract class SearchProcessor { traitPredicate = PredicateUtils.andPredicate(SearchPredicateUtil.getIsNullOrEmptyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, null, List.class), SearchPredicateUtil.getIsNullOrEmptyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, null, List.class)); } else if (context.isWildCardSearch()) { - String wildcardName = context.getClassificationName(); - wildcardName = wildcardName.replace(WILDCARD_CHAR,""); - traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getContainsPredicateGenerator().generatePredicate(CLASSIFICATION_NAMES_KEY, wildcardName, String.class), - SearchPredicateUtil.getContainsPredicateGenerator().generatePredicate(PROPAGATED_CLASSIFICATION_NAMES_KEY, wildcardName, String.class)); + //For wildcard search __classificationNames which of String type is taken instead of _traitNames which is of Array type + //No need to escape, as classification Names only support letters,numbers,space and underscore + String regexString = getRegexString("\\|" + context.getClassificationName() + "\\|"); + traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getRegexPredicateGenerator().generatePredicate(CLASSIFICATION_NAMES_KEY, regexString, String.class), + SearchPredicateUtil.getRegexPredicateGenerator().generatePredicate(PROPAGATED_CLASSIFICATION_NAMES_KEY, regexString, String.class)); } else { traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getContainsAnyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, context.getClassificationTypes(), List.class), SearchPredicateUtil.getContainsAnyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, context.getClassificationTypes(), List.class)); @@ -849,6 +849,10 @@ public abstract class SearchProcessor { return ".*" + escapeRegExChars(attributeValue) + ".*"; } + private static String getRegexString(String value) { + return ".*" + value.replace("*", ".*") + ".*"; + } + private static String getSuffixRegex(String attributeValue) { return ".*" + escapeRegExChars(attributeValue); } diff --git a/repository/src/main/java/org/apache/atlas/util/SearchPredicateUtil.java b/repository/src/main/java/org/apache/atlas/util/SearchPredicateUtil.java index 69770c3..4408cd4 100644 --- a/repository/src/main/java/org/apache/atlas/util/SearchPredicateUtil.java +++ b/repository/src/main/java/org/apache/atlas/util/SearchPredicateUtil.java @@ -30,6 +30,8 @@ import org.slf4j.LoggerFactory; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; +import java.util.regex.Pattern; +import java.util.regex.Matcher; public class SearchPredicateUtil { private static final Logger LOG = LoggerFactory.getLogger(SearchPredicateUtil.class); @@ -420,6 +422,35 @@ public class SearchPredicateUtil { return ret; } + public static VertexAttributePredicateGenerator getRegexPredicateGenerator() { + if (LOG.isDebugEnabled()) { + LOG.debug("==> getRegexPredicateGenerator"); + } + + VertexAttributePredicateGenerator ret = new VertexAttributePredicateGenerator() { + @Override + public Predicate generatePredicate(final String attrName, final Object attrVal, final Class attrClass) { + final Predicate ret; + + if (attrName == null || attrClass == null || attrVal == null) { + ret = ALWAYS_FALSE; + } else if (String.class.isAssignableFrom(attrClass)) { + ret = StringPredicate.getRegexPredicate(attrName, attrClass, (String) attrVal); + } else { + ret = ALWAYS_FALSE; + } + + return ret; + } + }; + + if (LOG.isDebugEnabled()) { + LOG.debug("<== getRegexPredicateGenerator"); + } + + return ret; + } + public static VertexAttributePredicateGenerator getLIKEPredicateGenerator() { if (LOG.isDebugEnabled()) { LOG.debug("==> getLIKEPredicateGenerator"); @@ -1355,6 +1386,16 @@ public class SearchPredicateUtil { } }; } + + static VertexAttributePredicate getRegexPredicate(String attrName, Class attrClass, String value) { + return new StringPredicate(attrName, attrClass, value) { + protected boolean compareValue(Object vertexAttrVal) { + Pattern pattern = Pattern.compile(value, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher((String) vertexAttrVal); + return matcher.matches(); + } + }; + } } public static Predicate generateIsEntityVertexPredicate(AtlasTypeRegistry typeRegistry) {
