Commit 86dd72af by Shwetha GS

ATLAS-911 Get entity by unique attribute doesn't enforce type (shwethags)

parent c9ee6d3f
...@@ -23,6 +23,7 @@ ATLAS-409 Atlas will not import avro tables with schema read from a file (dosset ...@@ -23,6 +23,7 @@ ATLAS-409 Atlas will not import avro tables with schema read from a file (dosset
ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via shwethags) ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via shwethags)
ALL CHANGES: ALL CHANGES:
ATLAS-911 Get entity by unique attribute doesn't enforce type (shwethags)
ATLAS-899 Fix Hive Hook documentation (sumasai via yhemanth) ATLAS-899 Fix Hive Hook documentation (sumasai via yhemanth)
ATLAS-890 Log received messages in case of error (sumasai via yhemanth) ATLAS-890 Log received messages in case of error (sumasai via yhemanth)
ATLAS-888 NPE in NotificationHookConsumer (sumasai via shwethags) ATLAS-888 NPE in NotificationHookConsumer (sumasai via shwethags)
......
...@@ -37,6 +37,7 @@ import org.apache.atlas.typesystem.ITypedStruct; ...@@ -37,6 +37,7 @@ import org.apache.atlas.typesystem.ITypedStruct;
import org.apache.atlas.typesystem.exception.EntityExistsException; import org.apache.atlas.typesystem.exception.EntityExistsException;
import org.apache.atlas.typesystem.exception.EntityNotFoundException; import org.apache.atlas.typesystem.exception.EntityNotFoundException;
import org.apache.atlas.typesystem.exception.TraitNotFoundException; import org.apache.atlas.typesystem.exception.TraitNotFoundException;
import org.apache.atlas.typesystem.persistence.Id;
import org.apache.atlas.typesystem.types.AttributeInfo; import org.apache.atlas.typesystem.types.AttributeInfo;
import org.apache.atlas.typesystem.types.ClassType; import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.DataTypes; import org.apache.atlas.typesystem.types.DataTypes;
...@@ -158,7 +159,9 @@ public class GraphBackedMetadataRepository implements MetadataRepository { ...@@ -158,7 +159,9 @@ public class GraphBackedMetadataRepository implements MetadataRepository {
LOG.info("Retrieving entity with type={} and {}={}", entityType, attribute, value); LOG.info("Retrieving entity with type={} and {}={}", entityType, attribute, value);
IDataType type = typeSystem.getDataType(IDataType.class, entityType); IDataType type = typeSystem.getDataType(IDataType.class, entityType);
String propertyKey = getFieldNameInVertex(type, attribute); String propertyKey = getFieldNameInVertex(type, attribute);
Vertex instanceVertex = graphHelper.getVertexForProperty(propertyKey, value); Vertex instanceVertex = graphHelper.findVertex(propertyKey, value,
Constants.ENTITY_TYPE_PROPERTY_KEY, entityType,
Constants.STATE_PROPERTY_KEY, Id.EntityState.ACTIVE.name());
String guid = instanceVertex.getProperty(Constants.GUID_PROPERTY_KEY); String guid = instanceVertex.getProperty(Constants.GUID_PROPERTY_KEY);
return graphToInstanceMapper.mapGraphToTypedInstance(guid, instanceVertex); return graphToInstanceMapper.mapGraphToTypedInstance(guid, instanceVertex);
......
...@@ -164,7 +164,7 @@ public final class GraphHelper { ...@@ -164,7 +164,7 @@ public final class GraphHelper {
* @return vertex with the given property keys * @return vertex with the given property keys
* @throws EntityNotFoundException * @throws EntityNotFoundException
*/ */
private Vertex findVertex(Object... args) throws EntityNotFoundException { public Vertex findVertex(Object... args) throws EntityNotFoundException {
StringBuilder condition = new StringBuilder(); StringBuilder condition = new StringBuilder();
GraphQuery query = titanGraph.query(); GraphQuery query = titanGraph.query();
for (int i = 0 ; i < args.length; i+=2) { for (int i = 0 ; i < args.length; i+=2) {
...@@ -301,10 +301,6 @@ public final class GraphHelper { ...@@ -301,10 +301,6 @@ public final class GraphHelper {
return findVertex(Constants.GUID_PROPERTY_KEY, guid); return findVertex(Constants.GUID_PROPERTY_KEY, guid);
} }
public Vertex getVertexForProperty(String propertyKey, Object value) throws EntityNotFoundException {
return findVertex(propertyKey, value, Constants.STATE_PROPERTY_KEY, Id.EntityState.ACTIVE.name());
}
public static String getQualifiedNameForMapKey(String prefix, String key) { public static String getQualifiedNameForMapKey(String prefix, String key) {
return prefix + "." + key; return prefix + "." + key;
} }
...@@ -381,7 +377,9 @@ public final class GraphHelper { ...@@ -381,7 +377,9 @@ public final class GraphHelper {
if (attributeInfo.isUnique) { if (attributeInfo.isUnique) {
String propertyKey = getQualifiedFieldName(classType, attributeInfo.name); String propertyKey = getQualifiedFieldName(classType, attributeInfo.name);
try { try {
result = getVertexForProperty(propertyKey, instance.get(attributeInfo.name)); result = findVertex(propertyKey, instance.get(attributeInfo.name),
Constants.ENTITY_TYPE_PROPERTY_KEY, classType.getName(),
Constants.STATE_PROPERTY_KEY, Id.EntityState.ACTIVE.name());
LOG.debug("Found vertex by unique attribute : " + propertyKey + "=" + instance.get(attributeInfo.name)); LOG.debug("Found vertex by unique attribute : " + propertyKey + "=" + instance.get(attributeInfo.name));
} catch (EntityNotFoundException e) { } catch (EntityNotFoundException e) {
//Its ok if there is no entity with the same unique value //Its ok if there is no entity with the same unique value
......
...@@ -206,7 +206,6 @@ public final class TestUtils { ...@@ -206,7 +206,6 @@ public final class TestUtils {
createOptionalAttrDef("namespace", DataTypes.STRING_TYPE), createOptionalAttrDef("namespace", DataTypes.STRING_TYPE),
createOptionalAttrDef("cluster", DataTypes.STRING_TYPE), createOptionalAttrDef("cluster", DataTypes.STRING_TYPE),
createOptionalAttrDef("colo", DataTypes.STRING_TYPE)); createOptionalAttrDef("colo", DataTypes.STRING_TYPE));
HierarchicalTypeDefinition<ClassType> databaseTypeDefinition = HierarchicalTypeDefinition<ClassType> databaseTypeDefinition =
createClassTypeDef(DATABASE_TYPE, DATABASE_TYPE + _description,ImmutableSet.of(SUPER_TYPE_NAME), createClassTypeDef(DATABASE_TYPE, DATABASE_TYPE + _description,ImmutableSet.of(SUPER_TYPE_NAME),
TypesUtil.createUniqueRequiredAttrDef(NAME, DataTypes.STRING_TYPE), TypesUtil.createUniqueRequiredAttrDef(NAME, DataTypes.STRING_TYPE),
......
...@@ -77,7 +77,7 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest { ...@@ -77,7 +77,7 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem); ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem);
repositoryService.createEntities(hrDept); repositoryService.createEntities(hrDept);
ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Person", "name", "Jane"); ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Manager", "name", "Jane");
Id janeGuid = jane.getId(); Id janeGuid = jane.getId();
ClassType personType = typeSystem.getDataType(ClassType.class, "Person"); ClassType personType = typeSystem.getDataType(ClassType.class, "Person");
ITypedReferenceableInstance instance = personType.createInstance(janeGuid); ITypedReferenceableInstance instance = personType.createInstance(janeGuid);
......
...@@ -514,7 +514,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase { ...@@ -514,7 +514,7 @@ public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
AtlasClient.EntityResult entityResult = deleteEntities(maxGuid); AtlasClient.EntityResult entityResult = deleteEntities(maxGuid);
ITypedReferenceableInstance john = repositoryService.getEntityDefinition("Manager", "name", "John"); ITypedReferenceableInstance john = repositoryService.getEntityDefinition("Person", "name", "John");
assertEquals(entityResult.getDeletedEntities().size(), 1); assertEquals(entityResult.getDeletedEntities().size(), 1);
assertTrue(entityResult.getDeletedEntities().contains(maxGuid)); assertTrue(entityResult.getDeletedEntities().contains(maxGuid));
......
...@@ -25,7 +25,6 @@ import com.thinkaurelius.titan.core.util.TitanCleanup; ...@@ -25,7 +25,6 @@ import com.thinkaurelius.titan.core.util.TitanCleanup;
import com.tinkerpop.blueprints.Compare; import com.tinkerpop.blueprints.Compare;
import com.tinkerpop.blueprints.GraphQuery; import com.tinkerpop.blueprints.GraphQuery;
import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.Vertex;
import org.apache.atlas.GraphTransaction; import org.apache.atlas.GraphTransaction;
import org.apache.atlas.RepositoryMetadataModule; import org.apache.atlas.RepositoryMetadataModule;
import org.apache.atlas.RequestContext; import org.apache.atlas.RequestContext;
...@@ -57,11 +56,9 @@ import org.testng.annotations.BeforeClass; ...@@ -57,11 +56,9 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import scala.actors.threadpool.Arrays; import scala.actors.threadpool.Arrays;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
...@@ -69,6 +66,11 @@ import java.util.Iterator; ...@@ -69,6 +66,11 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import static org.apache.atlas.typesystem.types.utils.TypesUtil.createClassTypeDef;
import static org.apache.atlas.typesystem.types.utils.TypesUtil.createUniqueRequiredAttrDef;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
/** /**
* GraphBackedMetadataRepository test * GraphBackedMetadataRepository test
* *
...@@ -186,7 +188,7 @@ public class GraphBackedMetadataRepositoryTest { ...@@ -186,7 +188,7 @@ public class GraphBackedMetadataRepositoryTest {
//Reuse the same database instance without id, with the same unique attribute //Reuse the same database instance without id, with the same unique attribute
ITypedReferenceableInstance table = createHiveTableInstance(databaseInstance); ITypedReferenceableInstance table = createHiveTableInstance(databaseInstance);
List<String> guids = repositoryService.createEntities(db, table); List<String> guids = createEntities(db, table);
Assert.assertEquals(guids.size(), 7); //1 db + 5 columns + 1 table. Shouldn't create db again Assert.assertEquals(guids.size(), 7); //1 db + 5 columns + 1 table. Shouldn't create db again
System.out.println("added db = " + guids.get(0)); System.out.println("added db = " + guids.get(0));
System.out.println("added table = " + guids.get(6)); System.out.println("added table = " + guids.get(6));
...@@ -201,6 +203,17 @@ public class GraphBackedMetadataRepositoryTest { ...@@ -201,6 +203,17 @@ public class GraphBackedMetadataRepositoryTest {
System.out.println("*** table = " + table); System.out.println("*** table = " + table);
} }
private List<String> createEntities(ITypedReferenceableInstance... instances) throws Exception {
RequestContext.createContext();
return repositoryService.createEntities(instances);
}
private List<String> createEntity(Referenceable entity) throws Exception {
ClassType type = typeSystem.getDataType(ClassType.class, entity.getTypeName());
ITypedReferenceableInstance instance = type.convert(entity, Multiplicity.REQUIRED);
return createEntities(instance);
}
@GraphTransaction @GraphTransaction
String getGUID() { String getGUID() {
Vertex tableVertex = getTableEntityVertex(); Vertex tableVertex = getTableEntityVertex();
...@@ -245,6 +258,36 @@ public class GraphBackedMetadataRepositoryTest { ...@@ -245,6 +258,36 @@ public class GraphBackedMetadataRepositoryTest {
Assert.fail(); Assert.fail();
} }
@Test
public void testMultipleTypesWithSameUniqueAttribute() throws Exception {
//Two entities of different types(with same supertype that has the unique attribute) with same qualified name should succeed
HierarchicalTypeDefinition<ClassType> supertype =
createClassTypeDef(randomString(), ImmutableSet.<String>of(),
createUniqueRequiredAttrDef("name", DataTypes.STRING_TYPE));
HierarchicalTypeDefinition<ClassType> t1 =
createClassTypeDef(randomString(), ImmutableSet.of(supertype.typeName));
HierarchicalTypeDefinition<ClassType> t2 =
createClassTypeDef(randomString(), ImmutableSet.of(supertype.typeName));
typeSystem.defineClassTypes(supertype, t1, t2);
final String name = randomString();
String id1 = createEntity(new Referenceable(t1.typeName) {{
set("name", name);
}}).get(0);
String id2 = createEntity(new Referenceable(t2.typeName) {{
set("name", name);
}}).get(0);
assertNotEquals(id1, id2);
ITypedReferenceableInstance entity = repositoryService.getEntityDefinition(t1.typeName, "name", name);
assertEquals(entity.getTypeName(), t1.typeName);
assertEquals(entity.getId()._getId(), id1);
entity = repositoryService.getEntityDefinition(t2.typeName, "name", name);
assertEquals(entity.getTypeName(), t2.typeName);
assertEquals(entity.getId()._getId(), id2);
}
@Test(dependsOnMethods = "testGetTraitNames") @Test(dependsOnMethods = "testGetTraitNames")
public void testAddTrait() throws Exception { public void testAddTrait() throws Exception {
final String aGUID = getGUID(); final String aGUID = getGUID();
...@@ -574,18 +617,22 @@ public class GraphBackedMetadataRepositoryTest { ...@@ -574,18 +617,22 @@ public class GraphBackedMetadataRepositoryTest {
return tableType.convert(tableInstance, Multiplicity.REQUIRED); return tableType.convert(tableInstance, Multiplicity.REQUIRED);
} }
private String random() { private String randomUTF() {
return RandomStringUtils.random(10); return RandomStringUtils.random(10);
} }
private String randomString() {
return RandomStringUtils.randomAlphanumeric(10);
}
@Test @Test
public void testUTFValues() throws Exception { public void testUTFValues() throws Exception {
Referenceable hrDept = new Referenceable("Department"); Referenceable hrDept = new Referenceable("Department");
Referenceable john = new Referenceable("Person"); Referenceable john = new Referenceable("Person");
john.set("name", random()); john.set("name", randomUTF());
john.set("department", hrDept); john.set("department", hrDept);
hrDept.set("name", random()); hrDept.set("name", randomUTF());
hrDept.set("employees", ImmutableList.of(john)); hrDept.set("employees", ImmutableList.of(john));
ClassType deptType = typeSystem.getDataType(ClassType.class, "Department"); ClassType deptType = typeSystem.getDataType(ClassType.class, "Department");
......
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