Commit 5932b1af by Le Ma Committed by Sarath Subramanian

ATLAS-3482 Enhance basic search to enable search on entity system attributes

parent e3e7f2e0
...@@ -61,6 +61,7 @@ public class SearchParameters implements Serializable { ...@@ -61,6 +61,7 @@ public class SearchParameters implements Serializable {
public static final String WILDCARD_CLASSIFICATIONS = "*"; public static final String WILDCARD_CLASSIFICATIONS = "*";
public static final String ALL_CLASSIFICATIONS = "_CLASSIFIED"; public static final String ALL_CLASSIFICATIONS = "_CLASSIFIED";
public static final String NO_CLASSIFICATIONS = "_NOT_CLASSIFIED"; public static final String NO_CLASSIFICATIONS = "_NOT_CLASSIFIED";
public static final String ALL_ENTITY_TYPES = "_ALL_ENTITY_TYPES";
/** /**
* @return The type of query * @return The type of query
......
...@@ -300,6 +300,16 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable { ...@@ -300,6 +300,16 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
this(name, typeName, DEFAULT_SEARCHWEIGHT); this(name, typeName, DEFAULT_SEARCHWEIGHT);
} }
public AtlasAttributeDef(String name, String typeName, boolean isUnique, boolean isIndexable) {
this(name, typeName, false, Cardinality.SINGLE, COUNT_NOT_SET, COUNT_NOT_SET, isUnique, isIndexable,
false, null,null, null, null, DEFAULT_SEARCHWEIGHT, null);
}
public AtlasAttributeDef(String name, String typeName, Cardinality cardinality, boolean isUnique, boolean isIndexable) {
this(name, typeName, false, cardinality, COUNT_NOT_SET, COUNT_NOT_SET, isUnique, isIndexable,
false, null,null, null, null, DEFAULT_SEARCHWEIGHT, null);
}
public AtlasAttributeDef(String name, String typeName, int searchWeight) { public AtlasAttributeDef(String name, String typeName, int searchWeight) {
this(name, typeName, false, Cardinality.SINGLE, searchWeight, null); this(name, typeName, false, Cardinality.SINGLE, searchWeight, null);
} }
......
...@@ -17,27 +17,35 @@ ...@@ -17,27 +17,35 @@
*/ */
package org.apache.atlas.type; package org.apache.atlas.type;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_LONG;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING;
import static org.apache.atlas.type.Constants.CREATED_BY_KEY;
import static org.apache.atlas.type.Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY;
import static org.apache.atlas.type.Constants.MODIFIED_BY_KEY;
import static org.apache.atlas.type.Constants.STATE_PROPERTY_KEY;
import static org.apache.atlas.type.Constants.TIMESTAMP_PROPERTY_KEY;
import static org.apache.atlas.type.Constants.TYPE_NAME_PROPERTY_KEY;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TimeBoundary; import org.apache.atlas.model.TimeBoundary;
import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.model.typedef.AtlasClassificationDef; import org.apache.atlas.model.typedef.AtlasClassificationDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.validator.routines.DateValidator; import org.apache.commons.validator.routines.DateValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
/** /**
* class that implements behaviour of a classification-type. * class that implements behaviour of a classification-type.
*/ */
public class AtlasClassificationType extends AtlasStructType { public class AtlasClassificationType extends AtlasStructType {
private static final Logger LOG = LoggerFactory.getLogger(AtlasClassificationType.class);
public static final AtlasClassificationType CLASSIFICATION_ROOT = initRootClassificationType();
private static final String CLASSIFICATION_ROOT_NAME = "__CLASSIFICATION_ROOT";
private final AtlasClassificationDef classificationDef; private final AtlasClassificationDef classificationDef;
private final String typeQryStr; private final String typeQryStr;
...@@ -488,6 +496,21 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -488,6 +496,21 @@ public class AtlasClassificationType extends AtlasStructType {
return CollectionUtils.isEmpty(this.entityTypes) || this.entityTypes.contains(entityType.getTypeName()); return CollectionUtils.isEmpty(this.entityTypes) || this.entityTypes.contains(entityType.getTypeName());
} }
private static AtlasClassificationType initRootClassificationType() {
List<AtlasAttributeDef> attributeDefs = new ArrayList<AtlasAttributeDef>() {{
add(new AtlasAttributeDef(TYPE_NAME_PROPERTY_KEY, AtlasBaseTypeDef.ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_LONG, false, true));
add(new AtlasAttributeDef(MODIFICATION_TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_LONG, false, true));
add(new AtlasAttributeDef(MODIFIED_BY_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(CREATED_BY_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(STATE_PROPERTY_KEY, ATLAS_TYPE_STRING, false, true));
}};
AtlasClassificationDef classificationDef = new AtlasClassificationDef(CLASSIFICATION_ROOT_NAME, "", "", attributeDefs);
return new AtlasClassificationType(classificationDef);
}
private void getTypeHierarchyInfo(AtlasTypeRegistry typeRegistry, private void getTypeHierarchyInfo(AtlasTypeRegistry typeRegistry,
Set<String> allSuperTypeNames, Set<String> allSuperTypeNames,
Map<String, AtlasAttribute> allAttributes) throws AtlasBaseException { Map<String, AtlasAttribute> allAttributes) throws AtlasBaseException {
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
*/ */
package org.apache.atlas.type; package org.apache.atlas.type;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_LONG;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING;
import static org.apache.atlas.type.Constants.*;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
...@@ -42,31 +45,31 @@ import java.util.List; ...@@ -42,31 +45,31 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
* class that implements behaviour of an entity-type. * class that implements behaviour of an entity-type.
*/ */
public class AtlasEntityType extends AtlasStructType { public class AtlasEntityType extends AtlasStructType {
private static final Logger LOG = LoggerFactory.getLogger(AtlasEntityType.class); private static final Logger LOG = LoggerFactory.getLogger(AtlasEntityType.class);
public static final AtlasEntityType ENTITY_ROOT = initRootEntityType();
private static final String NAME = "name"; private static final String NAME = "name";
private static final String DESCRIPTION = "description"; private static final String DESCRIPTION = "description";
private static final String OWNER = "owner"; private static final String OWNER = "owner";
private static final String CREATE_TIME = "createTime"; private static final String CREATE_TIME = "createTime";
private static final String DYN_ATTRIBUTE_PREFIX = "dynAttribute:"; private static final String DYN_ATTRIBUTE_PREFIX = "dynAttribute:";
private static final char DYN_ATTRIBUTE_NAME_SEPARATOR = '.'; private static final String OPTION_SCHEMA_ATTRIBUTES = "schemaAttributes";
private static final char DYN_ATTRIBUTE_OPEN_DELIM = '{'; private static final String INTERNAL_TYPENAME = "__internal";
private static final char DYN_ATTRIBUTE_CLOSE_DELIM = '}';
private static final char DYN_ATTRIBUTE_NAME_SEPARATOR = '.';
private static final char DYN_ATTRIBUTE_OPEN_DELIM = '{';
private static final char DYN_ATTRIBUTE_CLOSE_DELIM = '}';
private static final String[] ENTITY_HEADER_ATTRIBUTES = new String[]{NAME, DESCRIPTION, OWNER, CREATE_TIME}; private static final String[] ENTITY_HEADER_ATTRIBUTES = new String[]{NAME, DESCRIPTION, OWNER, CREATE_TIME};
private static final String OPTION_SCHEMA_ATTRIBUTES = "schemaAttributes"; private static final String ENTITY_ROOT_NAME = "__ENTITY_ROOT";
private final AtlasEntityDef entityDef; private final AtlasEntityDef entityDef;
private final String typeQryStr; private final String typeQryStr;
private static final String INTERNAL_TYPENAME = "__internal";
private List<AtlasEntityType> superTypes = Collections.emptyList(); private List<AtlasEntityType> superTypes = Collections.emptyList();
private Set<String> allSuperTypes = Collections.emptySet(); private Set<String> allSuperTypes = Collections.emptySet();
private Set<String> subTypes = Collections.emptySet(); private Set<String> subTypes = Collections.emptySet();
...@@ -83,7 +86,6 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -83,7 +86,6 @@ public class AtlasEntityType extends AtlasStructType {
private List<AtlasAttribute> dynEvalTriggerAttributes = Collections.emptyList(); private List<AtlasAttribute> dynEvalTriggerAttributes = Collections.emptyList();
private Map<String,List<TemplateToken>> parsedTemplates = Collections.emptyMap(); private Map<String,List<TemplateToken>> parsedTemplates = Collections.emptyMap();
public AtlasEntityType(AtlasEntityDef entityDef) { public AtlasEntityType(AtlasEntityDef entityDef) {
super(entityDef); super(entityDef);
...@@ -104,6 +106,8 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -104,6 +106,8 @@ public class AtlasEntityType extends AtlasStructType {
return entityDef; return entityDef;
} }
public static AtlasEntityType getEntityRoot() {return ENTITY_ROOT; }
@Override @Override
void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException { void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
super.resolveReferences(typeRegistry); super.resolveReferences(typeRegistry);
...@@ -400,10 +404,14 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -400,10 +404,14 @@ public class AtlasEntityType extends AtlasStructType {
} }
public String getQualifiedAttributeName(String attrName) throws AtlasBaseException { public String getQualifiedAttributeName(String attrName) throws AtlasBaseException {
if (allAttributes.containsKey(attrName)) { AtlasAttribute ret = getAttribute(attrName);
return allAttributes.get(attrName).getQualifiedName();
} else if (relationshipAttributes.containsKey(attrName)) { if (ret == null) {
return relationshipAttributes.get(attrName).values().iterator().next().getQualifiedName(); ret = relationshipAttributes.get(attrName).values().iterator().next();
}
if (ret != null) {
return ret.getQualifiedName();
} }
throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, entityDef.getName()); throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, entityDef.getName());
...@@ -506,11 +514,6 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -506,11 +514,6 @@ public class AtlasEntityType extends AtlasStructType {
} }
@Override @Override
public AtlasAttribute getAttribute(String attributeName) {
return allAttributes.get(attributeName);
}
@Override
public boolean validateValue(Object obj, String objName, List<String> messages) { public boolean validateValue(Object obj, String objName, List<String> messages) {
boolean ret = true; boolean ret = true;
...@@ -621,6 +624,30 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -621,6 +624,30 @@ public class AtlasEntityType extends AtlasStructType {
} }
} }
private static AtlasEntityType initRootEntityType() {
List<AtlasAttributeDef> attributeDefs = new ArrayList<AtlasAttributeDef>() {{
add(new AtlasAttributeDef(TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_LONG, false, true));
add(new AtlasAttributeDef(MODIFICATION_TIMESTAMP_PROPERTY_KEY, ATLAS_TYPE_LONG, false, true));
add(new AtlasAttributeDef(MODIFIED_BY_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(CREATED_BY_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(STATE_PROPERTY_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(GUID_PROPERTY_KEY, ATLAS_TYPE_STRING, true, true));
add(new AtlasAttributeDef(HISTORICAL_GUID_PROPERTY_KEY, ATLAS_TYPE_STRING, true, true));
add(new AtlasAttributeDef(TYPE_NAME_PROPERTY_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(CLASSIFICATION_TEXT_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(CLASSIFICATION_NAMES_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(PROPAGATED_CLASSIFICATION_NAMES_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(IS_INCOMPLETE_PROPERTY_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(LABELS_PROPERTY_KEY, ATLAS_TYPE_STRING, false, true));
add(new AtlasAttributeDef(CUSTOM_ATTRIBUTES_PROPERTY_KEY, ATLAS_TYPE_STRING, false, true));
}};
AtlasEntityDef entityDef = new AtlasEntityDef(ENTITY_ROOT_NAME, "", "", attributeDefs);
return new AtlasEntityType(entityDef);
}
private void addSubType(AtlasEntityType subType) { private void addSubType(AtlasEntityType subType) {
subTypes.add(subType.getTypeName()); subTypes.add(subType.getTypeName());
} }
......
...@@ -216,7 +216,23 @@ public class AtlasStructType extends AtlasType { ...@@ -216,7 +216,23 @@ public class AtlasStructType extends AtlasType {
} }
public AtlasAttribute getAttribute(String attributeName) { public AtlasAttribute getAttribute(String attributeName) {
return allAttributes.get(attributeName); AtlasAttribute ret = allAttributes.get(attributeName);
if (ret == null) {
ret = getSystemAttribute(attributeName);
}
return ret;
}
public AtlasAttribute getSystemAttribute(String attributeName) {
AtlasAttribute ret = null;
if (this instanceof AtlasEntityType) {
ret = AtlasEntityType.ENTITY_ROOT.allAttributes.get(attributeName);
} else if (this instanceof AtlasClassificationType) {
ret = AtlasClassificationType.CLASSIFICATION_ROOT.allAttributes.get(attributeName);
}
return ret;
} }
@Override @Override
...@@ -631,8 +647,10 @@ public class AtlasStructType extends AtlasType { ...@@ -631,8 +647,10 @@ public class AtlasStructType extends AtlasType {
} }
public String getQualifiedAttributeName(String attrName) throws AtlasBaseException { public String getQualifiedAttributeName(String attrName) throws AtlasBaseException {
if ( allAttributes.containsKey(attrName)) { AtlasAttribute attribute = getAttribute(attrName);
return allAttributes.get(attrName).getQualifiedName();
if (attribute != null) {
return attribute.getQualifiedName();
} }
throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, structDef.getName()); throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_ATTRIBUTE, attrName, structDef.getName());
...@@ -916,20 +934,33 @@ public class AtlasStructType extends AtlasType { ...@@ -916,20 +934,33 @@ public class AtlasStructType extends AtlasType {
} }
public static String getQualifiedAttributeName(AtlasStructDef structDef, String attrName) { public static String getQualifiedAttributeName(AtlasStructDef structDef, String attrName) {
return attrName.contains(".") ? attrName : String.format("%s.%s", structDef.getName(), attrName); if (isRootType(structDef)) {
return attrName;
} else {
return attrName.contains(".") ? attrName : String.format("%s.%s", structDef.getName(), attrName);
}
} }
public static String generateVertexPropertyName(AtlasStructDef structDef, AtlasAttributeDef attrDef, String qualifiedName) { public static String generateVertexPropertyName(AtlasStructDef structDef, AtlasAttributeDef attrDef, String qualifiedName) {
String vertexPropertyName = qualifiedName; String vertexPropertyName = qualifiedName;
String attrName = attrDef.getName();
if(!attrDef.getName().contains(".") && if (isRootType(structDef)) {
AtlasAttributeDef.IndexType.STRING.equals(attrDef.getIndexType()) && return attrName;
ATLAS_TYPE_STRING.equalsIgnoreCase(attrDef.getTypeName())) { } else {
vertexPropertyName = String.format("%s.%s%s", structDef.getName(), VERTEX_PROPERTY_PREFIX_STRING_INDEX_TYPE, attrDef.getName()); if(!attrDef.getName().contains(".") &&
AtlasAttributeDef.IndexType.STRING.equals(attrDef.getIndexType()) &&
ATLAS_TYPE_STRING.equalsIgnoreCase(attrDef.getTypeName())) {
vertexPropertyName = String.format("%s.%s%s", structDef.getName(), VERTEX_PROPERTY_PREFIX_STRING_INDEX_TYPE, attrDef.getName());
}
} }
return encodePropertyKey(vertexPropertyName); return encodePropertyKey(vertexPropertyName);
} }
private static boolean isRootType(AtlasStructDef structDef) {
return StringUtils.equals(structDef.getName(), AtlasEntityType.ENTITY_ROOT.getTypeName()) ||
StringUtils.equals(structDef.getName(), AtlasClassificationType.CLASSIFICATION_ROOT.getTypeName());
}
// Keys copied from org.janusgraph.graphdb.types.system.SystemTypeManager.RESERVED_CHARS // Keys copied from org.janusgraph.graphdb.types.system.SystemTypeManager.RESERVED_CHARS
// JanusGraph checks that these chars are not part of any keys hence encoding // JanusGraph checks that these chars are not part of any keys hence encoding
// also including Titan reserved characters to support migrated property keys // also including Titan reserved characters to support migrated property keys
......
...@@ -54,12 +54,13 @@ public class AtlasTypeRegistry { ...@@ -54,12 +54,13 @@ public class AtlasTypeRegistry {
private final Set<String> missingRelationshipDefs; private final Set<String> missingRelationshipDefs;
private final Map<String, String> commonIndexFieldNameCache; private final Map<String, String> commonIndexFieldNameCache;
public AtlasTypeRegistry() { public AtlasTypeRegistry() {
registryData = new RegistryData(); registryData = new RegistryData();
updateSynchronizer = new TypeRegistryUpdateSynchronizer(this); updateSynchronizer = new TypeRegistryUpdateSynchronizer(this);
missingRelationshipDefs = new HashSet<>(); missingRelationshipDefs = new HashSet<>();
commonIndexFieldNameCache = new HashMap<>(); commonIndexFieldNameCache = new HashMap<>();
resolveReferencesForRootTypes();
} }
// used only by AtlasTransientTypeRegistry // used only by AtlasTransientTypeRegistry
...@@ -68,6 +69,8 @@ public class AtlasTypeRegistry { ...@@ -68,6 +69,8 @@ public class AtlasTypeRegistry {
updateSynchronizer = other.updateSynchronizer; updateSynchronizer = other.updateSynchronizer;
missingRelationshipDefs = other.missingRelationshipDefs; missingRelationshipDefs = other.missingRelationshipDefs;
commonIndexFieldNameCache = other.commonIndexFieldNameCache; commonIndexFieldNameCache = other.commonIndexFieldNameCache;
resolveReferencesForRootTypes();
} }
public Collection<String> getAllTypeNames() { return registryData.allTypes.getAllTypeNames(); } public Collection<String> getAllTypeNames() { return registryData.allTypes.getAllTypeNames(); }
...@@ -242,6 +245,16 @@ public class AtlasTypeRegistry { ...@@ -242,6 +245,16 @@ public class AtlasTypeRegistry {
commonIndexFieldNameCache.put(propertyName, indexFieldName); commonIndexFieldNameCache.put(propertyName, indexFieldName);
} }
private void resolveReferencesForRootTypes() {
try {
AtlasEntityType.ENTITY_ROOT.resolveReferences(this);
AtlasClassificationType.CLASSIFICATION_ROOT.resolveReferences(this);
} catch (AtlasBaseException e) {
LOG.error("Failed to initialize root types", e);
throw new RuntimeException(e);
}
}
/** /**
* retrieves the index field name for the common field passed in. * retrieves the index field name for the common field passed in.
* @param propertyName the name of the common field. * @param propertyName the name of the common field.
......
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.atlas.type;
import static org.apache.atlas.type.AtlasStructType.AtlasAttribute.encodePropertyKey;
/**
* Intg Constants.
*/
public final class Constants {
public static final String INTERNAL_PROPERTY_KEY_PREFIX = "__";
/**
* Shared System Attributes
*/
public static final String TYPE_NAME_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "typeName");
public static final String STATE_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "state");
public static final String CREATED_BY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "createdBy");
public static final String SUPER_TYPES_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "superTypeNames");
public static final String MODIFIED_BY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "modifiedBy");
public static final String TIMESTAMP_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "timestamp");
public static final String MODIFICATION_TIMESTAMP_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "modificationTimestamp");
/**
* Entity-Only System Attributes
*/
public static final String GUID_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "guid");
public static final String HISTORICAL_GUID_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "historicalGuids");
public static final String LABELS_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "labels");
public static final String CUSTOM_ATTRIBUTES_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "customAttributes");
public static final String TRAIT_NAMES_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "traitNames");
public static final String PROPAGATED_TRAIT_NAMES_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "propagatedTraitNames");
public static final String CLASSIFICATION_TEXT_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "classificationsText");
public static final String CLASSIFICATION_NAMES_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "classificationNames");
public static final String PROPAGATED_CLASSIFICATION_NAMES_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "propagatedClassificationNames");
public static final String IS_INCOMPLETE_PROPERTY_KEY = encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "isIncomplete");
private Constants() {}
}
...@@ -786,7 +786,7 @@ public final class TestUtilsV2 { ...@@ -786,7 +786,7 @@ public final class TestUtilsV2 {
createUniqueRequiredAttrDef("name", "string"), createUniqueRequiredAttrDef("name", "string"),
createOptionalAttrDef("description", "string"), createOptionalAttrDef("description", "string"),
createRequiredAttrDef("type", "string"), createRequiredAttrDef("type", "string"),
createOptionalAttrDef("created", "date"), createOptionalAttrDef("created", "string"),
// enum // enum
new AtlasAttributeDef("tableType", "tableType", false, new AtlasAttributeDef("tableType", "tableType", false,
SINGLE, 1, 1, SINGLE, 1, 1,
......
...@@ -27,9 +27,9 @@ import org.apache.atlas.model.typedef.AtlasRelationshipDef; ...@@ -27,9 +27,9 @@ import org.apache.atlas.model.typedef.AtlasRelationshipDef;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags; import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory; import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
import org.apache.atlas.model.typedef.AtlasRelationshipEndDef; import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
import org.apache.atlas.model.typedef.AtlasStructDef;
import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import java.util.*; import java.util.*;
...@@ -38,7 +38,7 @@ import static org.testng.Assert.fail; ...@@ -38,7 +38,7 @@ import static org.testng.Assert.fail;
public class TestAtlasRelationshipType { public class TestAtlasRelationshipType {
private AtlasTypeRegistry typeRegistry = new AtlasTypeRegistry(); private AtlasTypeRegistry typeRegistry;
private static final String EMPLOYEE_TYPE = "employee"; private static final String EMPLOYEE_TYPE = "employee";
private static final String DEPARTMENT_TYPE = "department"; private static final String DEPARTMENT_TYPE = "department";
...@@ -48,35 +48,35 @@ public class TestAtlasRelationshipType { ...@@ -48,35 +48,35 @@ public class TestAtlasRelationshipType {
private static final String EMPLOYEE_ADDRESS_RELATION_TYPE = "employeeAddress"; private static final String EMPLOYEE_ADDRESS_RELATION_TYPE = "employeeAddress";
private static final String EMPLOYEE_PHONE_RELATION_TYPE = "employeePhone"; private static final String EMPLOYEE_PHONE_RELATION_TYPE = "employeePhone";
@Test @BeforeMethod
public void createTypesAndRelationships() throws AtlasBaseException { public void setUp() throws AtlasBaseException {
typeRegistry = new AtlasTypeRegistry();
createEmployeeTypes(); createEmployeeTypes();
createRelationshipTypes(); createRelationshipTypes();
} }
@Test @Test
public void testvalidateAtlasRelationshipDef() throws AtlasBaseException { public void testvalidateAtlasRelationshipDef() throws AtlasBaseException {
AtlasRelationshipEndDef ep_single = new AtlasRelationshipEndDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE); AtlasRelationshipEndDef ep_single = new AtlasRelationshipEndDef("typeA", "attr1", Cardinality.SINGLE);
AtlasRelationshipEndDef ep_single_container = new AtlasRelationshipEndDef("typeB", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE); AtlasRelationshipEndDef ep_single_container = new AtlasRelationshipEndDef("typeB", "attr2", Cardinality.SINGLE);
AtlasRelationshipEndDef ep_single_container_2 = new AtlasRelationshipEndDef("typeC", "attr3", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true); AtlasRelationshipEndDef ep_single_container_2 = new AtlasRelationshipEndDef("typeC", "attr3", Cardinality.SINGLE, true);
AtlasRelationshipEndDef ep_single_container_3 = new AtlasRelationshipEndDef("typeD", "attr4", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true); AtlasRelationshipEndDef ep_single_container_3 = new AtlasRelationshipEndDef("typeD", "attr4", Cardinality.SINGLE, true);
AtlasRelationshipEndDef ep_SET = new AtlasRelationshipEndDef("typeD", "attr4", AtlasStructDef.AtlasAttributeDef.Cardinality.SET,false); AtlasRelationshipEndDef ep_SET = new AtlasRelationshipEndDef("typeD", "attr4", Cardinality.SET,false);
AtlasRelationshipEndDef ep_LIST = new AtlasRelationshipEndDef("typeE", "attr5", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST,true); AtlasRelationshipEndDef ep_LIST = new AtlasRelationshipEndDef("typeE", "attr5", Cardinality.LIST,true);
AtlasRelationshipEndDef ep_SET_container = new AtlasRelationshipEndDef("typeF", "attr6", AtlasStructDef.AtlasAttributeDef.Cardinality.SET,true); AtlasRelationshipEndDef ep_SET_container = new AtlasRelationshipEndDef("typeF", "attr6", Cardinality.SET,true);
AtlasRelationshipDef relationshipDef1 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef1 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_single, ep_SET); RelationshipCategory.ASSOCIATION, PropagateTags.ONE_TO_TWO, ep_single, ep_SET);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef1); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef1);
AtlasRelationshipDef relationshipDef2 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef2 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_SET_container, ep_single); RelationshipCategory.COMPOSITION, PropagateTags.ONE_TO_TWO, ep_SET_container, ep_single);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef2); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef2);
AtlasRelationshipDef relationshipDef3 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef3 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.AGGREGATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_SET_container, ep_single); RelationshipCategory.AGGREGATION, PropagateTags.ONE_TO_TWO, ep_SET_container, ep_single);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef3); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef3);
try { try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_single_container_2, ep_single_container); RelationshipCategory.ASSOCIATION, PropagateTags.ONE_TO_TWO, ep_single_container_2, ep_single_container);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail"); fail("This call is expected to fail");
} catch (AtlasBaseException abe) { } catch (AtlasBaseException abe) {
...@@ -86,7 +86,7 @@ public class TestAtlasRelationshipType { ...@@ -86,7 +86,7 @@ public class TestAtlasRelationshipType {
} }
try { try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_single, ep_single_container); RelationshipCategory.COMPOSITION, PropagateTags.ONE_TO_TWO, ep_single, ep_single_container);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail"); fail("This call is expected to fail");
} catch (AtlasBaseException abe) { } catch (AtlasBaseException abe) {
...@@ -96,7 +96,7 @@ public class TestAtlasRelationshipType { ...@@ -96,7 +96,7 @@ public class TestAtlasRelationshipType {
} }
try { try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.AGGREGATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_single, ep_single_container); RelationshipCategory.AGGREGATION, PropagateTags.ONE_TO_TWO, ep_single, ep_single_container);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail"); fail("This call is expected to fail");
} catch (AtlasBaseException abe) { } catch (AtlasBaseException abe) {
...@@ -107,7 +107,7 @@ public class TestAtlasRelationshipType { ...@@ -107,7 +107,7 @@ public class TestAtlasRelationshipType {
try { try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_SET_container, ep_SET); RelationshipCategory.COMPOSITION, PropagateTags.ONE_TO_TWO, ep_SET_container, ep_SET);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail"); fail("This call is expected to fail");
} catch (AtlasBaseException abe) { } catch (AtlasBaseException abe) {
...@@ -117,7 +117,7 @@ public class TestAtlasRelationshipType { ...@@ -117,7 +117,7 @@ public class TestAtlasRelationshipType {
} }
try { try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_single, ep_LIST); RelationshipCategory.COMPOSITION, PropagateTags.ONE_TO_TWO, ep_single, ep_LIST);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail"); fail("This call is expected to fail");
} catch (AtlasBaseException abe) { } catch (AtlasBaseException abe) {
...@@ -127,7 +127,7 @@ public class TestAtlasRelationshipType { ...@@ -127,7 +127,7 @@ public class TestAtlasRelationshipType {
} }
try { try {
AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1", AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep_LIST, ep_single); RelationshipCategory.COMPOSITION, PropagateTags.ONE_TO_TWO, ep_LIST, ep_single);
AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef); AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
fail("This call is expected to fail"); fail("This call is expected to fail");
} catch (AtlasBaseException abe) { } catch (AtlasBaseException abe) {
...@@ -138,8 +138,8 @@ public class TestAtlasRelationshipType { ...@@ -138,8 +138,8 @@ public class TestAtlasRelationshipType {
} }
@Test(dependsOnMethods = "createTypesAndRelationships") @Test
public void testRelationshipAttributes() throws Exception { public void testRelationshipAttributes() {
Map<String, Map<String, AtlasAttribute>> employeeRelationAttrs = getRelationAttrsForType(EMPLOYEE_TYPE); Map<String, Map<String, AtlasAttribute>> employeeRelationAttrs = getRelationAttrsForType(EMPLOYEE_TYPE);
Assert.assertNotNull(employeeRelationAttrs); Assert.assertNotNull(employeeRelationAttrs);
......
...@@ -47,7 +47,7 @@ public class TestAtlasTypeRegistry { ...@@ -47,7 +47,7 @@ public class TestAtlasTypeRegistry {
* L2_1 L2_2 L2_3 L2_4 * L2_1 L2_2 L2_3 L2_4
*/ */
@Test @Test
public void testClassificationDefValidHierarchy() { public void testClassificationDefValidHierarchy() throws AtlasBaseException {
AtlasClassificationDef classifiL0 = new AtlasClassificationDef("L0"); AtlasClassificationDef classifiL0 = new AtlasClassificationDef("L0");
AtlasClassificationDef classifiL1_1 = new AtlasClassificationDef("L1-1"); AtlasClassificationDef classifiL1_1 = new AtlasClassificationDef("L1-1");
AtlasClassificationDef classifiL1_2 = new AtlasClassificationDef("L1-2"); AtlasClassificationDef classifiL1_2 = new AtlasClassificationDef("L1-2");
...@@ -135,7 +135,7 @@ public class TestAtlasTypeRegistry { ...@@ -135,7 +135,7 @@ public class TestAtlasTypeRegistry {
} }
@Test @Test
public void testClassificationDefInvalidHierarchy_Self() { public void testClassificationDefInvalidHierarchy_Self() throws AtlasBaseException {
AtlasClassificationDef classifiDef1 = new AtlasClassificationDef("classifiDef-1"); AtlasClassificationDef classifiDef1 = new AtlasClassificationDef("classifiDef-1");
classifiDef1.addSuperType(classifiDef1.getName()); classifiDef1.addSuperType(classifiDef1.getName());
...@@ -171,7 +171,7 @@ public class TestAtlasTypeRegistry { ...@@ -171,7 +171,7 @@ public class TestAtlasTypeRegistry {
* L2_1 L2_2 L2_3 L2_4 * L2_1 L2_2 L2_3 L2_4
*/ */
@Test @Test
public void testClassificationDefInvalidHierarchy_CircularRef() { public void testClassificationDefInvalidHierarchy_CircularRef() throws AtlasBaseException {
AtlasClassificationDef classifiL0 = new AtlasClassificationDef("L0"); AtlasClassificationDef classifiL0 = new AtlasClassificationDef("L0");
AtlasClassificationDef classifiL1_1 = new AtlasClassificationDef("L1-1"); AtlasClassificationDef classifiL1_1 = new AtlasClassificationDef("L1-1");
AtlasClassificationDef classifiL1_2 = new AtlasClassificationDef("L1-2"); AtlasClassificationDef classifiL1_2 = new AtlasClassificationDef("L1-2");
...@@ -228,7 +228,7 @@ public class TestAtlasTypeRegistry { ...@@ -228,7 +228,7 @@ public class TestAtlasTypeRegistry {
* L2_1 L2_2 L2_3 L2_4 * L2_1 L2_2 L2_3 L2_4
*/ */
@Test @Test
public void testEntityDefValidHierarchy() { public void testEntityDefValidHierarchy() throws AtlasBaseException {
AtlasEntityDef entL0 = new AtlasEntityDef("L0"); AtlasEntityDef entL0 = new AtlasEntityDef("L0");
AtlasEntityDef entL1_1 = new AtlasEntityDef("L1-1"); AtlasEntityDef entL1_1 = new AtlasEntityDef("L1-1");
AtlasEntityDef entL1_2 = new AtlasEntityDef("L1-2"); AtlasEntityDef entL1_2 = new AtlasEntityDef("L1-2");
...@@ -315,7 +315,7 @@ public class TestAtlasTypeRegistry { ...@@ -315,7 +315,7 @@ public class TestAtlasTypeRegistry {
} }
@Test @Test
public void testEntityDefInvalidHierarchy_Self() { public void testEntityDefInvalidHierarchy_Self() throws AtlasBaseException {
AtlasEntityDef entDef1 = new AtlasEntityDef("entDef-1"); AtlasEntityDef entDef1 = new AtlasEntityDef("entDef-1");
entDef1.addSuperType(entDef1.getName()); entDef1.addSuperType(entDef1.getName());
...@@ -351,7 +351,7 @@ public class TestAtlasTypeRegistry { ...@@ -351,7 +351,7 @@ public class TestAtlasTypeRegistry {
* L2_1 L2_2 L2_3 L2_4 * L2_1 L2_2 L2_3 L2_4
*/ */
@Test @Test
public void testEntityDefInvalidHierarchy_CircularRef() { public void testEntityDefInvalidHierarchy_CircularRef() throws AtlasBaseException {
AtlasEntityDef entL0 = new AtlasEntityDef("L0"); AtlasEntityDef entL0 = new AtlasEntityDef("L0");
AtlasEntityDef entL1_1 = new AtlasEntityDef("L1-1"); AtlasEntityDef entL1_1 = new AtlasEntityDef("L1-1");
AtlasEntityDef entL1_2 = new AtlasEntityDef("L1-2"); AtlasEntityDef entL1_2 = new AtlasEntityDef("L1-2");
...@@ -399,7 +399,7 @@ public class TestAtlasTypeRegistry { ...@@ -399,7 +399,7 @@ public class TestAtlasTypeRegistry {
} }
@Test @Test
public void testNestedUpdates() { public void testNestedUpdates() throws AtlasBaseException {
AtlasTypeRegistry typeRegistry = new AtlasTypeRegistry(); AtlasTypeRegistry typeRegistry = new AtlasTypeRegistry();
AtlasTransientTypeRegistry ttr = null; AtlasTransientTypeRegistry ttr = null;
boolean commit = false; boolean commit = false;
...@@ -436,7 +436,7 @@ public class TestAtlasTypeRegistry { ...@@ -436,7 +436,7 @@ public class TestAtlasTypeRegistry {
} }
@Test @Test
public void testParallelUpdates() { public void testParallelUpdates() throws AtlasBaseException {
final int numOfThreads = 3; final int numOfThreads = 3;
final int numOfTypesPerKind = 30; final int numOfTypesPerKind = 30;
final String enumTypePrefix = "testEnum-"; final String enumTypePrefix = "testEnum-";
...@@ -503,7 +503,7 @@ public class TestAtlasTypeRegistry { ...@@ -503,7 +503,7 @@ public class TestAtlasTypeRegistry {
* verify that after the update failure, the registry still has correct super-type/sub-type information for L0 and L1 * verify that after the update failure, the registry still has correct super-type/sub-type information for L0 and L1
*/ */
@Test @Test
public void testRegistryValidityOnInvalidUpdate() { public void testRegistryValidityOnInvalidUpdate() throws AtlasBaseException {
AtlasEntityDef entL0 = new AtlasEntityDef("L0"); AtlasEntityDef entL0 = new AtlasEntityDef("L0");
AtlasEntityDef entL1 = new AtlasEntityDef("L1"); AtlasEntityDef entL1 = new AtlasEntityDef("L1");
......
...@@ -101,7 +101,7 @@ public class ClassificationSearchProcessor extends SearchProcessor { ...@@ -101,7 +101,7 @@ public class ClassificationSearchProcessor extends SearchProcessor {
each of above cases with either has empty/or not tagFilters each of above cases with either has empty/or not tagFilters
*/ */
final boolean useIndexSearchForEntity = (classificationType != null || isWildcardSearch) && final boolean useIndexSearchForEntity = (classificationType != null || isWildcardSearch) &&
filterCriteria == null && !context.hasAttributeFilter(filterCriteria) &&
(typeAndSubTypesQryStr.length() <= MAX_QUERY_STR_LENGTH_TAGS); (typeAndSubTypesQryStr.length() <= MAX_QUERY_STR_LENGTH_TAGS);
/* If classification's attributes can be applied index filter, we can use direct index /* If classification's attributes can be applied index filter, we can use direct index
......
...@@ -49,10 +49,12 @@ import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_NOT_CLASSIFIED; ...@@ -49,10 +49,12 @@ 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.SearchContext.MATCH_ALL_WILDCARD_CLASSIFICATION;
import static org.apache.atlas.repository.Constants.PROPAGATED_TRAIT_NAMES_PROPERTY_KEY; import static org.apache.atlas.repository.Constants.PROPAGATED_TRAIT_NAMES_PROPERTY_KEY;
import static org.apache.atlas.repository.Constants.TRAIT_NAMES_PROPERTY_KEY; import static org.apache.atlas.repository.Constants.TRAIT_NAMES_PROPERTY_KEY;
import static org.apache.atlas.repository.Constants.TYPE_NAME_PROPERTY_KEY;
import static org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator.EQUAL; import static org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator.EQUAL;
import static org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator.NOT_EQUAL; import static org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator.NOT_EQUAL;
import static org.apache.atlas.repository.graphdb.AtlasGraphQuery.SortOrder.ASC; import static org.apache.atlas.repository.graphdb.AtlasGraphQuery.SortOrder.ASC;
import static org.apache.atlas.repository.graphdb.AtlasGraphQuery.SortOrder.DESC; import static org.apache.atlas.repository.graphdb.AtlasGraphQuery.SortOrder.DESC;
import static org.apache.atlas.type.AtlasEntityType.ENTITY_ROOT;
public class EntitySearchProcessor extends SearchProcessor { public class EntitySearchProcessor extends SearchProcessor {
private static final Logger LOG = LoggerFactory.getLogger(EntitySearchProcessor.class); private static final Logger LOG = LoggerFactory.getLogger(EntitySearchProcessor.class);
...@@ -86,11 +88,10 @@ public class EntitySearchProcessor extends SearchProcessor { ...@@ -86,11 +88,10 @@ public class EntitySearchProcessor extends SearchProcessor {
filterClassification = false; filterClassification = false;
} }
final Predicate typeNamePredicate = SearchPredicateUtil.getINPredicateGenerator() final Predicate typeNamePredicate;
.generatePredicate(Constants.TYPE_NAME_PROPERTY_KEY, typeAndSubTypes, String.class); final Predicate traitPredicate;
final Predicate activePredicate = SearchPredicateUtil.getEQPredicateGenerator() final Predicate activePredicate = SearchPredicateUtil.getEQPredicateGenerator()
.generatePredicate(Constants.STATE_PROPERTY_KEY, "ACTIVE", String.class); .generatePredicate(Constants.STATE_PROPERTY_KEY, "ACTIVE", String.class);
final Predicate traitPredicate;
if (classificationType == MATCH_ALL_WILDCARD_CLASSIFICATION || classificationType == MATCH_ALL_CLASSIFIED) { if (classificationType == MATCH_ALL_WILDCARD_CLASSIFICATION || classificationType == MATCH_ALL_CLASSIFIED) {
traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getNotEmptyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, null, List.class), traitPredicate = PredicateUtils.orPredicate(SearchPredicateUtil.getNotEmptyPredicateGenerator().generatePredicate(TRAIT_NAMES_PROPERTY_KEY, null, List.class),
...@@ -103,6 +104,12 @@ public class EntitySearchProcessor extends SearchProcessor { ...@@ -103,6 +104,12 @@ public class EntitySearchProcessor extends SearchProcessor {
SearchPredicateUtil.getContainsAnyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, classificationTypeAndSubTypes, List.class)); SearchPredicateUtil.getContainsAnyPredicateGenerator().generatePredicate(PROPAGATED_TRAIT_NAMES_PROPERTY_KEY, classificationTypeAndSubTypes, List.class));
} }
if (!isEntityRootType()) {
typeNamePredicate = SearchPredicateUtil.getINPredicateGenerator().generatePredicate(TYPE_NAME_PROPERTY_KEY, typeAndSubTypes, String.class);
} else {
typeNamePredicate = null;
}
processSearchAttributes(entityType, filterCriteria, indexAttributes, graphAttributes, allAttributes); processSearchAttributes(entityType, filterCriteria, indexAttributes, graphAttributes, allAttributes);
final boolean typeSearchByIndex = !filterClassification && typeAndSubTypesQryStr.length() <= MAX_QUERY_STR_LENGTH_TYPES; final boolean typeSearchByIndex = !filterClassification && typeAndSubTypesQryStr.length() <= MAX_QUERY_STR_LENGTH_TYPES;
...@@ -114,7 +121,9 @@ public class EntitySearchProcessor extends SearchProcessor { ...@@ -114,7 +121,9 @@ public class EntitySearchProcessor extends SearchProcessor {
graphIndexQueryBuilder.addTypeAndSubTypesQueryFilter(indexQuery, typeAndSubTypesQryStr); graphIndexQueryBuilder.addTypeAndSubTypesQueryFilter(indexQuery, typeAndSubTypesQryStr);
// TypeName check to be done in-memory as well to address ATLAS-2121 (case sensitivity) // TypeName check to be done in-memory as well to address ATLAS-2121 (case sensitivity)
inMemoryPredicate = typeNamePredicate; if (typeNamePredicate != null) {
inMemoryPredicate = typeNamePredicate;
}
} }
if (attrSearchByIndex) { if (attrSearchByIndex) {
...@@ -148,7 +157,7 @@ public class EntitySearchProcessor extends SearchProcessor { ...@@ -148,7 +157,7 @@ public class EntitySearchProcessor extends SearchProcessor {
AtlasGraphQuery query = context.getGraph().query(); AtlasGraphQuery query = context.getGraph().query();
if (!typeSearchByIndex) { if (!typeSearchByIndex) {
query.in(Constants.TYPE_NAME_PROPERTY_KEY, typeAndSubTypes); query.in(TYPE_NAME_PROPERTY_KEY, typeAndSubTypes);
} }
// If we need to filter on the trait names then we need to build the query and equivalent in-memory predicate // If we need to filter on the trait names then we need to build the query and equivalent in-memory predicate
...@@ -211,21 +220,26 @@ public class EntitySearchProcessor extends SearchProcessor { ...@@ -211,21 +220,26 @@ public class EntitySearchProcessor extends SearchProcessor {
} }
// Prepare the graph query and in-memory filter for the filtering phase // Prepare the graph query and in-memory filter for the filtering phase
filterGraphQueryPredicate = typeNamePredicate; if (typeNamePredicate != null) {
filterGraphQueryPredicate = typeNamePredicate;
}
Predicate attributesPredicate = constructInMemoryPredicate(entityType, filterCriteria, allAttributes); Predicate attributesPredicate = constructInMemoryPredicate(entityType, filterCriteria, allAttributes);
if (attributesPredicate != null) { if (attributesPredicate != null) {
filterGraphQueryPredicate = PredicateUtils.andPredicate(filterGraphQueryPredicate, attributesPredicate); filterGraphQueryPredicate = filterGraphQueryPredicate == null ? attributesPredicate :
PredicateUtils.andPredicate(filterGraphQueryPredicate, attributesPredicate);
} }
if (filterClassification) { if (filterClassification) {
filterGraphQueryPredicate = PredicateUtils.andPredicate(filterGraphQueryPredicate, traitPredicate); filterGraphQueryPredicate = filterGraphQueryPredicate == null ? traitPredicate :
PredicateUtils.andPredicate(filterGraphQueryPredicate, traitPredicate);
} }
// Filter condition for the STATUS // Filter condition for the STATUS
if (context.getSearchParameters().getExcludeDeletedEntities()) { if (context.getSearchParameters().getExcludeDeletedEntities()) {
filterGraphQueryPredicate = PredicateUtils.andPredicate(filterGraphQueryPredicate, activePredicate); filterGraphQueryPredicate = filterGraphQueryPredicate == null ? activePredicate :
PredicateUtils.andPredicate(filterGraphQueryPredicate, activePredicate);
} }
} }
......
...@@ -32,6 +32,7 @@ import java.util.Iterator; ...@@ -32,6 +32,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_CLASSIFIED; import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_CLASSIFIED;
import static org.apache.atlas.discovery.SearchContext.MATCH_ALL_ENTITY_TYPES;
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.SearchContext.MATCH_ALL_WILDCARD_CLASSIFICATION;
...@@ -52,7 +53,7 @@ public class FullTextSearchProcessor extends SearchProcessor { ...@@ -52,7 +53,7 @@ public class FullTextSearchProcessor extends SearchProcessor {
// if search includes entity-type criteria, adding a filter here can help avoid unnecessary // if search includes entity-type criteria, adding a filter here can help avoid unnecessary
// processing (and rejection) by subsequent EntitySearchProcessor // processing (and rejection) by subsequent EntitySearchProcessor
if (context.getEntityType() != null) { if (context.getEntityType() != null && context.getEntityType() != MATCH_ALL_ENTITY_TYPES) {
String typeAndSubTypeNamesQryStr = context.getEntityType().getTypeAndAllSubTypesQryStr(); String typeAndSubTypeNamesQryStr = context.getEntityType().getTypeAndAllSubTypesQryStr();
if (typeAndSubTypeNamesQryStr.length() <= MAX_QUERY_STR_LENGTH_TYPES) { if (typeAndSubTypeNamesQryStr.length() <= MAX_QUERY_STR_LENGTH_TYPES) {
......
...@@ -45,7 +45,9 @@ import org.slf4j.LoggerFactory; ...@@ -45,7 +45,9 @@ import org.slf4j.LoggerFactory;
import java.util.*; import java.util.*;
import static org.apache.atlas.discovery.SearchProcessor.ALL_ENTITY_TYPE_QUERY;
import static org.apache.atlas.model.discovery.SearchParameters.ALL_CLASSIFICATIONS; import static org.apache.atlas.model.discovery.SearchParameters.ALL_CLASSIFICATIONS;
import static org.apache.atlas.model.discovery.SearchParameters.ALL_ENTITY_TYPES;
import static org.apache.atlas.model.discovery.SearchParameters.NO_CLASSIFICATIONS; import static org.apache.atlas.model.discovery.SearchParameters.NO_CLASSIFICATIONS;
import static org.apache.atlas.model.discovery.SearchParameters.WILDCARD_CLASSIFICATIONS; import static org.apache.atlas.model.discovery.SearchParameters.WILDCARD_CLASSIFICATIONS;
...@@ -56,24 +58,26 @@ import static org.apache.atlas.model.discovery.SearchParameters.WILDCARD_CLASSIF ...@@ -56,24 +58,26 @@ import static org.apache.atlas.model.discovery.SearchParameters.WILDCARD_CLASSIF
*/ */
public class SearchContext { public class SearchContext {
private static final Logger LOG = LoggerFactory.getLogger(SearchContext.class); private static final Logger LOG = LoggerFactory.getLogger(SearchContext.class);
private final SearchParameters searchParameters;
private final AtlasTypeRegistry typeRegistry; private final AtlasTypeRegistry typeRegistry;
private final AtlasGraph graph; private final AtlasGraph graph;
private final AtlasEntityType entityType;
private final Set<String> indexedKeys; private final Set<String> indexedKeys;
private final Set<String> entityAttributes; private final Set<String> entityAttributes;
private final AtlasEntityType entityType; private final SearchParameters searchParameters;
private final AtlasClassificationType classificationType; private final AtlasClassificationType classificationType;
private final String classificationName; private final String classificationName;
private SearchProcessor searchProcessor;
private boolean terminateSearch = false;
private final Set<String> typeAndSubTypes; private final Set<String> typeAndSubTypes;
private final Set<String> classificationTypeAndSubTypes; private final Set<String> classificationTypeAndSubTypes;
private final String typeAndSubTypesQryStr; private final String typeAndSubTypesQryStr;
private final String classificationTypeAndSubTypesQryStr; private final String classificationTypeAndSubTypesQryStr;
private boolean terminateSearch = false;
private SearchProcessor searchProcessor;
public final static AtlasClassificationType MATCH_ALL_WILDCARD_CLASSIFICATION = new AtlasClassificationType(new AtlasClassificationDef(WILDCARD_CLASSIFICATIONS)); public final static AtlasClassificationType MATCH_ALL_WILDCARD_CLASSIFICATION = new AtlasClassificationType(new AtlasClassificationDef(WILDCARD_CLASSIFICATIONS));
public final static AtlasClassificationType MATCH_ALL_CLASSIFIED = new AtlasClassificationType(new AtlasClassificationDef(ALL_CLASSIFICATIONS)); public final static AtlasClassificationType MATCH_ALL_CLASSIFIED = new AtlasClassificationType(new AtlasClassificationDef(ALL_CLASSIFICATIONS));
public final static AtlasClassificationType MATCH_ALL_NOT_CLASSIFIED = new AtlasClassificationType(new AtlasClassificationDef(NO_CLASSIFICATIONS)); public final static AtlasClassificationType MATCH_ALL_NOT_CLASSIFIED = new AtlasClassificationType(new AtlasClassificationDef(NO_CLASSIFICATIONS));
public final static AtlasEntityType MATCH_ALL_ENTITY_TYPES = AtlasEntityType.getEntityRoot();
public SearchContext(SearchParameters searchParameters, AtlasTypeRegistry typeRegistry, AtlasGraph graph, Set<String> indexedKeys) throws AtlasBaseException { public SearchContext(SearchParameters searchParameters, AtlasTypeRegistry typeRegistry, AtlasGraph graph, Set<String> indexedKeys) throws AtlasBaseException {
this.classificationName = searchParameters.getClassification(); this.classificationName = searchParameters.getClassification();
...@@ -82,7 +86,7 @@ public class SearchContext { ...@@ -82,7 +86,7 @@ public class SearchContext {
this.graph = graph; this.graph = graph;
this.indexedKeys = indexedKeys; this.indexedKeys = indexedKeys;
this.entityAttributes = new HashSet<>(); this.entityAttributes = new HashSet<>();
this.entityType = typeRegistry.getEntityTypeByName(searchParameters.getTypeName()); this.entityType = getEntityType(searchParameters.getTypeName());
this.classificationType = getClassificationType(classificationName); this.classificationType = getClassificationType(classificationName);
// Validate if the type name exists // Validate if the type name exists
...@@ -111,33 +115,25 @@ public class SearchContext { ...@@ -111,33 +115,25 @@ public class SearchContext {
// Invalid attributes will raise an exception with 400 error code // Invalid attributes will raise an exception with 400 error code
validateAttributes(classificationType, searchParameters.getTagFilters()); validateAttributes(classificationType, searchParameters.getTagFilters());
if (entityType != null) { if (classificationType != null && !isBuiltInClassificationType()) {
if (searchParameters.getIncludeSubTypes()) { classificationTypeAndSubTypes = searchParameters.getIncludeSubClassifications() ? classificationType.getTypeAndAllSubTypes() : Collections.singleton(classificationType.getTypeName());
typeAndSubTypes = entityType.getTypeAndAllSubTypes(); classificationTypeAndSubTypesQryStr = searchParameters.getIncludeSubClassifications() ? classificationType.getTypeAndAllSubTypesQryStr() : classificationType.getTypeQryStr();
typeAndSubTypesQryStr = entityType.getTypeAndAllSubTypesQryStr();
} else {
typeAndSubTypes = Collections.singleton(entityType.getTypeName());
typeAndSubTypesQryStr = entityType.getTypeQryStr();
}
} else { } else {
typeAndSubTypes = Collections.emptySet(); classificationTypeAndSubTypes = Collections.emptySet();
typeAndSubTypesQryStr = ""; classificationTypeAndSubTypesQryStr = "";
} }
if (classificationType != null) { if (entityType != null) {
if (classificationType == MATCH_ALL_CLASSIFIED || classificationType == MATCH_ALL_NOT_CLASSIFIED || classificationType == MATCH_ALL_WILDCARD_CLASSIFICATION) { if (entityType.equals(MATCH_ALL_ENTITY_TYPES)) {
classificationTypeAndSubTypes = Collections.emptySet(); typeAndSubTypes = Collections.singleton(ALL_ENTITY_TYPE_QUERY);
classificationTypeAndSubTypesQryStr = ""; typeAndSubTypesQryStr = ALL_ENTITY_TYPE_QUERY;
} else if (searchParameters.getIncludeSubClassifications()) {
classificationTypeAndSubTypes = classificationType.getTypeAndAllSubTypes();
classificationTypeAndSubTypesQryStr = classificationType.getTypeAndAllSubTypesQryStr();
} else { } else {
classificationTypeAndSubTypes = Collections.singleton(classificationType.getTypeName()); typeAndSubTypes = searchParameters.getIncludeSubTypes() ? entityType.getTypeAndAllSubTypes() : Collections.singleton(entityType.getTypeName());
classificationTypeAndSubTypesQryStr = classificationType.getTypeQryStr(); typeAndSubTypesQryStr = searchParameters.getIncludeSubTypes() ? entityType.getTypeAndAllSubTypesQryStr() : entityType.getTypeQryStr();
} }
} else { } else {
classificationTypeAndSubTypes = Collections.emptySet(); typeAndSubTypes = Collections.emptySet();
classificationTypeAndSubTypesQryStr = ""; typeAndSubTypesQryStr = "";
} }
if (glossaryTermVertex != null) { if (glossaryTermVertex != null) {
...@@ -160,7 +156,6 @@ public class SearchContext { ...@@ -160,7 +156,6 @@ public class SearchContext {
addProcessor(new ClassificationSearchProcessor(this)); addProcessor(new ClassificationSearchProcessor(this));
} }
if (needEntityProcessor()) { if (needEntityProcessor()) {
addProcessor(new EntitySearchProcessor(this)); addProcessor(new EntitySearchProcessor(this));
} }
...@@ -190,6 +185,8 @@ public class SearchContext { ...@@ -190,6 +185,8 @@ public class SearchContext {
public SearchProcessor getSearchProcessor() { return searchProcessor; } public SearchProcessor getSearchProcessor() { return searchProcessor; }
public String getClassificationName() {return classificationName;}
public boolean includeEntityType(String entityType) { public boolean includeEntityType(String entityType) {
return typeAndSubTypes.isEmpty() || typeAndSubTypes.contains(entityType); return typeAndSubTypes.isEmpty() || typeAndSubTypes.contains(entityType);
} }
...@@ -285,7 +282,7 @@ public class SearchContext { ...@@ -285,7 +282,7 @@ public class SearchContext {
} }
} }
private boolean hasAttributeFilter(FilterCriteria filterCriteria) { public boolean hasAttributeFilter(FilterCriteria filterCriteria) {
return filterCriteria != null && return filterCriteria != null &&
(CollectionUtils.isNotEmpty(filterCriteria.getCriterion()) || StringUtils.isNotEmpty(filterCriteria.getAttributeName())); (CollectionUtils.isNotEmpty(filterCriteria.getCriterion()) || StringUtils.isNotEmpty(filterCriteria.getAttributeName()));
} }
...@@ -314,6 +311,11 @@ public class SearchContext { ...@@ -314,6 +311,11 @@ public class SearchContext {
return ret; return ret;
} }
private AtlasEntityType getEntityType(String entityName) {
return StringUtils.equals(entityName, ALL_ENTITY_TYPES) ? MATCH_ALL_ENTITY_TYPES :
typeRegistry.getEntityTypeByName(entityName);
}
private AtlasVertex getGlossaryTermVertex(String termName) { private AtlasVertex getGlossaryTermVertex(String termName) {
AtlasVertex ret = null; AtlasVertex ret = null;
......
...@@ -62,6 +62,7 @@ public abstract class SearchProcessor { ...@@ -62,6 +62,7 @@ public abstract class SearchProcessor {
public static final String SPACE_STRING = " "; public static final String SPACE_STRING = " ";
public static final String BRACE_OPEN_STR = "("; public static final String BRACE_OPEN_STR = "(";
public static final String BRACE_CLOSE_STR = ")"; public static final String BRACE_CLOSE_STR = ")";
public static final String ALL_ENTITY_TYPE_QUERY = "[* TO *]";
private static final Map<SearchParameters.Operator, String> OPERATOR_MAP = new HashMap<>(); private static final Map<SearchParameters.Operator, String> OPERATOR_MAP = new HashMap<>();
private static final Map<SearchParameters.Operator, VertexAttributePredicateGenerator> OPERATOR_PREDICATE_MAP = new HashMap<>(); private static final Map<SearchParameters.Operator, VertexAttributePredicateGenerator> OPERATOR_PREDICATE_MAP = new HashMap<>();
...@@ -131,6 +132,10 @@ public abstract class SearchProcessor { ...@@ -131,6 +132,10 @@ public abstract class SearchProcessor {
public abstract List<AtlasVertex> execute(); public abstract List<AtlasVertex> execute();
public abstract long getResultCount(); public abstract long getResultCount();
protected boolean isEntityRootType() {
return context.getEntityType() == SearchContext.MATCH_ALL_ENTITY_TYPES;
}
protected int collectResultVertices(final List<AtlasVertex> ret, final int startIdx, final int limit, int resultIdx, final List<AtlasVertex> entityVertices) { protected int collectResultVertices(final List<AtlasVertex> ret, final int startIdx, final int limit, int resultIdx, final List<AtlasVertex> entityVertices) {
for (AtlasVertex entityVertex : entityVertices) { for (AtlasVertex entityVertex : entityVertices) {
resultIdx++; resultIdx++;
...@@ -204,7 +209,7 @@ public abstract class SearchProcessor { ...@@ -204,7 +209,7 @@ public abstract class SearchProcessor {
// (AND (OR idx-att1=x idx-attr1=y) non-idx-attr=z (AND idx-attr2=xyz idx-attr2=abc)) // (AND (OR idx-att1=x idx-attr1=y) non-idx-attr=z (AND idx-attr2=xyz idx-attr2=abc))
// //
protected boolean canApplyIndexFilter(AtlasStructType structType, FilterCriteria filterCriteria, boolean insideOrCondition) { protected boolean canApplyIndexFilter(AtlasStructType structType, FilterCriteria filterCriteria, boolean insideOrCondition) {
if (filterCriteria == null) { if (!context.hasAttributeFilter(filterCriteria)) {
return true; return true;
} }
......
...@@ -325,15 +325,9 @@ public class DiscoveryREST { ...@@ -325,15 +325,9 @@ public class DiscoveryREST {
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Limit/offset should be non-negative"); throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Limit/offset should be non-negative");
} }
if (StringUtils.isEmpty(parameters.getTypeName()) && !isEmpty(parameters.getEntityFilters())) { if (StringUtils.isEmpty(parameters.getTypeName()) && StringUtils.isEmpty(parameters.getClassification()) &&
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "EntityFilters specified without Type name"); StringUtils.isEmpty(parameters.getQuery()) && StringUtils.isEmpty(parameters.getTermName()) &&
} isEmpty(parameters.getEntityFilters()) && isEmpty(parameters.getTagFilters())) {
if (StringUtils.isEmpty(parameters.getClassification()) && !isEmpty(parameters.getTagFilters())) {
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "TagFilters specified without tag name");
}
if (StringUtils.isEmpty(parameters.getTypeName()) && StringUtils.isEmpty(parameters.getClassification()) && StringUtils.isEmpty(parameters.getQuery()) && StringUtils.isEmpty(parameters.getTermName())) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_SEARCH_PARAMS); throw new AtlasBaseException(AtlasErrorCode.INVALID_SEARCH_PARAMS);
} }
......
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