You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2020/10/08 03:18:06 UTC
[atlas] branch master updated: ATLAS-3983: solr index query escape
character handling
This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push:
new 8bb3e85 ATLAS-3983: solr index query escape character handling
8bb3e85 is described below
commit 8bb3e853ea128e1eb2b181e8db869bf7d8050181
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Sun Oct 4 23:51:50 2020 -0700
ATLAS-3983: solr index query escape character handling
---
.../apache/atlas/type/AtlasClassificationType.java | 6 +-
.../org/apache/atlas/type/AtlasEntityType.java | 6 +-
.../org/apache/atlas/type/AtlasStructType.java | 106 +++++++++++++++++++--
.../atlas/discovery/GraphIndexQueryBuilder.java | 4 +-
.../org/apache/atlas/discovery/SearchContext.java | 4 +-
.../apache/atlas/discovery/SearchProcessor.java | 18 ----
6 files changed, 105 insertions(+), 39 deletions(-)
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
index e0843cb..22259bc 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasClassificationType.java
@@ -65,7 +65,7 @@ public class AtlasClassificationType extends AtlasStructType {
super(classificationDef);
this.classificationDef = classificationDef;
- this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()));
+ this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()), true);
}
/**
@@ -81,7 +81,7 @@ public class AtlasClassificationType extends AtlasStructType {
super(classificationDef);
this.classificationDef = classificationDef;
- this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()));
+ this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()), true);
resolveReferences(typeRegistry);
}
@@ -264,7 +264,7 @@ public class AtlasClassificationType extends AtlasStructType {
public String getTypeAndAllSubTypesQryStr() {
if (StringUtils.isEmpty(typeAndAllSubTypesQryStr)) {
- typeAndAllSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndAllSubTypes);
+ typeAndAllSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndAllSubTypes, true);
}
return typeAndAllSubTypesQryStr;
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
index 58de4cc..27c7f73 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -100,7 +100,7 @@ public class AtlasEntityType extends AtlasStructType {
super(entityDef);
this.entityDef = entityDef;
- this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()));
+ this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()), true);
this.displayTextAttribute = entityDef.getOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE);
}
@@ -108,7 +108,7 @@ public class AtlasEntityType extends AtlasStructType {
super(entityDef);
this.entityDef = entityDef;
- this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()));
+ this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()), true);
this.displayTextAttribute = entityDef.getOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE);
resolveReferences(typeRegistry);
@@ -573,7 +573,7 @@ public class AtlasEntityType extends AtlasStructType {
public String getTypeAndAllSubTypesQryStr() {
if (StringUtils.isEmpty(typeAndAllSubTypesQryStr)) {
- typeAndAllSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndAllSubTypes);
+ typeAndAllSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndAllSubTypes, true);
}
return typeAndAllSubTypesQryStr;
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
index b0d88fc..28d2e23 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -936,6 +936,10 @@ public class AtlasStructType extends AtlasType {
}
public static String escapeIndexQueryValue(Collection<String> values) {
+ return escapeIndexQueryValue(values, false);
+ }
+
+ public static String escapeIndexQueryValue(Collection<String> values, boolean allowWildcard) {
StringBuilder sb = new StringBuilder();
sb.append(BRACE_OPEN_CHAR);
@@ -943,10 +947,10 @@ public class AtlasStructType extends AtlasType {
if (CollectionUtils.isNotEmpty(values)) {
Iterator<String> iter = values.iterator();
- sb.append(escapeIndexQueryValue(iter.next()));
+ sb.append(escapeIndexQueryValue(iter.next(), allowWildcard));
while (iter.hasNext()) {
- sb.append(SPACE_CHAR).append(escapeIndexQueryValue(iter.next()));
+ sb.append(SPACE_CHAR).append(escapeIndexQueryValue(iter.next(), allowWildcard));
}
}
@@ -956,26 +960,109 @@ public class AtlasStructType extends AtlasType {
}
public static String escapeIndexQueryValue(String value) {
- String ret = value;
+ return escapeIndexQueryValue(value, false);
+ }
+
+ public static String escapeIndexQueryValue(String value, boolean allowWildcard) {
+ String ret = value;
+ boolean quoteValue = false;
+
+ if (hasIndexQueryEscapeChar(value)) {
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+
+ if (!(allowWildcard && c == '*') && isIndexQueryEscapeChar(c)) {
+ sb.append('\\');
+ }
+
+ if (!quoteValue) {
+ quoteValue = shouldQuoteIndexQueryForChar(c);
+ }
+
+ sb.append(c);
+ }
+
+ ret = sb.toString();
+ } else if (value != null) {
+ for (int i = 0; i < value.length(); i++) {
+ if (shouldQuoteIndexQueryForChar(value.charAt(i))) {
+ quoteValue = true;
+
+ break;
+ }
+ }
+ }
- if (StringUtils.containsAny(value, IDX_QRY_OFFENDING_CHARS)) {
- boolean isQuoteAtStart = value.charAt(0) == DOUBLE_QUOTE_CHAR;
- boolean isQuoteAtEnd = value.charAt(value.length() - 1) == DOUBLE_QUOTE_CHAR;
+ if (quoteValue) {
+ boolean isQuoteAtStart = ret.charAt(0) == DOUBLE_QUOTE_CHAR;
+ boolean isQuoteAtEnd = ret.charAt(ret.length() - 1) == DOUBLE_QUOTE_CHAR;
if (!isQuoteAtStart) {
if (!isQuoteAtEnd) {
- ret = DOUBLE_QUOTE_CHAR + value + DOUBLE_QUOTE_CHAR;
+ ret = DOUBLE_QUOTE_CHAR + ret + DOUBLE_QUOTE_CHAR;
} else {
- ret = DOUBLE_QUOTE_CHAR + value;
+ ret = DOUBLE_QUOTE_CHAR + ret;
}
} else if (!isQuoteAtEnd) {
- ret = value + DOUBLE_QUOTE_CHAR;
+ ret = ret + DOUBLE_QUOTE_CHAR;
}
+
}
return ret;
}
+ private static boolean hasIndexQueryEscapeChar(String value) {
+ if (value != null) {
+ for (int i = 0; i < value.length(); i++) {
+ if (isIndexQueryEscapeChar(value.charAt(i))) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean isIndexQueryEscapeChar(char c) {
+ switch (c) {
+ case '+':
+ case '-':
+ case '&':
+ case '|':
+ case '!':
+ case '(':
+ case ')':
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ case '^':
+ case '"':
+ case '~':
+ case '*':
+ case '?':
+ case ':':
+ case '\\':
+ case '/':
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean shouldQuoteIndexQueryForChar(char c) {
+ switch (c) {
+ case '@':
+ case ' ':
+ return true;
+ }
+
+ return false;
+ }
+
private String getRelationshipEdgeLabel(String relationshipLabel) {
return (relationshipLabel == null) ? getEdgeLabel(qualifiedName) : relationshipLabel;
}
@@ -1024,7 +1111,6 @@ public class AtlasStructType extends AtlasType {
new String[] {"%", "_p"}, //titan reserved characters
};
- private static final char[] IDX_QRY_OFFENDING_CHARS = { '@', '/', ' ', '-' };
private static final char BRACE_OPEN_CHAR = '(';
private static final char BRACE_CLOSE_CHAR = ')';
private static final char DOUBLE_QUOTE_CHAR = '"';
diff --git a/repository/src/main/java/org/apache/atlas/discovery/GraphIndexQueryBuilder.java b/repository/src/main/java/org/apache/atlas/discovery/GraphIndexQueryBuilder.java
index 35d64b7..1cd8786 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/GraphIndexQueryBuilder.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/GraphIndexQueryBuilder.java
@@ -17,9 +17,7 @@
*/
package org.apache.atlas.discovery;
-import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_CLASSIFIED;
import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_NOT_CLASSIFIED;
-import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_WILDCARD_CLASSIFICATION;
import static org.apache.atlas.discovery.SearchProcessor.INDEX_SEARCH_PREFIX;
import static org.apache.atlas.repository.Constants.CLASSIFICATION_NAMES_KEY;
import static org.apache.atlas.repository.Constants.PROPAGATED_CLASSIFICATION_NAMES_KEY;
@@ -39,7 +37,7 @@ public class GraphIndexQueryBuilder {
void addClassificationTypeFilter(StringBuilder indexQuery) {
if (indexQuery != null && CollectionUtils.isNotEmpty(context.getClassificationNames())) {
- String classificationNames = AtlasStructType.AtlasAttribute.escapeIndexQueryValue(context.getClassificationNames());
+ String classificationNames = AtlasStructType.AtlasAttribute.escapeIndexQueryValue(context.getClassificationNames(), true);
if (indexQuery.length() != 0) {
indexQuery.append(" AND ");
}
diff --git a/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java b/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
index 2cb287f..aa49121 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchContext.java
@@ -144,7 +144,7 @@ public class SearchContext {
}
if (CollectionUtils.isNotEmpty(classificationTypeAndSubTypes)) {
- classificationTypeAndSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(classificationTypeAndSubTypes);
+ classificationTypeAndSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(classificationTypeAndSubTypes, true);
}
} else {
classificationTypeAndSubTypes = Collections.emptySet();
@@ -171,7 +171,7 @@ public class SearchContext {
}
if (CollectionUtils.isNotEmpty(typeAndSubTypes)) {
- typeAndSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndSubTypes);
+ typeAndSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndSubTypes, true);
}
} else {
typeAndSubTypes = Collections.emptySet();
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 da9dd66..01daf53 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/SearchProcessor.java
@@ -1150,24 +1150,6 @@ public abstract class SearchProcessor {
private static boolean isIndexQuerySpecialChar(char c) {
switch (c) {
- case '+':
- case '-':
- case '&':
- case '|':
- case '!':
- case '(':
- case ')':
- case '{':
- case '}':
- case '[':
- case ']':
- case '^':
- case '"':
- case '~':
- case '*':
- case '?':
- case ':':
- case '/':
case '#':
case '$':
case '%':