Commit 08944c54 by Madhan Neethiraj

ATLAS-1593: fix type-update handling to ensure that active type registry state…

ATLAS-1593: fix type-update handling to ensure that active type registry state is not updated while processing the changes
parent 765d556c
......@@ -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 {
......
......@@ -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;
......
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