Repository: incubator-atlas
Updated Branches:
  refs/heads/master 765d556cc -> 08944c54d


ATLAS-1593: fix type-update handling to ensure that active type registry state 
is not updated while processing the changes


Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/08944c54
Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/08944c54
Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/08944c54

Branch: refs/heads/master
Commit: 08944c54de13054b4b7a76dbcba79218779f02d3
Parents: 765d556
Author: Madhan Neethiraj <[email protected]>
Authored: Thu Feb 23 17:51:22 2017 -0800
Committer: Madhan Neethiraj <[email protected]>
Committed: Fri Feb 24 16:22:15 2017 -0800

----------------------------------------------------------------------
 .../apache/atlas/type/AtlasTypeRegistry.java    | 22 +++---
 .../atlas/type/TestAtlasTypeRegistry.java       | 77 ++++++++++++++++++++
 2 files changed, 88 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/08944c54/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java 
b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
index 3f3ea59..ddb6c71 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
@@ -65,7 +65,7 @@ public class AtlasTypeRegistry {
 
     // used only by AtlasTransientTypeRegistry
     protected AtlasTypeRegistry(AtlasTypeRegistry other) {
-        registryData       = new RegistryData(other.registryData);
+        registryData       = new RegistryData();
         updateSynchronizer = other.updateSynchronizer;
     }
 
@@ -245,15 +245,6 @@ public class AtlasTypeRegistry {
             allTypes.addType(new AtlasBuiltInTypes.AtlasObjectIdType());
         }
 
-        RegistryData(RegistryData other) {
-            allTypes           = new TypeCache(other.allTypes);
-            enumDefs           = new TypeDefCache<>(other.enumDefs, allTypes);
-            structDefs         = new TypeDefCache<>(other.structDefs, 
allTypes);
-            classificationDefs = new TypeDefCache<>(other.classificationDefs, 
allTypes);
-            entityDefs         = new TypeDefCache<>(other.entityDefs, 
allTypes);
-            allDefCaches       = new TypeDefCache[] { enumDefs, structDefs, 
classificationDefs, entityDefs };
-        }
-
         AtlasBaseTypeDef getTypeDefByName(String name) {
             AtlasBaseTypeDef ret = null;
 
@@ -320,8 +311,17 @@ public class AtlasTypeRegistry {
         private List<AtlasBaseTypeDef> deletedTypes = new ArrayList<>();
 
 
-        private AtlasTransientTypeRegistry(AtlasTypeRegistry parent) {
+        private AtlasTransientTypeRegistry(AtlasTypeRegistry parent) throws 
AtlasBaseException {
             super(parent);
+
+            addTypesWithNoRefResolve(parent.getAllEnumDefs());
+            addTypesWithNoRefResolve(parent.getAllStructDefs());
+            addTypesWithNoRefResolve(parent.getAllClassificationDefs());
+            addTypesWithNoRefResolve(parent.getAllEntityDefs());
+
+            addedTypes.clear();
+            updatedTypes.clear();
+            deletedTypes.clear();
         }
 
         private void resolveReferences() throws AtlasBaseException {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/08944c54/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java
----------------------------------------------------------------------
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 f93a2e8..accba77 100644
--- a/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java
+++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasTypeRegistry.java
@@ -482,6 +482,83 @@ public class TestAtlasTypeRegistry {
         }
     }
 
+    /* create 2 entity types: L0 and L1, with L0 as superType of L1
+     * add entity type L2, with L0, L1 and L2 as super-types - this should 
fail due to L2 self-referencing itself in super-types
+     * verify that after the update failure, the registry still has correct 
super-type/sub-type information for L0 and L1
+     */
+    @Test
+    public void testRegistryValidityOnInvalidUpdate() {
+        AtlasEntityDef entL0 = new AtlasEntityDef("L0");
+        AtlasEntityDef entL1 = new AtlasEntityDef("L1");
+
+        entL1.addSuperType(entL0.getName());
+
+        entL0.addAttribute(new AtlasAttributeDef("L0_a1", 
AtlasBaseTypeDef.ATLAS_TYPE_INT));
+        entL1.addAttribute(new AtlasAttributeDef("L1_a1", 
AtlasBaseTypeDef.ATLAS_TYPE_INT));
+
+        AtlasTypesDef typesDef = new AtlasTypesDef();
+
+        typesDef.getEntityDefs().add(entL0);
+        typesDef.getEntityDefs().add(entL1);
+
+        AtlasTypeRegistry          typeRegistry = new AtlasTypeRegistry();
+        AtlasTransientTypeRegistry ttr          = null;
+        boolean                    commit       = false;
+        String                     failureMsg   = null;
+
+        try {
+            ttr = typeRegistry.lockTypeRegistryForUpdate();
+
+            ttr.addTypes(typesDef);
+
+            commit = true;
+        } catch (AtlasBaseException excp) {
+            failureMsg = excp.getMessage();
+        } finally {
+            typeRegistry.releaseTypeRegistryForUpdate(ttr, commit);
+        }
+        assertNull(failureMsg);
+
+        validateSuperTypes(typeRegistry, "L0", new HashSet<String>());
+        validateSubTypes(typeRegistry, "L0", new 
HashSet<>(Arrays.asList("L1")));
+
+        validateSuperTypes(typeRegistry, "L1", new 
HashSet<>(Arrays.asList("L0")));
+        validateSubTypes(typeRegistry, "L1", new HashSet<String>());
+
+
+        // create a circular reference
+        AtlasEntityDef entL2 = new AtlasEntityDef("L2");
+        entL2.addSuperType(entL0.getName());
+        entL2.addSuperType(entL1.getName());
+        entL2.addSuperType(entL2.getName());
+
+        typesDef.clear();
+        typesDef.getEntityDefs().add(entL2);
+
+        try {
+            commit = false;
+
+            ttr = typeRegistry.lockTypeRegistryForUpdate();
+
+            ttr.updateTypes(typesDef);
+
+            commit = true;
+        } catch (AtlasBaseException excp) {
+            failureMsg = excp.getMessage();
+        } finally {
+            typeRegistry.releaseTypeRegistryForUpdate(ttr, commit);
+        }
+        assertNotNull(failureMsg);
+
+        assertNull(typeRegistry.getEntityTypeByName("L2"));
+
+        validateSuperTypes(typeRegistry, "L0", new HashSet<String>());
+        validateSubTypes(typeRegistry, "L0", new 
HashSet<>(Arrays.asList("L1")));
+
+        validateSuperTypes(typeRegistry, "L1", new 
HashSet<>(Arrays.asList("L0")));
+        validateSubTypes(typeRegistry, "L1", new HashSet<String>());
+    }
+
     private boolean addType(AtlasTypeRegistry typeRegistry, AtlasBaseTypeDef 
typeDef) {
         boolean                    ret = false;
         AtlasTransientTypeRegistry ttr = null;

Reply via email to