This is an automated email from the ASF dual-hosted git repository.
sarath 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 add9fac ATLAS-3343: Ordering of dynAttr evaluation
add9fac is described below
commit add9fac419addf164fcfe1a35535080ca8b67543
Author: Merryle Wang <[email protected]>
AuthorDate: Thu Aug 8 11:25:22 2019 -0700
ATLAS-3343: Ordering of dynAttr evaluation
Signed-off-by: Sarath Subramanian <[email protected]>
---
.../org/apache/atlas/type/AtlasEntityType.java | 56 +++++++++++++++
.../org/apache/atlas/type/TestAtlasEntityType.java | 82 ++++++++++++++++++++--
2 files changed, 132 insertions(+), 6 deletions(-)
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 23eaa0a..884447f 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -687,6 +687,9 @@ public class AtlasEntityType extends AtlasStructType {
}
}
+ //reorder dynAttributes in a topological sort
+ dynAttributes = reorderDynAttributes();
+
for (List<TemplateToken> parsedTemplate : parsedTemplates.values()) {
for (TemplateToken token : parsedTemplate) {
// If token is an instance of AttributeToken means that the
attribute is of this entity type
@@ -1000,4 +1003,57 @@ public class AtlasEntityType extends AtlasStructType {
return ret;
}
+
+ private List<AtlasAttribute> reorderDynAttributes() {
+ Map<AtlasAttribute, List<AtlasAttribute>> adj =
createTokenAttributesMap();
+
+ return topologicalSort(adj);
+ }
+
+ private List<AtlasAttribute> topologicalSort(Map<AtlasAttribute,
List<AtlasAttribute>> adj){
+ List<AtlasAttribute> order = new ArrayList<>();
+ Set<AtlasAttribute> visited = new HashSet<>();
+
+ for (AtlasAttribute attribute : adj.keySet()) {
+ visitAttribute(attribute, visited, order, adj);
+ }
+
+ Collections.reverse(order);
+
+ return order;
+ }
+
+ private void visitAttribute(AtlasAttribute attribute, Set<AtlasAttribute>
visited, List<AtlasAttribute> order, Map<AtlasAttribute, List<AtlasAttribute>>
adj) {
+ if (!visited.contains(attribute)) {
+ visited.add(attribute);
+
+ for (AtlasAttribute neighbor : adj.get(attribute)) {
+ visitAttribute(neighbor, visited, order, adj);
+ }
+
+ order.add(attribute);
+ }
+ }
+
+ private Map<AtlasAttribute, List<AtlasAttribute>>
createTokenAttributesMap() {
+ Map<AtlasAttribute, List<AtlasAttribute>> adj = new HashMap<>();
+
+ for (AtlasAttribute attribute : dynAttributes) {
+ adj.put(attribute, new ArrayList<>());
+ }
+
+ for (AtlasAttribute attribute : adj.keySet()) {
+ for (TemplateToken token :
parsedTemplates.get(attribute.getName())) {
+ if (token instanceof AttributeToken) {
+ AtlasAttribute tokenAttribute =
getAttribute(token.getValue());
+
+ if (adj.containsKey(tokenAttribute)) {
+ adj.get(tokenAttribute).add(attribute);
+ }
+ }
+ }
+ }
+
+ return adj;
+ }
}
diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasEntityType.java
b/intg/src/test/java/org/apache/atlas/type/TestAtlasEntityType.java
index c114bdf..7429703 100644
--- a/intg/src/test/java/org/apache/atlas/type/TestAtlasEntityType.java
+++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasEntityType.java
@@ -38,12 +38,14 @@ import static org.testng.Assert.*;
public class TestAtlasEntityType {
- private static final String TYPE_TABLE = "my_table";
- private static final String TYPE_COLUMN = "my_column";
- private static final String ATTR_TABLE = "table";
- private static final String ATTR_COLUMNS = "columns";
- private static final String ATTR_OWNER = "owner";
- private static final String ATTR_NAME = "name";
+ private static final String TYPE_TABLE = "my_table";
+ private static final String TYPE_COLUMN = "my_column";
+ private static final String ATTR_TABLE = "table";
+ private static final String ATTR_COLUMNS = "columns";
+ private static final String ATTR_OWNER = "owner";
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_DESCRIPTION = "description";
+ private static final String ATTR_LOCATION = "location";
private final AtlasEntityType entityType;
private final List<Object> validValues = new ArrayList<>();
@@ -198,6 +200,38 @@ public class TestAtlasEntityType {
}
@Test
+ public void testReorderDynAttributes() {
+ AtlasTypeRegistry typeRegistry = new AtlasTypeRegistry();
+ AtlasTransientTypeRegistry ttr = null;
+ boolean commit = false;
+ List<AtlasEntityDef> entityDefs = new ArrayList<>();
+ String failureMsg = null;
+
+ entityDefs.add(createTableEntityDefForTopSort());
+
+ try {
+ ttr = typeRegistry.lockTypeRegistryForUpdate();
+
+ ttr.addTypes(entityDefs);
+ //options are read in the table,
+ AtlasEntityType typeTable = ttr.getEntityTypeByName(TYPE_TABLE);
+
+ // Expect attributes in this order: ATTR_DESCRIPTION, ATTR_OWNER,
ATTR_NAME, ATTR_LOCATION
+ assertEquals(typeTable.getDynEvalAttributes().get(0).getName(),
ATTR_DESCRIPTION);
+ assertEquals(typeTable.getDynEvalAttributes().get(1).getName(),
ATTR_OWNER);
+ assertEquals(typeTable.getDynEvalAttributes().get(2).getName(),
ATTR_NAME);
+ assertEquals(typeTable.getDynEvalAttributes().get(3).getName(),
ATTR_LOCATION);
+
+ commit = true;
+ } catch (AtlasBaseException excp) {
+ failureMsg = excp.getMessage();
+ } finally {
+ typeRegistry.releaseTypeRegistryForUpdate(ttr, commit);
+ }
+ assertNull(failureMsg, "failed to create types " + TYPE_TABLE + " and
" + TYPE_COLUMN);
+ }
+
+ @Test
public void testConstraintInvalidOwnedRef_InvalidAttributeType() {
AtlasTypeRegistry typeRegistry = new AtlasTypeRegistry();
AtlasTransientTypeRegistry ttr = null;
@@ -371,6 +405,42 @@ public class TestAtlasEntityType {
return table;
}
+ private AtlasEntityDef createTableEntityDefForTopSort() {
+ AtlasEntityDef table = new AtlasEntityDef(TYPE_TABLE);
+ AtlasAttributeDef attrName = new AtlasAttributeDef(ATTR_NAME,
AtlasBaseTypeDef.ATLAS_TYPE_STRING);
+ AtlasAttributeDef attrOwner = new AtlasAttributeDef(ATTR_OWNER,
AtlasBaseTypeDef.ATLAS_TYPE_STRING);
+ AtlasAttributeDef attrDescription = new
AtlasAttributeDef(ATTR_DESCRIPTION, AtlasBaseTypeDef.ATLAS_TYPE_STRING);
+ AtlasAttributeDef attrLocation = new
AtlasAttributeDef(ATTR_LOCATION, AtlasBaseTypeDef.ATLAS_TYPE_STRING);
+
+ table.addAttribute(attrName);
+ table.addAttribute(attrOwner);
+ table.addAttribute(attrDescription);
+ table.addAttribute(attrLocation);
+
+ Map<String,String> options = new HashMap<>();
+
+ String key1 = "dynAttribute:" + ATTR_OWNER;
+ String value1 = "{" + ATTR_DESCRIPTION + "}";
+
+ String key2 = "dynAttribute:" + ATTR_DESCRIPTION;
+ String value2 = "template";
+
+ String key3 = "dynAttribute:" + ATTR_NAME;
+ String value3 = "{" + ATTR_DESCRIPTION + "}@{" + ATTR_OWNER + "}";
+
+ String key4 = "dynAttribute:" + ATTR_LOCATION;
+ String value4 = "{" + ATTR_NAME + "}@{" + ATTR_OWNER + "}";
+
+ options.put(key1, value1);
+ options.put(key2, value2);
+ options.put(key3, value3);
+ options.put(key4, value4);
+
+ table.setOptions(options);
+
+ return table;
+ }
+
private AtlasEntityDef createTableEntityDefWithOwnedRefOnInvalidType() {
AtlasEntityDef table = new AtlasEntityDef(TYPE_TABLE);
AtlasAttributeDef attrName = new AtlasAttributeDef(ATTR_NAME,
AtlasBaseTypeDef.ATLAS_TYPE_STRING);