Repository: incubator-atlas
Updated Branches:
  refs/heads/master 19a5f65c9 -> 6ccba52c2


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6ccba52c/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
index 0ff33ba..c902f81 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java
@@ -17,7 +17,7 @@
  */
 package org.apache.atlas.repository.store.graph.v1;
 
-import org.apache.atlas.AtlasClient;
+import com.google.common.collect.ImmutableSet;
 import org.apache.atlas.AtlasException;
 import org.apache.atlas.RepositoryMetadataModule;
 import org.apache.atlas.TestUtils;
@@ -25,13 +25,13 @@ import org.apache.atlas.TestUtilsV2;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.model.instance.AtlasStruct;
 import org.apache.atlas.model.instance.EntityMutationResponse;
 import org.apache.atlas.model.instance.EntityMutations;
-import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.model.typedef.AtlasEntityDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
 import org.apache.atlas.repository.graph.AtlasGraphProvider;
-import org.apache.atlas.repository.graph.DeleteHandler;
 import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
 import org.apache.atlas.repository.store.graph.EntityGraphDiscovery;
@@ -39,24 +39,23 @@ import 
org.apache.atlas.repository.store.graph.EntityResolver;
 import org.apache.atlas.services.MetadataService;
 import org.apache.atlas.store.AtlasTypeDefStore;
 import org.apache.atlas.type.AtlasArrayType;
-import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasMapType;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.type.AtlasTypeUtil;
 import org.apache.atlas.typesystem.IInstance;
 import org.apache.atlas.typesystem.ITypedReferenceableInstance;
-import org.apache.atlas.typesystem.ITypedStruct;
-import org.apache.atlas.typesystem.Struct;
 import org.apache.atlas.typesystem.persistence.Id;
 import org.apache.atlas.typesystem.persistence.ReferenceableInstance;
 import org.apache.atlas.typesystem.persistence.StructInstance;
+import org.apache.atlas.typesystem.types.EnumValue;
 import org.apache.atlas.util.AtlasRepositoryConfiguration;
+import org.apache.commons.lang.RandomStringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
-import org.testng.annotations.AfterTest;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Guice;
@@ -64,11 +63,14 @@ import org.testng.annotations.Test;
 
 import javax.inject.Inject;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import static org.apache.atlas.TestUtils.randomString;
+import static org.testng.Assert.assertEquals;
+
 @Guice(modules = RepositoryMetadataModule.class)
 public class AtlasEntityStoreV1Test {
 
@@ -85,15 +87,22 @@ public class AtlasEntityStoreV1Test {
     @Inject
     MetadataService metadataService;
     
-    private AtlasEntity entityCreated;
+    private AtlasEntity deptEntity;
+    private AtlasEntity dbEntity;
+    private AtlasEntity tableEntity;
 
     @BeforeClass
     public void setUp() throws Exception {
         new GraphBackedSearchIndexer(typeRegistry);
-        final AtlasTypesDef atlasTypesDef = 
TestUtilsV2.defineDeptEmployeeTypes();
-        typeDefStore.createTypesDef(atlasTypesDef);
+        final AtlasTypesDef deptTypesDef = 
TestUtilsV2.defineDeptEmployeeTypes();
+        typeDefStore.createTypesDef(deptTypesDef);
+
+        final AtlasTypesDef hiveTypesDef = TestUtilsV2.defineHiveTypes();
+        typeDefStore.createTypesDef(hiveTypesDef);
         
-        entityCreated = TestUtilsV2.createDeptEg1();
+        deptEntity = TestUtilsV2.createDeptEg1();
+        dbEntity = TestUtilsV2.createDBEntity();
+        tableEntity = TestUtilsV2.createTableEntity(dbEntity.getGuid());
     }
 
     @AfterClass
@@ -121,17 +130,363 @@ public class AtlasEntityStoreV1Test {
 
     @Test
     public void testCreate() throws Exception {
-        EntityMutationResponse response = 
entityStore.createOrUpdate(entityCreated);
-        List<AtlasEntityHeader> entitiesCreated = 
response.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
-        Assert.assertNotNull(entitiesCreated);
-        Assert.assertEquals(entitiesCreated.size(), 5);
+        EntityMutationResponse response = 
entityStore.createOrUpdate(deptEntity);
+
+        validateMutationResponse(response, 
EntityMutations.EntityOperation.CREATE, 5);
+        AtlasEntityHeader deptEntity = response.getFirstEntityCreated();
+
+        validateAttributes(deptEntity);
+
+        //Create DB
+        EntityMutationResponse dbCreationResponse = 
entityStore.createOrUpdate(dbEntity);
+        validateMutationResponse(dbCreationResponse, 
EntityMutations.EntityOperation.CREATE, 1);
+
+        AtlasEntityHeader dbEntity = 
dbCreationResponse.getFirstEntityCreated();
+        validateAttributes(dbEntity);
+
+        //Create Table
+        //Update DB guid
+        AtlasObjectId dbId = (AtlasObjectId) 
tableEntity.getAttribute("database");
+        dbId.setGuid(dbEntity.getGuid());
+        tableEntity.setAttribute("database", dbId);
+
+        EntityMutationResponse tableCreationResponse = 
entityStore.createOrUpdate(tableEntity);
+        validateMutationResponse(tableCreationResponse, 
EntityMutations.EntityOperation.CREATE, 1);
+
+        AtlasEntityHeader tableEntity = 
tableCreationResponse.getFirstEntityCreated();
+        validateAttributes(tableEntity);
+
+    }
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testArrayOfEntityUpdate() throws Exception {
+        //clear state
+        init();
+
+        AtlasEntity entityClone = new AtlasEntity(deptEntity);
+
+        List<AtlasEntity> employees = (List<AtlasEntity>) 
entityClone.getAttribute("employees");
+
+        AtlasEntity entityRemoved = clearSubOrdinates(employees, 1);
+        entityClone.setAttribute("employees", employees);
+        EntityMutationResponse response = 
entityStore.createOrUpdate(entityClone);
+        
+        validateMutationResponse(response, 
EntityMutations.EntityOperation.UPDATE, 5);
+        AtlasEntityHeader deptEntity = response.getFirstEntityUpdated();
+        validateAttributes(deptEntity);
+
+
+        init();
+        //add  entity back
+        addSubordinate(employees.get(1), entityRemoved);
+        response = entityStore.createOrUpdate(entityClone);
+        validateMutationResponse(response, 
EntityMutations.EntityOperation.UPDATE, 5);
+        deptEntity = response.getFirstEntityUpdated();
+        validateAttributes(deptEntity);
+
+        //test array of class with id
+        final List<AtlasEntity> columns = new ArrayList<>();
+        Map<String, Object> values = new HashMap<>();
+        values.put(TestUtilsV2.NAME, "col1");
+        values.put("type", "type");
+        AtlasEntity col1 = new AtlasEntity(TestUtilsV2.COLUMN_TYPE, values);
+        columns.add(col1);
+        AtlasEntity tableUpdated = new AtlasEntity(tableEntity);
+        tableUpdated.setAttribute(TestUtilsV2.COLUMNS_ATTR_NAME, columns);
+
+        init();
+        entityStore.createOrUpdate(col1);
+
+        init();
+        response = entityStore.createOrUpdate(tableUpdated);
+        final AtlasEntityHeader updateTable = response.getFirstEntityUpdated();
+        validateAttributes(updateTable);
+
+    }
+    
+    @Test(dependsOnMethods = "testCreate")
+    public void testUpdateEntityWithMap() throws Exception {
+
+        AtlasEntity tableClone = new AtlasEntity(tableEntity);
+        final Map<String, AtlasStruct> partsMap = new HashMap<>();
+        partsMap.put("part0", new AtlasStruct(TestUtils.PARTITION_STRUCT_TYPE,
+            new HashMap<String, Object>() {{
+                put(TestUtilsV2.NAME, "test");
+            }}));
+
+        
+        tableClone.setAttribute("partitionsMap", partsMap);
+
+        init();
+        EntityMutationResponse response = 
entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition1 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition1);
+                
+        Assert.assertTrue(partsMap.get("part0").equals(((Map<String, 
AtlasStruct>) tableDefinition1.getAttribute("partitionsMap")).get("part0")));
+
+        //update map - add a map key
+        partsMap.put("part1", new AtlasStruct(TestUtils.PARTITION_STRUCT_TYPE,
+            new HashMap<String, Object>() {{
+                put(TestUtilsV2.NAME, "test1");
+            }}));
+        tableClone.setAttribute("partitionsMap", partsMap);
+
+        init();
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition2 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition2);
+
+        assertEquals(((Map<String, AtlasStruct>) 
tableDefinition2.getAttribute("partitionsMap")).size(), 2);
+        Assert.assertTrue(partsMap.get("part1").equals(((Map<String, 
AtlasStruct>) tableDefinition2.getAttribute("partitionsMap")).get("part1")));
+
+        //update map - remove a key and add another key
+        partsMap.remove("part0");
+        partsMap.put("part2", new AtlasStruct(TestUtils.PARTITION_STRUCT_TYPE,
+            new HashMap<String, Object>() {{
+                put(TestUtilsV2.NAME, "test2");
+            }}));
+        tableClone.setAttribute("partitionsMap", partsMap);
+
+        init();
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition3 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition3);
+
+        assertEquals(((Map<String, AtlasStruct>) 
tableDefinition3.getAttribute("partitionsMap")).size(), 2);
+        Assert.assertNull(((Map<String, AtlasStruct>) 
tableDefinition3.getAttribute("partitionsMap")).get("part0"));
+        Assert.assertTrue(partsMap.get("part2").equals(((Map<String, 
AtlasStruct>) tableDefinition3.getAttribute("partitionsMap")).get("part2")));
+
+        //update struct value for existing map key
+        init();
+        AtlasStruct partition2 = partsMap.get("part2");
+        partition2.setAttribute(TestUtilsV2.NAME, "test2Updated");
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition4 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition4);
+
+        assertEquals(((Map<String, AtlasStruct>) 
tableDefinition4.getAttribute("partitionsMap")).size(), 2);
+        Assert.assertNull(((Map<String, AtlasStruct>) 
tableDefinition4.getAttribute("partitionsMap")).get("part0"));
+
+        assertEquals(((Map<String, AtlasStruct>) 
tableDefinition4.getAttribute("partitionsMap")).size(), 2);
+        Assert.assertNull(((Map<String, AtlasStruct>) 
tableDefinition4.getAttribute("partitionsMap")).get("part0"));
+        Assert.assertTrue(partsMap.get("part2").equals(((Map<String, 
AtlasStruct>) tableDefinition4.getAttribute("partitionsMap")).get("part2")));
+
+        //Test map pointing to a class
+
+        final Map<String, AtlasEntity> columnsMap = new HashMap<>();
+        AtlasEntity col0Type = new AtlasEntity(TestUtilsV2.COLUMN_TYPE,
+            new HashMap<String, Object>() {{
+                put(TestUtilsV2.NAME, "test1");
+                put("type", "string");
+            }});
+
+
+        init();
+        entityStore.createOrUpdate(col0Type);
+
+        AtlasEntity col1Type = new AtlasEntity(TestUtils.COLUMN_TYPE,
+            new HashMap<String, Object>() {{
+                put(TestUtilsV2.NAME, "test2");
+                put("type", "string");
+            }});
+
+        init();
+        entityStore.createOrUpdate(col1Type);
+
+        columnsMap.put("col0", col0Type);
+        columnsMap.put("col1", col1Type);
+        tableClone.setAttribute(TestUtils.COLUMNS_MAP, columnsMap);
+
+        init();
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition5 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition5);
+
+        //Swap elements
+        columnsMap.clear();
+        columnsMap.put("col0", col1Type);
+        columnsMap.put("col1", col0Type);
+
+        tableClone.setAttribute(TestUtils.COLUMNS_MAP, columnsMap);
+        init();
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition6 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition6);
+
+        //Drop the first key and change the class type as well to col0
+        columnsMap.clear();
+        columnsMap.put("col0", col0Type);
+
+        init();
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition7 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition7);
+
+        //Clear state
+        tableClone.setAttribute(TestUtils.COLUMNS_MAP, null);
+        init();
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition8 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition8);
+    }
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testMapOfPrimitivesUpdate() throws Exception {
+        //clear state
+        init();
+
+        AtlasEntity entityClone = new AtlasEntity(tableEntity);
+
+        //Add a new entry
+        Map<String, String> paramsMap = (Map<String, String>) 
entityClone.getAttribute("parametersMap");
+        paramsMap.put("newParam", "value");
+        entityClone.setAttribute("parametersMap", paramsMap);
+
+        EntityMutationResponse response = 
entityStore.createOrUpdate(entityClone);
+        validateMutationResponse(response, 
EntityMutations.EntityOperation.UPDATE, 1);
+        AtlasEntityHeader tableEntity = response.getFirstEntityUpdated();
+        validateAttributes(tableEntity);
+
+        //clear state
+        init();
+
+        //Remove an entry
+        paramsMap.remove("key1");
+        entityClone.setAttribute("parametersMap", paramsMap);
+
+        response = entityStore.createOrUpdate(entityClone);
+        validateMutationResponse(response, 
EntityMutations.EntityOperation.UPDATE, 1);
+        tableEntity = response.getFirstEntityUpdated();
+        validateAttributes(tableEntity);
+    }
+
+    @Test(dependsOnMethods = "testCreate")
+    public void testArrayOfStructs() throws Exception {
+        //Modify array of structs
+//        TestUtils.dumpGraph(TestUtils.getGraph());
+        init();
+        final AtlasStruct partition1 = new 
AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE);
+        partition1.setAttribute(TestUtilsV2.NAME, "part1");
+        final AtlasStruct partition2 = new 
AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE);
+        partition2.setAttribute(TestUtilsV2.NAME, "part2");
+
+        List<AtlasStruct> partitions = new ArrayList<AtlasStruct>(){{ 
add(partition1); add(partition2); }};
+        tableEntity.setAttribute("partitions", partitions);
+
+        EntityMutationResponse response = 
entityStore.createOrUpdate(tableEntity);
+        AtlasEntityHeader tableDefinition = response.getFirstEntityUpdated();
+
+        validateAttributes(tableDefinition);
 
-        AtlasEntityHeader deptEntity = entitiesCreated.get(0);
+        //add a new element to array of struct
+        init();
+        final AtlasStruct partition3 = new 
AtlasStruct(TestUtils.PARTITION_STRUCT_TYPE);
+        partition3.setAttribute(TestUtilsV2.NAME, "part3");
+        partitions.add(partition3);
+        tableEntity.setAttribute("partitions", partitions);
+        response = entityStore.createOrUpdate(tableEntity);
+        tableDefinition = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition);
+
+        //remove one of the struct values
+        init();
+        partitions.remove(1);
+        tableEntity.setAttribute("partitions", partitions);
+        response = entityStore.createOrUpdate(tableEntity);
+        tableDefinition = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition);
+
+        //Update struct value within array of struct
+        init();
+        partitions.get(0).setAttribute(TestUtilsV2.NAME, "part4");
+        tableEntity.setAttribute("partitions", partitions);
+        response = entityStore.createOrUpdate(tableEntity);
+        tableDefinition = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition);
+
+
+        //add a repeated element to array of struct
+        init();
+        final AtlasStruct partition4 = new 
AtlasStruct(TestUtils.PARTITION_STRUCT_TYPE);
+        partition4.setAttribute(TestUtilsV2.NAME, "part4");
+        partitions.add(partition4);
+        tableEntity.setAttribute("partitions", partitions);
+        response = entityStore.createOrUpdate(tableEntity);
+        tableDefinition = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition);
+
+        // Remove all elements. Should set array attribute to null
+        init();
+        partitions.clear();
+        tableEntity.setAttribute("partitions", partitions);
+        response = entityStore.createOrUpdate(tableEntity);
+        tableDefinition = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition);
+    }
 
-        //TODO : Use the older API for get until new instance API is ready.
-        ITypedReferenceableInstance instance = 
metadataService.getEntityDefinition(deptEntity.getGuid());
-        assertAttributes(deptEntity, instance);
 
+    @Test(dependsOnMethods = "testCreate")
+    public void testStructs() throws Exception {
+        init();
+
+        AtlasEntity tableClone = new AtlasEntity(tableEntity);
+        AtlasStruct serdeInstance = new AtlasStruct(TestUtils.SERDE_TYPE);
+        serdeInstance.setAttribute(TestUtilsV2.NAME, "serde1Name");
+        serdeInstance.setAttribute("serde", "test");
+        serdeInstance.setAttribute("description", "testDesc");
+        tableClone.setAttribute("serde1", serdeInstance);
+        tableClone.setAttribute("database", dbEntity);
+
+        EntityMutationResponse response = 
entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition1 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition1);
+
+        //update struct attribute
+        init();
+        serdeInstance.setAttribute("serde", "testUpdated");
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition2 = response.getFirstEntityUpdated();
+        validateAttributes(tableDefinition2);
+
+        //set to null
+        init();
+        tableClone.setAttribute("description", null);
+        response = entityStore.createOrUpdate(tableClone);
+        AtlasEntityHeader tableDefinition3 = response.getFirstEntityUpdated();
+        Assert.assertNull(tableDefinition3.getAttribute("description"));
+        validateAttributes(tableDefinition3);
+    }
+
+    private AtlasEntity clearSubOrdinates(List<AtlasEntity> employees, int 
index) {
+
+        AtlasEntity ret = null;
+        List<AtlasEntity> subOrdinates = (List<AtlasEntity>) 
employees.get(index).getAttribute("subordinates");
+        List<AtlasEntity> subOrdClone = new ArrayList<>(subOrdinates);
+        ret = subOrdClone.remove(index);
+
+        employees.get(index).setAttribute("subordinates", subOrdClone);
+        return ret;
+    }
+
+    private int addSubordinate(AtlasEntity manager, AtlasEntity employee) {
+        List<AtlasEntity> subOrdinates = (List<AtlasEntity>) 
manager.getAttribute("subordinates");
+        subOrdinates.add(employee);
+
+        manager.setAttribute("subordinates", subOrdinates);
+
+        return subOrdinates.size() - 1;
+    }
+
+    private void validateMutationResponse(EntityMutationResponse response, 
EntityMutations.EntityOperation op, int expectedNumCreated) {
+        List<AtlasEntityHeader> entitiesCreated = 
response.getEntitiesByOperation(op);
+        Assert.assertNotNull(entitiesCreated);
+        Assert.assertEquals(entitiesCreated.size(), expectedNumCreated);
+    }
+
+    private void validateAttributes(AtlasEntityHeader entity) throws 
AtlasBaseException, AtlasException {
+        //TODO : Use the older API for get until new instance API is ready and 
validated
+        ITypedReferenceableInstance instance = 
metadataService.getEntityDefinition(entity.getGuid());
+        assertAttributes(entity, instance);
     }
 
     private void assertAttributes(AtlasStruct entity, IInstance instance) 
throws AtlasBaseException, AtlasException {
@@ -151,19 +506,26 @@ public class AtlasEntityStoreV1Test {
 
         switch(attributeType.getTypeCategory()) {
         case ENTITY:
-            if ( expected instanceof  Id) {
+            if ( expected instanceof Id) {
                 String guid = ((Id) expected)._getId();
                 Assert.assertTrue(AtlasEntity.isAssigned(guid));
             } else {
                 ReferenceableInstance expectedInstance = 
(ReferenceableInstance) expected;
                 AtlasEntity actualInstance = (AtlasEntity) actual;
-                assertAttributes(actualInstance, expectedInstance);
+                if ( actualInstance != null) {
+                    assertAttributes(actualInstance, expectedInstance);
+                }
             }
             break;
         case PRIMITIVE:
-        case ENUM:
             Assert.assertEquals(actual, expected);
             break;
+        case ENUM:
+            EnumValue expectedEnumVal = (EnumValue) expected;
+            if ( actual != null) {
+                Assert.assertEquals(actual, expectedEnumVal.value);
+            }
+            break;
         case MAP:
             AtlasMapType mapType = (AtlasMapType) attributeType;
             AtlasType keyType = mapType.getKeyType();
@@ -171,9 +533,11 @@ public class AtlasEntityStoreV1Test {
             Map actualMap = (Map) actual;
             Map expectedMap = (Map) expected;
 
-            Assert.assertEquals(actualMap.size(), expectedMap.size());
-            for (Object key : actualMap.keySet()) {
-                assertAttribute(actualMap.get(key), expectedMap.get(key), 
valueType, attrName);
+            if (expectedMap != null && actualMap != null) {
+                Assert.assertEquals(actualMap.size(), expectedMap.size());
+                for (Object key : actualMap.keySet()) {
+                    assertAttribute(actualMap.get(key), expectedMap.get(key), 
valueType, attrName);
+                }
             }
             break;
         case ARRAY:
@@ -200,37 +564,120 @@ public class AtlasEntityStoreV1Test {
     }
 
     @Test(dependsOnMethods = "testCreate")
-    public void testArrayUpdate() throws Exception {
-        //clear state
+    public void testClassUpdate() throws Exception {
+
         init();
+        //Create new db instance
+        final AtlasEntity databaseInstance = TestUtilsV2.createDBEntity();
 
-        AtlasEntity entityClone = new AtlasEntity(entityCreated);
+        EntityMutationResponse response = 
entityStore.createOrUpdate(databaseInstance);
+        final AtlasEntityHeader dbCreated = response.getFirstEntityCreated();
 
-        List<AtlasEntity> employees = (List<AtlasEntity>) 
entityClone.getAttribute("employees");
+        init();
+        AtlasEntity tableClone = new AtlasEntity(tableEntity);
+        tableClone.setAttribute("database", new 
AtlasObjectId(TestUtils.DATABASE_TYPE, dbCreated.getGuid()));
+        response = entityStore.createOrUpdate(tableClone);
+        final AtlasEntityHeader tableDefinition = 
response.getFirstEntityUpdated();
 
-        List<AtlasEntity> updatedEmployees = new ArrayList<>(employees);
-        clearSubOrdinates(updatedEmployees, 1);
-        entityClone.setAttribute("employees", updatedEmployees);
+        Assert.assertNotNull(tableDefinition.getAttribute("database"));
+        Assert.assertEquals(((AtlasObjectId) 
tableDefinition.getAttribute("database")).getGuid(), dbCreated.getGuid());
+    }
 
-        EntityMutationResponse response = 
entityStore.createOrUpdate(entityClone);
-        
-        List<AtlasEntityHeader> entitiesUpdated = 
response.getEntitiesByOperation(EntityMutations.EntityOperation.UPDATE);
-        Assert.assertNotNull(entitiesUpdated);
-        Assert.assertEquals(entitiesUpdated.size(), 5);
+    @Test
+    public void testCheckOptionalAttrValueRetention() throws Exception {
 
-        AtlasEntityHeader deptEntity = entitiesUpdated.get(0);
+        AtlasEntity dbEntity = TestUtilsV2.createDBEntity();
+        EntityMutationResponse response = entityStore.createOrUpdate(dbEntity);
+        AtlasEntityHeader firstEntityCreated = 
response.getFirstEntityCreated();
 
-        //TODO : Change to new API after new instance GET API is ready.
-        ITypedReferenceableInstance instance = 
metadataService.getEntityDefinition(deptEntity.getGuid());
-        assertAttributes(deptEntity, instance);
+        //The optional boolean attribute should have a non-null value
+        final String isReplicatedAttr = "isReplicated";
+        final String paramsAttr = "parameters";
+        
Assert.assertNotNull(firstEntityCreated.getAttribute(isReplicatedAttr));
+        Assert.assertEquals(firstEntityCreated.getAttribute(isReplicatedAttr), 
Boolean.FALSE);
+        Assert.assertNull(firstEntityCreated.getAttribute(paramsAttr));
 
+        //Update to true
+        init();
+        dbEntity.setAttribute(isReplicatedAttr, Boolean.TRUE);
+        //Update array
+        final HashMap<String, String> params = new HashMap<String, String>() 
{{ put("param1", "val1"); put("param2", "val2"); }};
+        dbEntity.setAttribute(paramsAttr, params);
+        //Complete update
+        response = entityStore.createOrUpdate(dbEntity);
+        AtlasEntityHeader firstEntityUpdated = 
response.getFirstEntityUpdated();
+
+        
Assert.assertNotNull(firstEntityUpdated.getAttribute(isReplicatedAttr));
+        Assert.assertEquals(firstEntityUpdated.getAttribute(isReplicatedAttr), 
Boolean.TRUE);
+        Assert.assertEquals(firstEntityUpdated.getAttribute(paramsAttr), 
params);
+
+        //TODO - enable test after GET API is ready
+//        init();
+//        //Complete update without setting the attribute
+//        AtlasEntity newEntity = TestUtilsV2.createDBEntity();
+//        //Reset name to the current DB name
+//        newEntity.setAttribute(AtlasClient.NAME, 
firstEntityCreated.getAttribute(AtlasClient.NAME));
+//        response = entityStore.createOrUpdate(newEntity);
+//
+//        firstEntityUpdated = response.getFirstEntityUpdated();
+//        
Assert.assertNotNull(firstEntityUpdated.getAttribute(isReplicatedAttr));
+//        
Assert.assertEquals(firstEntityUpdated.getAttribute(isReplicatedAttr), 
Boolean.TRUE);
+//        Assert.assertEquals(firstEntityUpdated.getAttribute(paramsAttr), 
params);
     }
 
-    private void clearSubOrdinates(List<AtlasEntity> updatedEmployees, int 
index) {
-        List<AtlasEntity> subOrdinates = (List<AtlasEntity>) 
updatedEmployees.get(index).getAttribute("subordinates");
-        List<AtlasEntity> subOrdClone = new ArrayList<>(subOrdinates);
-        subOrdClone.remove(index);
+    @Test(enabled = false)
+    //Titan doesn't allow some reserved chars in property keys. Verify that 
atlas encodes these
+    //See GraphHelper.encodePropertyKey()
+    //TODO : Failing in typedef creation
+    public void testSpecialCharacters() throws Exception {
+        //Verify that type can be created with reserved characters in 
typename, attribute name
+        final String typeName = "test_type_"+ 
RandomStringUtils.randomAlphanumeric(10);
+        String strAttrName = randomStrWithReservedChars();
+        String arrayAttrName = randomStrWithReservedChars();
+        String mapAttrName = randomStrWithReservedChars();
+
+        AtlasEntityDef typeDefinition =
+            AtlasTypeUtil.createClassTypeDef(typeName, "Special chars test 
type", ImmutableSet.<String>of(),
+                AtlasTypeUtil.createOptionalAttrDef(strAttrName, "string"),
+                AtlasTypeUtil.createOptionalAttrDef(arrayAttrName, 
"array<string>"),
+                AtlasTypeUtil.createOptionalAttrDef(mapAttrName, 
"map<string,string>"));
+
+        typeDefStore.createEntityDef(typeDefinition);
+
+        //verify that entity can be created with reserved characters in string 
value, array value and map key and value
+        AtlasEntity entity = new AtlasEntity();
+        entity.setAttribute(strAttrName, randomStrWithReservedChars());
+        entity.setAttribute(arrayAttrName, new 
String[]{randomStrWithReservedChars()});
+        entity.setAttribute(mapAttrName, new HashMap<String, String>() {{
+            put(randomStrWithReservedChars(), randomStrWithReservedChars());
+        }});
+
+        final EntityMutationResponse response = 
entityStore.createOrUpdate(entity);
+        final AtlasEntityHeader firstEntityCreated = 
response.getFirstEntityCreated();
+        validateAttributes(firstEntityCreated);
+
+
+        //Verify that search with reserved characters works - for string 
attribute
+//        String query =
+//            String.format("`%s` where `%s` = '%s'", typeName, strAttrName, 
entity.getAttribute(strAttrName));
+//        String responseJson = discoveryService.searchByDSL(query, new 
QueryParams(1, 0));
+//        JSONObject response = new JSONObject(responseJson);
+//        assertEquals(response.getJSONArray("rows").length(), 1);
+    }
+
+    private String randomStrWithReservedChars() {
+        return randomString() + "\"${}%";
+    }
+
+    @Test(expectedExceptions = AtlasBaseException.class)
+    public void testCreateRequiredAttrNull() throws Exception {
+        //Update required attribute
 
-        updatedEmployees.get(index).setAttribute("subordinates", subOrdClone);
+        AtlasEntity tableEntity = new AtlasEntity(TestUtilsV2.TABLE_TYPE);
+        tableEntity.setAttribute(TestUtilsV2.NAME, "table_" + 
TestUtils.randomString());
+
+        entityStore.createOrUpdate(tableEntity);
+        Assert.fail("Expected exception while creating with required attribute 
null");
     }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6ccba52c/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
----------------------------------------------------------------------
diff --git 
a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
 
b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
index 74ab740..75a7183 100644
--- 
a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
+++ 
b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasEntityFormatConverter.java
@@ -145,8 +145,8 @@ public class AtlasEntityFormatConverter extends 
AtlasStructFormatConverter {
 
                 ret = new Referenceable(entity.getGuid(), entity.getTypeName(),
                                         fromV2ToV1(entityType, 
entity.getAttributes()));
-            } else if (v2Obj instanceof String) { // transient-id
-                ret = new Referenceable((String) v2Obj, type.getTypeName(), 
null);
+            } else if (v2Obj instanceof AtlasObjectId) { // transient-id
+                ret = new Referenceable(((AtlasObjectId) v2Obj).getGuid(), 
type.getTypeName(), null);
             } else {
                 throw new AtlasBaseException(AtlasErrorCode.UNEXPECTED_TYPE, 
"Map or AtlasEntity or String",
                                              
v2Obj.getClass().getCanonicalName());

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6ccba52c/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
----------------------------------------------------------------------
diff --git 
a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
 
b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
index 2b13552..7368c72 100644
--- 
a/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
+++ 
b/webapp/src/main/java/org/apache/atlas/web/adapters/AtlasInstanceRestAdapters.java
@@ -31,6 +31,8 @@ import 
org.apache.atlas.model.instance.AtlasEntityWithAssociations;
 import org.apache.atlas.model.instance.EntityMutationResponse;
 import org.apache.atlas.model.instance.EntityMutations;
 import org.apache.atlas.services.MetadataService;
+import org.apache.atlas.type.AtlasClassificationType;
+import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.typesystem.IReferenceableInstance;
@@ -106,7 +108,10 @@ public class AtlasInstanceRestAdapters {
 
     public AtlasClassification getClassification(IStruct classification) 
throws AtlasBaseException {
         AtlasFormatConverter converter          = 
instanceFormatters.getConverter(TypeCategory.CLASSIFICATION);
-        AtlasType            classificationType = 
typeRegistry.getType(classification.getTypeName());
+        AtlasClassificationType classificationType = 
typeRegistry.getClassificationTypeByName(classification.getTypeName());
+        if (classificationType == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, 
TypeCategory.CLASSIFICATION.name(), classification.getTypeName());
+        }
         AtlasClassification  ret                = 
(AtlasClassification)converter.fromV1ToV2(classification, classificationType);
 
         return ret;
@@ -114,7 +119,11 @@ public class AtlasInstanceRestAdapters {
 
     public AtlasEntityWithAssociations getAtlasEntity(IReferenceableInstance 
referenceable) throws AtlasBaseException {
         AtlasFormatConverter converter  = 
instanceFormatters.getConverter(TypeCategory.ENTITY);
-        AtlasType            entityType = 
typeRegistry.getType(referenceable.getTypeName());
+        AtlasEntityType entityType = 
typeRegistry.getEntityTypeByName(referenceable.getTypeName());
+        if (entityType == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, 
TypeCategory.ENTITY.name(), referenceable.getTypeName());
+        }
+
         AtlasEntityWithAssociations ret = 
(AtlasEntityWithAssociations)converter.fromV1ToV2(referenceable, entityType);
 
         return ret;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6ccba52c/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
----------------------------------------------------------------------
diff --git 
a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java 
b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
index c55234c..47e1fa3 100644
--- a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
+++ b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
@@ -190,12 +190,12 @@ public class TestEntitiesREST {
 
         if ( retrievedDBEntity != null) {
             LOG.info("verifying entity of type {} ", dbEntity.getTypeName());
-            verifyAttributes(dbEntity.getAttributes(), 
retrievedDBEntity.getAttributes());
+            verifyAttributes(retrievedDBEntity.getAttributes(), 
dbEntity.getAttributes());
         }
 
         if ( retrievedColumnEntity != null) {
             LOG.info("verifying entity of type {} ", 
columns.get(0).getTypeName());
-            verifyAttributes(columns.get(0).getAttributes(), 
retrievedColumnEntity.getAttributes());
+            verifyAttributes(retrievedColumnEntity.getAttributes(), 
columns.get(0).getAttributes());
         }
 
         if ( retrievedTableEntity != null) {
@@ -216,10 +216,13 @@ public class TestEntitiesREST {
         }
     }
 
-    public static void verifyAttributes(Map<String, Object> sourceAttrs, 
Map<String, Object> targetAttributes) throws Exception {
-        for (String name : sourceAttrs.keySet() ) {
+    public static void verifyAttributes(Map<String, Object> actual, 
Map<String, Object> expected) throws Exception {
+        for (String name : actual.keySet() ) {
             LOG.info("verifying attribute {} ", name);
-            Assert.assertEquals(targetAttributes.get(name), 
sourceAttrs.get(name));
+
+            if ( expected.get(name) != null) {
+                Assert.assertEquals(actual.get(name), expected.get(name));
+            }
         }
     }
 

Reply via email to