This is an automated email from the ASF dual-hosted git repository. madhan pushed a commit to branch branch-2.0 in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/branch-2.0 by this push: new dc0e306 ATLAS-3716: updated entity-def to support displayTextAttribute option dc0e306 is described below commit dc0e306817c2952dff0d16da37fe2038e661ccc7 Author: Madhan Neethiraj <mad...@apache.org> AuthorDate: Thu Apr 2 10:59:40 2020 -0700 ATLAS-3716: updated entity-def to support displayTextAttribute option (cherry picked from commit 076d83c3face54b53159faa066e398f622d836b0) --- addons/models/1000-Hadoop/1030-hive_model.json | 7 ++- ..._process_execution_add_display_text_option.json | 15 +++++++ .../atlas/model/typedef/AtlasBaseTypeDef.java | 19 ++++++++ .../apache/atlas/model/typedef/AtlasEntityDef.java | 2 + .../org/apache/atlas/type/AtlasEntityType.java | 50 ++++++++++++++++++++-- .../apache/atlas/type/TestAtlasTypeRegistry.java | 32 +++++++++++++- .../store/graph/v2/EntityGraphRetriever.java | 26 +++++++---- .../org/apache/atlas/examples/QuickStartV2.java | 2 + 8 files changed, 138 insertions(+), 15 deletions(-) diff --git a/addons/models/1000-Hadoop/1030-hive_model.json b/addons/models/1000-Hadoop/1030-hive_model.json index 8901aa4..b44f724 100644 --- a/addons/models/1000-Hadoop/1030-hive_model.json +++ b/addons/models/1000-Hadoop/1030-hive_model.json @@ -464,7 +464,7 @@ "ProcessExecution" ], "serviceType": "hive", - "typeVersion" : "1.0", + "typeVersion" : "1.1", "attributeDefs" : [ { "name": "startTime", @@ -530,7 +530,10 @@ "isOptional": false, "isUnique": false } - ] + ], + "options": { + "displayTextAttribute": "queryText" + } }, { "name": "hive_db_ddl", diff --git a/addons/models/1000-Hadoop/patches/016-hive_process_execution_add_display_text_option.json b/addons/models/1000-Hadoop/patches/016-hive_process_execution_add_display_text_option.json new file mode 100644 index 0000000..cb15b34 --- /dev/null +++ b/addons/models/1000-Hadoop/patches/016-hive_process_execution_add_display_text_option.json @@ -0,0 +1,15 @@ +{ + "patches": [ + { + "id": "TYPEDEF_PATCH_1000_016_001", + "description": "Add 'displayTextAttribute' typeDefOptions to hive_process_execution", + "action": "UPDATE_TYPEDEF_OPTIONS", + "typeName": "hive_process_execution", + "applyToVersion": "1.0", + "updateToVersion": "1.1", + "typeDefOptions": { + "displayTextAttribute": "queryText" + } + } + ] +} diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java index eb86345..d461352 100644 --- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java +++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java @@ -18,6 +18,7 @@ package org.apache.atlas.model.typedef; import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.apache.atlas.model.TypeCategory; @@ -307,6 +308,24 @@ public abstract class AtlasBaseTypeDef implements java.io.Serializable { } } + @JsonIgnore + public String getOption(String optionName) { + Map<String, String> options = this.options; + + return options != null ? options.get(optionName) : null; + } + + @JsonIgnore + public void setOption(String optionName, String value) { + Map<String, String> options = this.options; + + if (options == null) { + this.options = options = new HashMap<>(); + } + + options.put(optionName, value); + } + public StringBuilder toString(StringBuilder sb) { if (sb == null) { sb = new StringBuilder(); diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasEntityDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasEntityDef.java index 5bc6e97..d3356fa 100644 --- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasEntityDef.java +++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasEntityDef.java @@ -55,6 +55,8 @@ import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ public class AtlasEntityDef extends AtlasStructDef implements java.io.Serializable { private static final long serialVersionUID = 1L; + public static final String OPTION_DISPLAY_TEXT_ATTRIBUTE = "displayTextAttribute"; + private Set<String> superTypes; // this is a read-only field, any value provided during create & update operation is ignored 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 b592701..3962c3c 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java @@ -86,6 +86,7 @@ public class AtlasEntityType extends AtlasStructType { private Map<String, Map<String, AtlasAttribute>> relationshipAttributes = Collections.emptyMap(); private Map<String, Map<String, AtlasBusinessAttribute>> businessAttributes = Collections.emptyMap(); private List<AtlasAttribute> ownedRefAttributes = Collections.emptyList(); + private String displayTextAttribute = null; private String typeAndAllSubTypesQryStr = ""; private boolean isInternalType = false; private Map<String, AtlasAttribute> headerAttributes = Collections.emptyMap(); @@ -98,15 +99,17 @@ public class AtlasEntityType extends AtlasStructType { public AtlasEntityType(AtlasEntityDef entityDef) { super(entityDef); - this.entityDef = entityDef; - this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName())); + this.entityDef = entityDef; + this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName())); + this.displayTextAttribute = entityDef.getOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE); } public AtlasEntityType(AtlasEntityDef entityDef, AtlasTypeRegistry typeRegistry) throws AtlasBaseException { super(entityDef); - this.entityDef = entityDef; - this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName())); + this.entityDef = entityDef; + this.typeQryStr = AtlasAttribute.escapeIndexQueryValue(Collections.singleton(getTypeName())); + this.displayTextAttribute = entityDef.getOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE); resolveReferences(typeRegistry); } @@ -181,6 +184,29 @@ public class AtlasEntityType extends AtlasStructType { } } } + + if (this.displayTextAttribute != null) { + if (getAttribute(this.displayTextAttribute) == null) { + LOG.warn("{}: ignoring option {}, as attribute {} does not exist", getTypeName(), AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE, this.displayTextAttribute); + + this.displayTextAttribute = null; + } + } + + if (this.displayTextAttribute == null) { // find displayTextAttribute in direct superTypes + for (AtlasEntityType superType : superTypes) { + // read from superType's entityDef; not from superType.getDisplayTextAttribute(), as that might have been resolved to its superType + this.displayTextAttribute = superType.getEntityDef().getOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE); + + if (this.displayTextAttribute != null) { + if (getAttribute(this.displayTextAttribute) == null) { // if displayTextAttribute in superType is invalid, ignore + this.displayTextAttribute = null; + } else { + break; + } + } + } + } } @Override @@ -321,6 +347,18 @@ public class AtlasEntityType extends AtlasStructType { entityDef.setBusinessAttributeDefs(bmAttributeDefs); + if (this.displayTextAttribute == null) { + for (String superTypeName : allSuperTypes) { // find displayTextAttribute in all superTypes + AtlasEntityType superType = typeRegistry.getEntityTypeByName(superTypeName); + + this.displayTextAttribute = superType.getDisplayTextAttribute(); + + if (this.displayTextAttribute != null) { + break; + } + } + } + this.parsedTemplates = parseDynAttributeTemplates(); populateDynFlagsInfo(); @@ -413,6 +451,10 @@ public class AtlasEntityType extends AtlasStructType { return ownedRefAttributes; } + public String getDisplayTextAttribute() { + return displayTextAttribute; + } + public List<AtlasAttribute> getDynEvalAttributes() { return dynAttributes; } @VisibleForTesting diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java index 945c06b..3b55a63 100644 --- a/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java +++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java @@ -26,6 +26,7 @@ import org.testng.annotations.Test; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; @@ -219,7 +220,7 @@ public class TestAtlasTypeRegistry { } /* - * L0 + * L0 L0_1 * / \ * / \ * L1_1---- L1_2 @@ -230,6 +231,7 @@ public class TestAtlasTypeRegistry { @Test public void testEntityDefValidHierarchy() throws AtlasBaseException { AtlasEntityDef entL0 = new AtlasEntityDef("L0"); + AtlasEntityDef entL0_1 = new AtlasEntityDef("L0-1"); AtlasEntityDef entL1_1 = new AtlasEntityDef("L1-1"); AtlasEntityDef entL1_2 = new AtlasEntityDef("L1-2"); AtlasEntityDef entL2_1 = new AtlasEntityDef("L2-1"); @@ -253,9 +255,16 @@ public class TestAtlasTypeRegistry { entL2_3.addAttribute(new AtlasAttributeDef("L2-3_a1", AtlasBaseTypeDef.ATLAS_TYPE_INT)); entL2_4.addAttribute(new AtlasAttributeDef("L2-4_a1", AtlasBaseTypeDef.ATLAS_TYPE_INT)); + // set displayNames in L0, L1_1, L2_1 + entL0.setOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE, "L0_a1"); + entL1_1.setOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE, "L1-1_a1"); + entL2_1.setOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE, "L2-1_a1"); + entL2_4.setOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE, "non-existing-attr"); + AtlasTypesDef typesDef = new AtlasTypesDef(); typesDef.getEntityDefs().add(entL0); + typesDef.getEntityDefs().add(entL0_1); typesDef.getEntityDefs().add(entL1_1); typesDef.getEntityDefs().add(entL1_2); typesDef.getEntityDefs().add(entL2_1); @@ -312,6 +321,15 @@ public class TestAtlasTypeRegistry { validateAttributeNames(typeRegistry, "L2-2", new HashSet<>(Arrays.asList("L0_a1", "L1-1_a1", "L2-2_a1"))); validateAttributeNames(typeRegistry, "L2-3", new HashSet<>(Arrays.asList("L0_a1", "L1-1_a1", "L1-2_a1", "L2-3_a1"))); validateAttributeNames(typeRegistry, "L2-4", new HashSet<>(Arrays.asList("L0_a1", "L1-2_a1", "L2-4_a1"))); + + validateDisplayNameAttribute(typeRegistry, "L0", "L0_a1"); // directly assigned for this type + validateDisplayNameAttribute(typeRegistry, "L0-1"); // not assigned for this type + validateDisplayNameAttribute(typeRegistry, "L1-1", "L1-1_a1"); // directly assigned for this type + validateDisplayNameAttribute(typeRegistry, "L1-2", "L0_a1"); // inherits from L0 + validateDisplayNameAttribute(typeRegistry, "L2-1", "L2-1_a1"); // directly assigned for this type + validateDisplayNameAttribute(typeRegistry, "L2-2", "L1-1_a1"); // inherits from L1-1 + validateDisplayNameAttribute(typeRegistry, "L2-3", "L1-1_a1"); // inherits from L1-1 or L0 + validateDisplayNameAttribute(typeRegistry, "L2-4", "L0_a1"); // invalid-name ignored, inherits from L0 } @Test @@ -678,4 +696,16 @@ public class TestAtlasTypeRegistry { assertNotNull(attributes); assertEquals(attributes.keySet(), attributeNames); } + + private void validateDisplayNameAttribute(AtlasTypeRegistry typeRegistry, String entityTypeName, String... displayNameAttributes) { + AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName); + + if (displayNameAttributes == null || displayNameAttributes.length == 0) { + assertNull(entityType.getDisplayTextAttribute()); + } else { + List<String> validValues = Arrays.asList(displayNameAttributes); + + assertTrue(validValues.contains(entityType.getDisplayTextAttribute()), entityTypeName + ": invalid displayNameAttribute " + entityType.getDisplayTextAttribute() + ". Valid values: " + validValues); + } + } } diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java index 3a0d001..36bee30 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java @@ -704,8 +704,7 @@ public class EntityGraphRetriever { } } - Object name = ret.getAttribute(NAME); - Object displayText = name != null ? name : ret.getAttribute(QUALIFIED_NAME); + Object displayText = getDisplayText(entityVertex, entityType); if (displayText != null) { ret.setDisplayText(displayText.toString()); @@ -1484,18 +1483,29 @@ public class EntityGraphRetriever { } private Object getDisplayText(AtlasVertex entityVertex, String entityTypeName) throws AtlasBaseException { - AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName); - Object ret = null; + return getDisplayText(entityVertex, typeRegistry.getEntityTypeByName(entityTypeName)); + } + + private Object getDisplayText(AtlasVertex entityVertex, AtlasEntityType entityType) throws AtlasBaseException { + Object ret = null; if (entityType != null) { - ret = getVertexAttribute(entityVertex, entityType.getAttribute(NAME)); + String displayTextAttribute = entityType.getDisplayTextAttribute(); - if (ret == null) { - ret = getVertexAttribute(entityVertex, entityType.getAttribute(DISPLAY_NAME)); + if (displayTextAttribute != null) { + ret = getVertexAttribute(entityVertex, entityType.getAttribute(displayTextAttribute)); } if (ret == null) { - ret = getVertexAttribute(entityVertex, entityType.getAttribute(QUALIFIED_NAME)); + ret = getVertexAttribute(entityVertex, entityType.getAttribute(NAME)); + + if (ret == null) { + ret = getVertexAttribute(entityVertex, entityType.getAttribute(DISPLAY_NAME)); + + if (ret == null) { + ret = getVertexAttribute(entityVertex, entityType.getAttribute(QUALIFIED_NAME)); + } + } } } diff --git a/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java b/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java index 4474a28..b5d2a47 100755 --- a/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java +++ b/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java @@ -278,6 +278,8 @@ public class QuickStartV2 { createRequiredAttrDef("queryId", "string"), createRequiredAttrDef("queryGraph", "string")); + processExecutionTypeDef.setOption(AtlasEntityDef.OPTION_DISPLAY_TEXT_ATTRIBUTE, "queryText"); + AtlasEntityDef viewTypeDef = createClassTypeDef(VIEW_TYPE, VIEW_TYPE, VERSION_1, Collections.singleton("DataSet")); // Relationship-Definitions