Commit 8bb3e853 by Madhan Neethiraj

ATLAS-3983: solr index query escape character handling

parent 4f95ee8c
...@@ -65,7 +65,7 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -65,7 +65,7 @@ public class AtlasClassificationType extends AtlasStructType {
super(classificationDef); super(classificationDef);
this.classificationDef = 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 { ...@@ -81,7 +81,7 @@ public class AtlasClassificationType extends AtlasStructType {
super(classificationDef); super(classificationDef);
this.classificationDef = classificationDef; this.classificationDef = classificationDef;
this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName())); this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName()), true);
resolveReferences(typeRegistry); resolveReferences(typeRegistry);
} }
...@@ -264,7 +264,7 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -264,7 +264,7 @@ public class AtlasClassificationType extends AtlasStructType {
public String getTypeAndAllSubTypesQryStr() { public String getTypeAndAllSubTypesQryStr() {
if (StringUtils.isEmpty(typeAndAllSubTypesQryStr)) { if (StringUtils.isEmpty(typeAndAllSubTypesQryStr)) {
typeAndAllSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndAllSubTypes); typeAndAllSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndAllSubTypes, true);
} }
return typeAndAllSubTypesQryStr; return typeAndAllSubTypesQryStr;
......
...@@ -100,7 +100,7 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -100,7 +100,7 @@ public class AtlasEntityType extends AtlasStructType {
super(entityDef); super(entityDef);
this.entityDef = 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); this.displayTextAttribute = entityDef.getOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE);
} }
...@@ -108,7 +108,7 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -108,7 +108,7 @@ public class AtlasEntityType extends AtlasStructType {
super(entityDef); super(entityDef);
this.entityDef = 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); this.displayTextAttribute = entityDef.getOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE);
resolveReferences(typeRegistry); resolveReferences(typeRegistry);
...@@ -573,7 +573,7 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -573,7 +573,7 @@ public class AtlasEntityType extends AtlasStructType {
public String getTypeAndAllSubTypesQryStr() { public String getTypeAndAllSubTypesQryStr() {
if (StringUtils.isEmpty(typeAndAllSubTypesQryStr)) { if (StringUtils.isEmpty(typeAndAllSubTypesQryStr)) {
typeAndAllSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndAllSubTypes); typeAndAllSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndAllSubTypes, true);
} }
return typeAndAllSubTypesQryStr; return typeAndAllSubTypesQryStr;
......
...@@ -936,6 +936,10 @@ public class AtlasStructType extends AtlasType { ...@@ -936,6 +936,10 @@ public class AtlasStructType extends AtlasType {
} }
public static String escapeIndexQueryValue(Collection<String> values) { public static String escapeIndexQueryValue(Collection<String> values) {
return escapeIndexQueryValue(values, false);
}
public static String escapeIndexQueryValue(Collection<String> values, boolean allowWildcard) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(BRACE_OPEN_CHAR); sb.append(BRACE_OPEN_CHAR);
...@@ -943,10 +947,10 @@ public class AtlasStructType extends AtlasType { ...@@ -943,10 +947,10 @@ public class AtlasStructType extends AtlasType {
if (CollectionUtils.isNotEmpty(values)) { if (CollectionUtils.isNotEmpty(values)) {
Iterator<String> iter = values.iterator(); Iterator<String> iter = values.iterator();
sb.append(escapeIndexQueryValue(iter.next())); sb.append(escapeIndexQueryValue(iter.next(), allowWildcard));
while (iter.hasNext()) { 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 { ...@@ -956,26 +960,109 @@ public class AtlasStructType extends AtlasType {
} }
public static String escapeIndexQueryValue(String value) { 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)) { if (quoteValue) {
boolean isQuoteAtStart = value.charAt(0) == DOUBLE_QUOTE_CHAR; boolean isQuoteAtStart = ret.charAt(0) == DOUBLE_QUOTE_CHAR;
boolean isQuoteAtEnd = value.charAt(value.length() - 1) == DOUBLE_QUOTE_CHAR; boolean isQuoteAtEnd = ret.charAt(ret.length() - 1) == DOUBLE_QUOTE_CHAR;
if (!isQuoteAtStart) { if (!isQuoteAtStart) {
if (!isQuoteAtEnd) { if (!isQuoteAtEnd) {
ret = DOUBLE_QUOTE_CHAR + value + DOUBLE_QUOTE_CHAR; ret = DOUBLE_QUOTE_CHAR + ret + DOUBLE_QUOTE_CHAR;
} else { } else {
ret = DOUBLE_QUOTE_CHAR + value; ret = DOUBLE_QUOTE_CHAR + ret;
} }
} else if (!isQuoteAtEnd) { } else if (!isQuoteAtEnd) {
ret = value + DOUBLE_QUOTE_CHAR; ret = ret + DOUBLE_QUOTE_CHAR;
} }
} }
return ret; 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) { private String getRelationshipEdgeLabel(String relationshipLabel) {
return (relationshipLabel == null) ? getEdgeLabel(qualifiedName) : relationshipLabel; return (relationshipLabel == null) ? getEdgeLabel(qualifiedName) : relationshipLabel;
} }
...@@ -1024,7 +1111,6 @@ public class AtlasStructType extends AtlasType { ...@@ -1024,7 +1111,6 @@ public class AtlasStructType extends AtlasType {
new String[] {"%", "_p"}, //titan reserved characters 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_OPEN_CHAR = '(';
private static final char BRACE_CLOSE_CHAR = ')'; private static final char BRACE_CLOSE_CHAR = ')';
private static final char DOUBLE_QUOTE_CHAR = '"'; private static final char DOUBLE_QUOTE_CHAR = '"';
......
...@@ -17,9 +17,7 @@ ...@@ -17,9 +17,7 @@
*/ */
package org.apache.atlas.discovery; 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_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.discovery.SearchProcessor.INDEX_SEARCH_PREFIX;
import static org.apache.atlas.repository.Constants.CLASSIFICATION_NAMES_KEY; import static org.apache.atlas.repository.Constants.CLASSIFICATION_NAMES_KEY;
import static org.apache.atlas.repository.Constants.PROPAGATED_CLASSIFICATION_NAMES_KEY; import static org.apache.atlas.repository.Constants.PROPAGATED_CLASSIFICATION_NAMES_KEY;
...@@ -39,7 +37,7 @@ public class GraphIndexQueryBuilder { ...@@ -39,7 +37,7 @@ public class GraphIndexQueryBuilder {
void addClassificationTypeFilter(StringBuilder indexQuery) { void addClassificationTypeFilter(StringBuilder indexQuery) {
if (indexQuery != null && CollectionUtils.isNotEmpty(context.getClassificationNames())) { 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) { if (indexQuery.length() != 0) {
indexQuery.append(" AND "); indexQuery.append(" AND ");
} }
......
...@@ -144,7 +144,7 @@ public class SearchContext { ...@@ -144,7 +144,7 @@ public class SearchContext {
} }
if (CollectionUtils.isNotEmpty(classificationTypeAndSubTypes)) { if (CollectionUtils.isNotEmpty(classificationTypeAndSubTypes)) {
classificationTypeAndSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(classificationTypeAndSubTypes); classificationTypeAndSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(classificationTypeAndSubTypes, true);
} }
} else { } else {
classificationTypeAndSubTypes = Collections.emptySet(); classificationTypeAndSubTypes = Collections.emptySet();
...@@ -171,7 +171,7 @@ public class SearchContext { ...@@ -171,7 +171,7 @@ public class SearchContext {
} }
if (CollectionUtils.isNotEmpty(typeAndSubTypes)) { if (CollectionUtils.isNotEmpty(typeAndSubTypes)) {
typeAndSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndSubTypes); typeAndSubTypesQryStr = AtlasAttribute.escapeIndexQueryValue(typeAndSubTypes, true);
} }
} else { } else {
typeAndSubTypes = Collections.emptySet(); typeAndSubTypes = Collections.emptySet();
......
...@@ -1150,24 +1150,6 @@ public abstract class SearchProcessor { ...@@ -1150,24 +1150,6 @@ public abstract class SearchProcessor {
private static boolean isIndexQuerySpecialChar(char c) { private static boolean isIndexQuerySpecialChar(char c) {
switch (c) { switch (c) {
case '+':
case '-':
case '&':
case '|':
case '!':
case '(':
case ')':
case '{':
case '}':
case '[':
case ']':
case '^':
case '"':
case '~':
case '*':
case '?':
case ':':
case '/':
case '#': case '#':
case '$': case '$':
case '%': case '%':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment