You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sh...@apache.org on 2015/12/08 07:40:08 UTC

[2/5] incubator-atlas git commit: ATLAS-47 Entity mutations for complex types (sumasai via shwethags)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
index b6e62aa..78af443 100755
--- a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
@@ -29,13 +29,13 @@ import org.apache.atlas.RepositoryMetadataModule;
 import org.apache.atlas.TestUtils;
 import org.apache.atlas.discovery.graph.GraphBackedDiscoveryService;
 import org.apache.atlas.repository.Constants;
-import org.apache.atlas.repository.EntityNotFoundException;
 import org.apache.atlas.repository.RepositoryException;
 import org.apache.atlas.typesystem.IStruct;
 import org.apache.atlas.typesystem.ITypedReferenceableInstance;
 import org.apache.atlas.typesystem.ITypedStruct;
 import org.apache.atlas.typesystem.Referenceable;
 import org.apache.atlas.typesystem.Struct;
+import org.apache.atlas.typesystem.exception.EntityNotFoundException;
 import org.apache.atlas.typesystem.persistence.Id;
 import org.apache.atlas.typesystem.types.ClassType;
 import org.apache.atlas.typesystem.types.DataTypes;
@@ -131,7 +131,7 @@ public class GraphBackedMetadataRepositoryTest {
         Assert.assertNotNull(entity);
     }
 
-    @Test(expectedExceptions = RepositoryException.class)
+    @Test(expectedExceptions = EntityNotFoundException.class)
     public void testGetEntityDefinitionNonExistent() throws Exception {
         repositoryService.getEntityDefinition("blah");
         Assert.fail();
@@ -342,13 +342,13 @@ public class GraphBackedMetadataRepositoryTest {
         }
 
         Id expected = new Id(guid, tableVertex.<Integer>getProperty(Constants.VERSION_PROPERTY_KEY), TestUtils.TABLE_TYPE);
-        Assert.assertEquals(repositoryService.getIdFromVertex(TestUtils.TABLE_TYPE, tableVertex), expected);
+        Assert.assertEquals(GraphHelper.getIdFromVertex(TestUtils.TABLE_TYPE, tableVertex), expected);
     }
 
     @Test(dependsOnMethods = "testCreateEntity")
     public void testGetTypeName() throws Exception {
         Vertex tableVertex = getTableEntityVertex();
-        Assert.assertEquals(repositoryService.getTypeName(tableVertex), TestUtils.TABLE_TYPE);
+        Assert.assertEquals(GraphHelper.getTypeName(tableVertex), TestUtils.TABLE_TYPE);
     }
 
     @Test(dependsOnMethods = "testCreateEntity")
@@ -415,6 +415,9 @@ public class GraphBackedMetadataRepositoryTest {
     public void testBug37860() throws Exception {
         String dslQuery = "hive_table as t where name = 'bar' "
             + "database where name = 'foo' and description = 'foo database' select t";
+
+        TestUtils.dumpGraph(graphProvider.get());
+
         System.out.println("Executing dslQuery = " + dslQuery);
         String jsonResults = discoveryService.searchByDSL(dslQuery);
         Assert.assertNotNull(jsonResults);
@@ -446,6 +449,8 @@ public class GraphBackedMetadataRepositoryTest {
         //but with elasticsearch, doesn't work without sleep. why??
         long sleepInterval = 1000;
 
+        TestUtils.dumpGraph(graphProvider.get());
+
         //person in hr department whose name is john
         Thread.sleep(sleepInterval);
         String response = discoveryService.searchByFullText("john");
@@ -475,31 +480,36 @@ public class GraphBackedMetadataRepositoryTest {
     @Test(dependsOnMethods = "testSubmitEntity")
     public void testUpdateEntity_MultiplicityOneNonCompositeReference() throws Exception {
         ITypedReferenceableInstance john = repositoryService.getEntityDefinition("Person", "name", "John");
-        String johnGuid = john.getId()._getId();
+        Id johnGuid = john.getId();
         ITypedReferenceableInstance max = repositoryService.getEntityDefinition("Person", "name", "Max");
         String maxGuid = max.getId()._getId();
         ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Person", "name", "Jane");
-        String janeGuid = jane.getId()._getId();
+        Id janeGuid = jane.getId();
         
         // Update max's mentor reference to john.
-        repositoryService.updateEntity(maxGuid, "mentor", johnGuid);
+        ClassType personType = typeSystem.getDataType(ClassType.class, "Person");
+        ITypedReferenceableInstance instance = personType.createInstance(max.getId());
+        instance.set("mentor", johnGuid);
+        repositoryService.updatePartial(instance);
         
         // Verify the update was applied correctly - john should now be max's mentor.
         max = repositoryService.getEntityDefinition(maxGuid);
         Object object = max.get("mentor");
         Assert.assertTrue(object instanceof ITypedReferenceableInstance);
         ITypedReferenceableInstance refTarget = (ITypedReferenceableInstance) object;
-        Assert.assertEquals(refTarget.getId()._getId(), johnGuid);
+        Assert.assertEquals(refTarget.getId()._getId(), johnGuid._getId());
 
         // Update max's mentor reference to jane.
-        repositoryService.updateEntity(maxGuid, "mentor", janeGuid);
-        
+        instance = personType.createInstance(max.getId());
+        instance.set("mentor", janeGuid);
+        repositoryService.updatePartial(instance);
+
         // Verify the update was applied correctly - jane should now be max's mentor.
         max = repositoryService.getEntityDefinition(maxGuid);
         object = max.get("mentor");
         Assert.assertTrue(object instanceof ITypedReferenceableInstance);
         refTarget = (ITypedReferenceableInstance) object;
-        Assert.assertEquals(refTarget.getId()._getId(), janeGuid);
+        Assert.assertEquals(refTarget.getId()._getId(), janeGuid._getId());
     }
 
     private ITypedReferenceableInstance createHiveTableInstance(Referenceable databaseInstance) throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/repository/src/test/java/org/apache/atlas/repository/graph/GraphRepoMapperScaleTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/graph/GraphRepoMapperScaleTest.java b/repository/src/test/java/org/apache/atlas/repository/graph/GraphRepoMapperScaleTest.java
index 11e8219..c25ccf8 100755
--- a/repository/src/test/java/org/apache/atlas/repository/graph/GraphRepoMapperScaleTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/graph/GraphRepoMapperScaleTest.java
@@ -18,15 +18,9 @@
 
 package org.apache.atlas.repository.graph;
 
-import com.google.inject.Inject;
-import com.thinkaurelius.titan.core.TitanFactory;
 import com.thinkaurelius.titan.core.TitanGraph;
 import com.thinkaurelius.titan.core.TitanIndexQuery;
 import com.thinkaurelius.titan.core.util.TitanCleanup;
-import com.thinkaurelius.titan.diskstorage.BackendException;
-import com.thinkaurelius.titan.diskstorage.configuration.ReadConfiguration;
-import com.thinkaurelius.titan.diskstorage.configuration.backend.CommonsConfiguration;
-import com.thinkaurelius.titan.graphdb.configuration.GraphDatabaseConfiguration;
 import com.tinkerpop.blueprints.Compare;
 import com.tinkerpop.blueprints.GraphQuery;
 import com.tinkerpop.blueprints.Predicate;
@@ -42,19 +36,16 @@ import org.apache.atlas.typesystem.types.ClassType;
 import org.apache.atlas.typesystem.types.IDataType;
 import org.apache.atlas.typesystem.types.Multiplicity;
 import org.apache.atlas.typesystem.types.TypeSystem;
-import org.apache.commons.io.FileUtils;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
-import java.io.File;
-import java.io.IOException;
+import javax.inject.Inject;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
-import java.util.Random;
 
 @Test
 @Guice(modules = RepositoryMetadataModule.class)
@@ -63,15 +54,13 @@ public class GraphRepoMapperScaleTest {
     private static final String DATABASE_NAME = "foo";
     private static final String TABLE_NAME = "bar";
 
-    private static final String INDEX_DIR =
-            System.getProperty("java.io.tmpdir", "/tmp") + "/atlas-test" + new Random().nextLong();
-
     @Inject
     GraphProvider<TitanGraph> graphProvider;
 
     @Inject
     private GraphBackedMetadataRepository repositoryService;
 
+    @Inject
     private GraphBackedSearchIndexer searchIndexer;
 
     private TypeSystem typeSystem = TypeSystem.getInstance();
@@ -81,7 +70,7 @@ public class GraphRepoMapperScaleTest {
     @BeforeClass
     @GraphTransaction
     public void setUp() throws Exception {
-        searchIndexer = new GraphBackedSearchIndexer(graphProvider);
+        //Make sure we can cleanup the index directory
         Collection<IDataType> typesAdded = TestUtils.createHiveTypes(typeSystem);
         searchIndexer.onAdd(typesAdded);
     }
@@ -127,7 +116,6 @@ public class GraphRepoMapperScaleTest {
 
         //Elasticsearch requires some time before index is updated
         Thread.sleep(5000);
-
         searchWithOutIndex(Constants.GUID_PROPERTY_KEY, dbGUID);
         searchWithOutIndex(Constants.ENTITY_TYPE_PROPERTY_KEY, "column_type");
         searchWithOutIndex(Constants.ENTITY_TYPE_PROPERTY_KEY, TestUtils.TABLE_TYPE);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java b/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java
index 9d32332..0352ef3 100644
--- a/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/service/DefaultMetadataServiceTest.java
@@ -18,29 +18,40 @@
 
 package org.apache.atlas.service;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 import com.thinkaurelius.titan.core.TitanGraph;
 import com.thinkaurelius.titan.core.util.TitanCleanup;
+import org.apache.atlas.typesystem.exception.TypeNotFoundException;
+import org.apache.atlas.typesystem.exception.EntityNotFoundException;
+import org.apache.atlas.utils.ParamChecker;
 import org.apache.atlas.RepositoryMetadataModule;
 import org.apache.atlas.TestUtils;
-import org.apache.atlas.TypeNotFoundException;
-import org.apache.atlas.repository.EntityNotFoundException;
 import org.apache.atlas.repository.graph.GraphProvider;
 import org.apache.atlas.services.MetadataService;
 import org.apache.atlas.typesystem.Referenceable;
+import org.apache.atlas.typesystem.Struct;
 import org.apache.atlas.typesystem.TypesDef;
 import org.apache.atlas.typesystem.json.InstanceSerialization;
 import org.apache.atlas.typesystem.json.TypesSerialization;
-import org.apache.atlas.typesystem.types.EnumType;
+import org.apache.atlas.typesystem.persistence.Id;
 import org.apache.atlas.typesystem.types.EnumValue;
+import org.apache.atlas.typesystem.types.TypeSystem;
+import org.apache.atlas.typesystem.types.ValueConversionException;
 import org.apache.commons.lang.RandomStringUtils;
 import org.codehaus.jettison.json.JSONArray;
 import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 @Guice(modules = RepositoryMetadataModule.class)
 public class DefaultMetadataServiceTest {
     @Inject
@@ -48,8 +59,16 @@ public class DefaultMetadataServiceTest {
     @Inject
     private GraphProvider<TitanGraph> graphProvider;
 
+    private Referenceable db = createDBEntity();
+
+    private Id dbId;
+
+    private Referenceable table;
+
+    private Id tableId;
+
 
-    @BeforeClass
+    @BeforeTest
     public void setUp() throws Exception {
         TypesDef typesDef = TestUtils.defineHiveTypes();
         try {
@@ -57,10 +76,21 @@ public class DefaultMetadataServiceTest {
         } catch (TypeNotFoundException e) {
             metadataService.createType(TypesSerialization.toJson(typesDef));
         }
+
+        String dbGUid = createInstance(db);
+        dbId = new Id(dbGUid, 0, TestUtils.DATABASE_TYPE);
+
+        table = createTableEntity(dbId);
+        String tableGuid = createInstance(table);
+        String tableDefinitionJson =
+                metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        table = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        tableId = new Id(tableGuid, 0, TestUtils.TABLE_TYPE);
     }
 
-    @AfterClass
-    public void shudown() {
+    @AfterTest
+    public void shutdown() {
+        TypeSystem.getInstance().reset();
         try {
             //TODO - Fix failure during shutdown while using BDB
             graphProvider.get().shutdown();
@@ -82,6 +112,16 @@ public class DefaultMetadataServiceTest {
         return new JSONArray(response).getString(0);
     }
 
+    private String updateInstance(Referenceable entity) throws Exception {
+        ParamChecker.notNull(entity, "Entity");
+        ParamChecker.notNull(entity.getId(), "Entity");
+        String entityjson = InstanceSerialization.toJson(entity, true);
+        JSONArray entitiesJson = new JSONArray();
+        entitiesJson.put(entityjson);
+        String response = metadataService.updateEntities(entitiesJson.toString());
+        return new JSONArray(response).getString(0);
+    }
+
     private Referenceable createDBEntity() {
         Referenceable entity = new Referenceable(TestUtils.DATABASE_TYPE);
         String dbName = RandomStringUtils.randomAlphanumeric(10);
@@ -90,6 +130,18 @@ public class DefaultMetadataServiceTest {
         return entity;
     }
 
+    private Referenceable createTableEntity(Id dbId) {
+        Referenceable entity = new Referenceable(TestUtils.TABLE_TYPE);
+        String tableName = RandomStringUtils.randomAlphanumeric(10);
+        entity.set("name", tableName);
+        entity.set("description", "random table");
+        entity.set("type", "type");
+        entity.set("tableType", "MANAGED");
+        entity.set("database", dbId);
+        entity.set("created", new Date());
+        return entity;
+    }
+
     @Test
     public void testCreateEntityWithUniqueAttribute() throws Exception {
         //name is the unique attribute
@@ -116,30 +168,447 @@ public class DefaultMetadataServiceTest {
         table.set("description", "random table");
         table.set("type", "type");
         table.set("tableType", "MANAGED");
-        table.set("database", db);
+        table.set("database", new Id(dbId, 0, TestUtils.DATABASE_TYPE));
+        table.set("databaseComposite", db);
         createInstance(table);
 
         //table create should re-use the db instance created earlier
         String tableDefinitionJson =
                 metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
         Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
-        Referenceable actualDb = (Referenceable) tableDefinition.get("database");
+        Referenceable actualDb = (Referenceable) tableDefinition.get("databaseComposite");
         Assert.assertEquals(actualDb.getId().id, dbId);
     }
 
     @Test
-    public void testCreateEntityWithEnum() throws Exception {
-        Referenceable dbEntity = createDBEntity();
-        String db = createInstance(dbEntity);
+    public void testUpdateEntityByUniqueAttribute() throws Exception {
+        final List<String> colNameList = ImmutableList.of("col1", "col2");
+        Referenceable tableUpdated = new Referenceable(TestUtils.TABLE_TYPE, new HashMap<String, Object>() {{
+            put("columnNames", colNameList);
+        }});
+        metadataService.updateEntityByUniqueAttribute(table.getTypeName(), "name", (String) table.get("name"), tableUpdated);
 
-        Referenceable table = new Referenceable(TestUtils.TABLE_TYPE);
-        table.set("name", TestUtils.randomString());
-        table.set("description", "random table");
-        table.set("type", "type");
-        table.set("tableType", "MANAGED");
-        table.set("database", dbEntity);
-        createInstance(table);
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        List<String> actualColumns = (List) tableDefinition.get("columnNames");
+        Assert.assertEquals(actualColumns, colNameList);
+    }
+
+    @Test
+    public void testUpdateEntityWithMap() throws Exception {
+
+        final Map<String, Struct> partsMap = new HashMap<>();
+        partsMap.put("part0", new Struct("partition_type",
+            new HashMap<String, Object>() {{
+                put("name", "test");
+            }}));
+
+        table.set("partitionsMap", partsMap);
+
+        updateInstance(table);
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertTrue(partsMap.get("part0").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part0")));
+
+        //update map - add a map key
+        partsMap.put("part1", new Struct("partition_type",
+            new HashMap<String, Object>() {{
+                put("name", "test1");
+            }}));
+        table.set("partitionsMap", partsMap);
 
+        updateInstance(table);
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2);
+        Assert.assertTrue(partsMap.get("part1").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part1")));
+
+        //update map - remove a key and add another key
+        partsMap.remove("part0");
+        partsMap.put("part2", new Struct("partition_type",
+            new HashMap<String, Object>() {{
+                put("name", "test2");
+            }}));
+        table.set("partitionsMap", partsMap);
+
+        updateInstance(table);
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2);
+        Assert.assertNull(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part0"));
+        Assert.assertTrue(partsMap.get("part2").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part2")));
+
+
+        //update struct value for existing map key
+        Struct partition2 = (Struct)partsMap.get("part2");
+        partition2.set("name", "test2Updated");
+        updateInstance(table);
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertEquals(((Map<String, Struct>)tableDefinition.get("partitionsMap")).size(), 2);
+        Assert.assertNull(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part0"));
+        Assert.assertTrue(partsMap.get("part2").equalsContents(((Map<String, Struct>)tableDefinition.get("partitionsMap")).get("part2")));
+    }
+
+    @Test
+    public void testUpdateEntityAddAndUpdateArrayAttr() throws Exception {
+        //Update entity, add new array attribute
+        //add array of primitives
+        final List<String> colNameList = ImmutableList.of("col1", "col2");
+        Referenceable tableUpdated = new Referenceable(TestUtils.TABLE_TYPE, new HashMap<String, Object>() {{
+            put("columnNames", colNameList);
+        }});
+        metadataService.updateEntityPartialByGuid(tableId._getId(), tableUpdated);
+
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        List<String> actualColumns = (List) tableDefinition.get("columnNames");
+        Assert.assertEquals(actualColumns, colNameList);
+
+        //update array of primitives
+        final List<String> updatedColNameList = ImmutableList.of("col2", "col3");
+        tableUpdated = new Referenceable(TestUtils.TABLE_TYPE, new HashMap<String, Object>() {{
+            put("columnNames", updatedColNameList);
+        }});
+        metadataService.updateEntityPartialByGuid(tableId.getId()._getId(), tableUpdated);
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        actualColumns = (List) tableDefinition.get("columnNames");
+        Assert.assertEquals(actualColumns, updatedColNameList);
+    }
+
+    @Test
+    public void testUpdateEntityArrayOfClass() throws Exception {
+        //test array of class with id
+        final List<Referenceable> columns = new ArrayList<>();
+        Map<String, Object> values = new HashMap<>();
+        values.put("name", "col1");
+        values.put("type", "type");
+        Referenceable ref = new Referenceable("column_type", values);
+        columns.add(ref);
+        Referenceable tableUpdated = new Referenceable(TestUtils.TABLE_TYPE, new HashMap<String, Object>() {{
+            put("columns", columns);
+        }});
+        metadataService.updateEntityPartialByGuid(tableId._getId(), tableUpdated);
+
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        final List<Referenceable> arrClsColumns = (List) tableDefinition.get("columns");
+        Assert.assertTrue(arrClsColumns.get(0).equalsContents(columns.get(0)));
+
+        //Partial update. Add col5 But also update col1
+        Map<String, Object> valuesCol5 = new HashMap<>();
+        valuesCol5.put("name", "col5");
+        valuesCol5.put("type", "type");
+        ref = new Referenceable("column_type", valuesCol5);
+        //update col1
+        arrClsColumns.get(0).set("type", "type1");
+
+        //add col5
+        final List<Referenceable> updateColumns = new ArrayList<>(arrClsColumns);
+        updateColumns.add(ref);
+
+        tableUpdated = new Referenceable(TestUtils.TABLE_TYPE, new HashMap<String, Object>() {{
+            put("columns", updateColumns);
+        }});
+        metadataService.updateEntityPartialByGuid(tableId._getId(), tableUpdated);
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        List<Referenceable> arrColumnsList = (List) tableDefinition.get("columns");
+        Assert.assertEquals(arrColumnsList.size(), 2);
+        Assert.assertTrue(arrColumnsList.get(0).equalsContents(updateColumns.get(0)));
+        Assert.assertTrue(arrColumnsList.get(1).equalsContents(updateColumns.get(1)));
+
+        //Complete update. Add  array elements - col3,4
+        Map<String, Object> values1 = new HashMap<>();
+        values1.put("name", "col3");
+        values1.put("type", "type");
+        Referenceable ref1 = new Referenceable("column_type", values1);
+        columns.add(ref1);
+
+        Map<String, Object> values2 = new HashMap<>();
+        values2.put("name", "col4");
+        values2.put("type", "type");
+        Referenceable ref2 = new Referenceable("column_type", values2);
+        columns.add(ref2);
+
+        table.set("columns", columns);
+        updateInstance(table);
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        arrColumnsList = (List) tableDefinition.get("columns");
+        Assert.assertEquals(arrColumnsList.size(), columns.size());
+        Assert.assertTrue(arrColumnsList.get(1).equalsContents(columns.get(1)));
+        Assert.assertTrue(arrColumnsList.get(2).equalsContents(columns.get(2)));
+
+
+        //Remove a class reference/Id and insert another reference
+        //Also covers isComposite case since columns is a composite
+        values.clear();
+        columns.clear();
+
+        values.put("name", "col2");
+        values.put("type", "type");
+        ref = new Referenceable("column_type", values);
+        columns.add(ref);
+        table.set("columns", columns);
+        updateInstance(table);
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        arrColumnsList = (List) tableDefinition.get("columns");
+        Assert.assertEquals(arrColumnsList.size(), columns.size());
+        Assert.assertTrue(arrColumnsList.get(0).equalsContents(columns.get(0)));
+
+        //Update array column to null
+        table.setNull("columns");
+        String newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        Assert.assertNull(tableDefinition.get("columns"));
+    }
+
+
+    @Test
+    public void testStructs() throws Exception {
+        Struct serdeInstance = new Struct(TestUtils.SERDE_TYPE);
+        serdeInstance.set("name", "serde1Name");
+        serdeInstance.set("serde", "test");
+        serdeInstance.set("description", "testDesc");
+        table.set("serde1", serdeInstance);
+
+        String newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        Assert.assertNotNull(tableDefinition.get("serde1"));
+        Assert.assertTrue(serdeInstance.equalsContents(tableDefinition.get("serde1")));
+
+        //update struct attribute
+        serdeInstance.set("serde", "testUpdated");
+        updateInstance(table);
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertTrue(serdeInstance.equalsContents(tableDefinition.get("serde1")));
+
+        //set to null
+        serdeInstance.setNull("description");
+        updateInstance(table);
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(tableId._getId());
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        Assert.assertNull(((Struct)tableDefinition.get("serde1")).get("description"));
+    }
+
+    @Test
+    public void testClassUpdate() throws Exception {
+        //Create new db instance
+        final Referenceable databaseInstance = new Referenceable(TestUtils.DATABASE_TYPE);
+        databaseInstance.set("name", TestUtils.randomString());
+        databaseInstance.set("description", "new database");
+
+        String dbId = createInstance(databaseInstance);
+
+        /*Update reference property with Id */
+        metadataService.updateEntityAttributeByGuid(tableId._getId(), "database", dbId);
+
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(tableId._getId());
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertEquals(dbId, (((Id)tableDefinition.get("database"))._getId()));
+
+        /* Update with referenceable - TODO - Fails . Need to fix this */
+        /*final String dbName = TestUtils.randomString();
+        final Referenceable databaseInstance2 = new Referenceable(TestUtils.DATABASE_TYPE);
+        databaseInstance2.set("name", dbName);
+        databaseInstance2.set("description", "new database 2");
+
+        Referenceable updateTable = new Referenceable(TestUtils.TABLE_TYPE, new HashMap<String, Object>() {{
+            put("database", databaseInstance2);
+        }});
+        metadataService.updateEntityAttributeByGuid(tableId._getId(), updateTable);
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(tableId._getId());
+        Referenceable tableDefinitionActual = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        String dbDefJson = metadataService.getEntityDefinition(TestUtils.DATABASE_TYPE, "name", dbName);
+        Referenceable dbDef = InstanceSerialization.fromJsonReferenceable(dbDefJson, true);
+
+        Assert.assertNotEquals(dbId, (((Id) tableDefinitionActual.get("database"))._getId()));
+        Assert.assertEquals(dbDef.getId()._getId(), (((Id) tableDefinitionActual.get("database"))._getId())); */
+
+    }
+
+    @Test
+    public void testArrayOfStructs() throws Exception {
+        //Add array of structs
+        TestUtils.dumpGraph(graphProvider.get());
+
+        final Struct partition1 = new Struct(TestUtils.PARTITION_TYPE);
+        partition1.set("name", "part1");
+
+        final Struct partition2 = new Struct(TestUtils.PARTITION_TYPE);
+        partition2.set("name", "part2");
+
+        List<Struct> partitions = new ArrayList<Struct>(){{ add(partition1); add(partition2); }};
+        table.set("partitions", partitions);
+
+        String newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertNotNull(tableDefinition.get("partitions"));
+        List<Struct> partitionsActual = (List<Struct>) tableDefinition.get("partitions");
+        Assert.assertEquals(partitionsActual.size(), 2);
+        Assert.assertTrue(partitions.get(0).equalsContents(partitionsActual.get(0)));
+
+        //add a new element to array of struct
+        final Struct partition3 = new Struct(TestUtils.PARTITION_TYPE);
+        partition3.set("name", "part3");
+        partitions.add(partition3);
+        table.set("partitions", partitions);
+        newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertNotNull(tableDefinition.get("partitions"));
+        partitionsActual = (List<Struct>) tableDefinition.get("partitions");
+        Assert.assertEquals(partitionsActual.size(), 3);
+        Assert.assertTrue(partitions.get(2).equalsContents(partitionsActual.get(2)));
+
+        //remove one of the struct values
+        partitions.remove(1);
+        table.set("partitions", partitions);
+        newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertNotNull(tableDefinition.get("partitions"));
+        partitionsActual = (List<Struct>) tableDefinition.get("partitions");
+        Assert.assertEquals(partitionsActual.size(), 2);
+        Assert.assertTrue(partitions.get(0).equalsContents(partitionsActual.get(0)));
+        Assert.assertTrue(partitions.get(1).equalsContents(partitionsActual.get(1)));
+
+        //Update struct value within array of struct
+        partition1.set("name", "part4");
+        newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertNotNull(tableDefinition.get("partitions"));
+        partitionsActual = (List<Struct>) tableDefinition.get("partitions");
+        Assert.assertEquals(partitionsActual.size(), 2);
+        Assert.assertTrue(partitions.get(0).equalsContents(partitionsActual.get(0)));
+
+        //add a repeated element to array of struct
+        final Struct partition4 = new Struct(TestUtils.PARTITION_TYPE);
+        partition4.set("name", "part4");
+        partitions.add(partition4);
+        table.set("partitions", partitions);
+        newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertNotNull(tableDefinition.get("partitions"));
+        partitionsActual = (List<Struct>) tableDefinition.get("partitions");
+        Assert.assertEquals(partitionsActual.size(), 3);
+        Assert.assertEquals(partitionsActual.get(2).get("name"), "part4");
+        Assert.assertEquals(partitionsActual.get(0).get("name"), "part4");
+        Assert.assertTrue(partitions.get(2).equalsContents(partitionsActual.get(2)));
+
+
+        // Remove all elements. Should set array attribute to null
+        partitions.clear();
+        newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertNull(tableDefinition.get("partitions"));
+    }
+
+
+    @Test(expectedExceptions = ValueConversionException.class)
+    public void testUpdateRequiredAttrToNull() throws Exception {
+        //Update required attribute
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        Assert.assertEquals(tableDefinition.get("description"), "random table");
+        table.setNull("description");
+
+        updateInstance(table);
+        Assert.fail("Expected exception while updating required attribute to null");
+    }
+
+    @Test
+    public void testUpdateOptionalAttrToNull() throws Exception {
+
+        String tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+
+        //Update optional Attribute
+        Assert.assertNotNull(tableDefinition.get("created"));
+        //Update optional attribute
+        table.setNull("created");
+
+        String newtableId = updateInstance(table);
+        Assert.assertEquals(newtableId, tableId._getId());
+
+        tableDefinitionJson =
+            metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
+        tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);
+        Assert.assertNull(tableDefinition.get("created"));
+    }
+
+    @Test
+    public void testCreateEntityWithEnum() throws Exception {
         String tableDefinitionJson =
                 metadataService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", (String) table.get("name"));
         Referenceable tableDefinition = InstanceSerialization.fromJsonReferenceable(tableDefinitionJson, true);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/repository/src/test/scala/org/apache/atlas/query/GremlinTest.scala
----------------------------------------------------------------------
diff --git a/repository/src/test/scala/org/apache/atlas/query/GremlinTest.scala b/repository/src/test/scala/org/apache/atlas/query/GremlinTest.scala
index 1097828..0b57df3 100755
--- a/repository/src/test/scala/org/apache/atlas/query/GremlinTest.scala
+++ b/repository/src/test/scala/org/apache/atlas/query/GremlinTest.scala
@@ -39,7 +39,6 @@ class GremlinTest extends BaseGremlinTest {
     gProvider = new TitanGraphProvider();
     gp = new DefaultGraphPersistenceStrategy(new GraphBackedMetadataRepository(gProvider))
     g = QueryTestsUtils.setupTestGraph(gProvider)
-
   }
 
   @AfterClass

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/pom.xml
----------------------------------------------------------------------
diff --git a/server-api/pom.xml b/server-api/pom.xml
new file mode 100644
index 0000000..88de030
--- /dev/null
+++ b/server-api/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>apache-atlas</artifactId>
+        <groupId>org.apache.atlas</groupId>
+        <version>0.6-incubating-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>atlas-server-api</artifactId>
+
+    <name>Apache Atlas Server API</name>
+    <description>Apache Atlas Server related APIs</description>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.atlas</groupId>
+            <artifactId>atlas-typesystem</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/src/main/java/org/apache/atlas/discovery/DiscoveryException.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/discovery/DiscoveryException.java b/server-api/src/main/java/org/apache/atlas/discovery/DiscoveryException.java
new file mode 100644
index 0000000..ba69af7
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/discovery/DiscoveryException.java
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.discovery;
+
+import org.apache.atlas.AtlasException;
+
+import java.security.PrivilegedActionException;
+
+public class DiscoveryException extends AtlasException {
+
+    /**
+     * Constructs a new exception with the specified detail message.  The
+     * cause is not initialized, and may subsequently be initialized by
+     * a call to {@link #initCause}.
+     *
+     * @param message the detail message. The detail message is saved for
+     *                later retrieval by the {@link #getMessage()} method.
+     */
+    public DiscoveryException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this exception's detail message.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *                by the {@link #getMessage()} method).
+     * @param cause   the cause (which is saved for later retrieval by the
+     *                {@link #getCause()} method).  (A <tt>null</tt> value is
+     *                permitted, and indicates that the cause is nonexistent or
+     *                unknown.)
+     * @since 1.4
+     */
+    public DiscoveryException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of <tt>(cause==null ? null : cause.toString())</tt> (which
+     * typically contains the class and detail message of <tt>cause</tt>).
+     * This constructor is useful for exceptions that are little more than
+     * wrappers for other throwables (for example, {@link
+     * PrivilegedActionException}).
+     *
+     * @param cause the cause (which is saved for later retrieval by the
+     *              {@link #getCause()} method).  (A <tt>null</tt> value is
+     *              permitted, and indicates that the cause is nonexistent or
+     *              unknown.)
+     * @since 1.4
+     */
+    public DiscoveryException(Throwable cause) {
+        super(cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/src/main/java/org/apache/atlas/discovery/DiscoveryService.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/discovery/DiscoveryService.java b/server-api/src/main/java/org/apache/atlas/discovery/DiscoveryService.java
new file mode 100644
index 0000000..e347c2c
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/discovery/DiscoveryService.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.discovery;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Metadata discovery service.
+ */
+public interface DiscoveryService {
+
+    /**
+     * Full text search
+     */
+    String searchByFullText(String query) throws DiscoveryException;
+
+    /**
+     * Search using query DSL.
+     *
+     * @param dslQuery query in DSL format.
+     * @return JSON representing the type and results.
+     */
+    String searchByDSL(String dslQuery) throws DiscoveryException;
+
+    /**
+     * Assumes the User is familiar with the persistence structure of the Repository.
+     * The given query is run uninterpreted against the underlying Graph Store.
+     * The results are returned as a List of Rows. each row is a Map of Key,Value pairs.
+     *
+     * @param gremlinQuery query in gremlin dsl format
+     * @return List of Maps
+     * @throws org.apache.atlas.discovery.DiscoveryException
+     */
+    List<Map<String, String>> searchByGremlin(String gremlinQuery) throws DiscoveryException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/src/main/java/org/apache/atlas/discovery/LineageService.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/discovery/LineageService.java b/server-api/src/main/java/org/apache/atlas/discovery/LineageService.java
new file mode 100644
index 0000000..8dc36cd
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/discovery/LineageService.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.discovery;
+
+import org.apache.atlas.AtlasException;
+
+/**
+ * Lineage service interface.
+ */
+public interface LineageService {
+
+    /**
+     * Return the lineage outputs for the given tableName.
+     *
+     * @param tableName tableName
+     * @return Outputs as JSON
+     */
+    String getOutputs(String tableName) throws AtlasException;
+
+    /**
+     * Return the lineage outputs graph for the given tableName.
+     *
+     * @param tableName tableName
+     * @return Outputs Graph as JSON
+     */
+    String getOutputsGraph(String tableName) throws AtlasException;
+
+    /**
+     * Return the lineage inputs for the given tableName.
+     *
+     * @param tableName tableName
+     * @return Inputs as JSON
+     */
+    String getInputs(String tableName) throws AtlasException;
+
+    /**
+     * Return the lineage inputs graph for the given tableName.
+     *
+     * @param tableName tableName
+     * @return Inputs Graph as JSON
+     */
+    String getInputsGraph(String tableName) throws AtlasException;
+
+    /**
+     * Return the schema for the given tableName.
+     *
+     * @param tableName tableName
+     * @return Schema as JSON
+     */
+    String getSchema(String tableName) throws AtlasException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/src/main/java/org/apache/atlas/listener/EntityChangeListener.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/listener/EntityChangeListener.java b/server-api/src/main/java/org/apache/atlas/listener/EntityChangeListener.java
new file mode 100644
index 0000000..619ed85
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/listener/EntityChangeListener.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.listener;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.typesystem.IStruct;
+import org.apache.atlas.typesystem.ITypedReferenceableInstance;
+
+import java.util.Collection;
+
+/**
+ * Entity (a Typed instance) change notification listener.
+ */
+public interface EntityChangeListener {
+
+    /**
+     * This is upon adding new entities to the repository.
+     *
+     * @param entities  the created entities
+     *
+     * @throws AtlasException if the listener notification fails
+     */
+    void onEntitiesAdded(Collection<ITypedReferenceableInstance> entities) throws AtlasException;
+
+    /**
+     * This is upon updating an entity.
+     *
+     * @param entities        the updated entities
+     *
+     * @throws AtlasException if the listener notification fails
+     */
+    void onEntitiesUpdated(Collection<ITypedReferenceableInstance> entities) throws AtlasException;
+
+    /**
+     * This is upon adding a new trait to a typed instance.
+     *
+     * @param entity        the entity
+     * @param trait     trait that needs to be added to entity
+     *
+     * @throws AtlasException if the listener notification fails
+     */
+    void onTraitAdded(ITypedReferenceableInstance entity, IStruct trait) throws AtlasException;
+
+    /**
+     * This is upon deleting a trait from a typed instance.
+     *
+     * @param entity        the entity
+     * @param traitName     trait name for the instance that needs to be deleted from entity
+     *
+     * @throws AtlasException if the listener notification fails
+     */
+    void onTraitDeleted(ITypedReferenceableInstance entity, String traitName) throws AtlasException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/src/main/java/org/apache/atlas/listener/TypesChangeListener.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/listener/TypesChangeListener.java b/server-api/src/main/java/org/apache/atlas/listener/TypesChangeListener.java
new file mode 100644
index 0000000..5ff6d4a
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/listener/TypesChangeListener.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.listener;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.typesystem.types.IDataType;
+
+import java.util.Collection;
+
+/**
+ * Types change notification listener.
+ */
+public interface TypesChangeListener {
+
+    /**
+     * This is upon adding new type(s) to Store.
+     *
+     * @param dataTypes data type
+     * @throws AtlasException
+     */
+    void onAdd(Collection<? extends IDataType> dataTypes) throws AtlasException;
+
+    /**
+     * This is upon removing an existing type from the Store.
+     *
+     * @param typeName type name
+     * @throws AtlasException
+     */
+    // void onRemove(String typeName) throws MetadataException;
+
+     //This is upon updating an existing type to the store
+     void onChange(Collection<? extends IDataType> dataTypes) throws AtlasException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/src/main/java/org/apache/atlas/services/MetadataService.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/services/MetadataService.java b/server-api/src/main/java/org/apache/atlas/services/MetadataService.java
new file mode 100644
index 0000000..0cfed2e
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/services/MetadataService.java
@@ -0,0 +1,187 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.services;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.listener.EntityChangeListener;
+import org.apache.atlas.typesystem.Referenceable;
+import org.apache.atlas.typesystem.types.DataTypes;
+import org.codehaus.jettison.json.JSONObject;
+
+import java.util.List;
+
+/**
+ * Metadata service.
+ */
+public interface MetadataService {
+
+    /**
+     * Creates a new type based on the type system to enable adding
+     * entities (instances for types).
+     *
+     * @param typeDefinition definition as json
+     * @return a unique id for this type
+     */
+    JSONObject createType(String typeDefinition) throws AtlasException;
+
+    /**
+     * Updates the given types in the type definition
+     * @param typeDefinition
+     * @return
+     * @throws AtlasException
+     */
+    JSONObject updateType(String typeDefinition) throws AtlasException;
+
+    /**
+     * Return the definition for the given type.
+     *
+     * @param typeName name for this type, must be unique
+     * @return type definition as JSON
+     */
+    String getTypeDefinition(String typeName) throws AtlasException;
+
+    /**
+     * Return the list of types in the type system.
+     *
+     * @return list of type names in the type system
+     */
+    List<String> getTypeNamesList() throws AtlasException;
+
+    /**
+     * Return the list of trait type names in the type system.
+     *
+     * @return list of trait type names in the type system
+     */
+    List<String> getTypeNamesByCategory(DataTypes.TypeCategory typeCategory) throws AtlasException;
+
+    /**
+     * Creates an entity, instance of the type.
+     *
+     * @param entityDefinition definition
+     * @return guid
+     */
+    String createEntities(String entityDefinition) throws AtlasException;
+
+    /**
+     * Return the definition for the given guid.
+     *
+     * @param guid guid
+     * @return entity definition as JSON
+     */
+    String getEntityDefinition(String guid) throws AtlasException;
+
+    /**
+     * Return the definition given type and attribute. The attribute has to be unique attribute for the type
+     * @param entityType - type name
+     * @param attribute - attribute name
+     * @param value - attribute value
+     * @return
+     * @throws AtlasException
+     */
+    String getEntityDefinition(String entityType, String attribute, String value) throws AtlasException;
+
+    /**
+     * Return the list of entity names for the given type in the repository.
+     *
+     * @param entityType type
+     * @return list of entity names for the given type in the repository
+     */
+    List<String> getEntityList(String entityType) throws AtlasException;
+
+    /**
+     * Adds the property to the given entity id(guid).
+     * Currently supports updates only on PRIMITIVE, CLASS attribute types
+     *
+     * @param guid entity id
+     * @param attribute property name
+     * @param value    property value
+     */
+    void updateEntityAttributeByGuid(String guid, String attribute, String value) throws AtlasException;
+
+    /**
+     * Supports Partial updates of an entity. Users can update a subset of attributes for an entity identified by its guid
+     * Note however that it cannot be used to set attribute values to null or delete attrbute values
+     *
+     */
+    void updateEntityPartialByGuid(String guid, Referenceable entity) throws AtlasException;
+
+    /**
+     * Batch API - Adds/Updates the given entity id(guid).
+     *
+     * @param entityJson entity json
+     * @return List of guids which were updated and ones which were newly created as part of the updated entity
+     */
+    String updateEntities(String entityJson) throws AtlasException;
+
+    // Trait management functions
+
+    /**
+     * Updates entity identified by a qualified name
+     *
+     * @param typeName
+     * @param uniqueAttributeName
+     * @param attrValue
+     * @param updatedEntity
+     * @return Guid of updated entity
+     * @throws AtlasException
+     */
+    String updateEntityByUniqueAttribute(String typeName, String uniqueAttributeName, String attrValue,
+                                         Referenceable updatedEntity) throws AtlasException;
+
+    /**
+     * Gets the list of trait names for a given entity represented by a guid.
+     *
+     * @param guid globally unique identifier for the entity
+     * @return a list of trait names for the given entity guid
+     * @throws AtlasException
+     */
+    List<String> getTraitNames(String guid) throws AtlasException;
+
+    /**
+     * Adds a new trait to an existing entity represented by a guid.
+     *
+     * @param guid          globally unique identifier for the entity
+     * @param traitInstanceDefinition trait instance that needs to be added to entity
+     * @throws AtlasException
+     */
+    void addTrait(String guid, String traitInstanceDefinition) throws AtlasException;
+
+    /**
+     * Deletes a given trait from an existing entity represented by a guid.
+     *
+     * @param guid                 globally unique identifier for the entity
+     * @param traitNameToBeDeleted name of the trait
+     * @throws AtlasException
+     */
+    void deleteTrait(String guid, String traitNameToBeDeleted) throws AtlasException;
+
+    /**
+     * Register a listener for entity change.
+     *
+     * @param listener  the listener to register
+     */
+    void registerListener(EntityChangeListener listener);
+
+    /**
+     * Unregister an entity change listener.
+     *
+     * @param listener  the listener to unregister
+     */
+    void unregisterListener(EntityChangeListener listener);
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/src/main/java/org/apache/atlas/typesystem/exception/EntityExistsException.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/typesystem/exception/EntityExistsException.java b/server-api/src/main/java/org/apache/atlas/typesystem/exception/EntityExistsException.java
new file mode 100644
index 0000000..b16cfa9
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/typesystem/exception/EntityExistsException.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.typesystem.exception;
+
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.typesystem.IReferenceableInstance;
+
+public class EntityExistsException extends AtlasException {
+    public EntityExistsException(IReferenceableInstance typedInstance, Exception e) {
+        super("Model violation for type "+ typedInstance.getTypeName(), e);
+    }
+
+    public EntityExistsException(IReferenceableInstance typedInstance) {
+        super("Model violation for type "+ typedInstance.getTypeName());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/server-api/src/main/java/org/apache/atlas/typesystem/exception/EntityNotFoundException.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/typesystem/exception/EntityNotFoundException.java b/server-api/src/main/java/org/apache/atlas/typesystem/exception/EntityNotFoundException.java
new file mode 100644
index 0000000..0fec895
--- /dev/null
+++ b/server-api/src/main/java/org/apache/atlas/typesystem/exception/EntityNotFoundException.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.typesystem.exception;
+
+import org.apache.atlas.AtlasException;
+
+/**
+ * A simple wrapper for 404.
+ */
+public class EntityNotFoundException extends AtlasException {
+    public EntityNotFoundException() {
+    }
+
+    public EntityNotFoundException(String message) {
+        super(message);
+    }
+
+    public EntityNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public EntityNotFoundException(Throwable cause) {
+        super(cause);
+    }
+
+    public EntityNotFoundException(String message, Throwable cause, boolean enableSuppression,
+            boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/pom.xml
----------------------------------------------------------------------
diff --git a/typesystem/pom.xml b/typesystem/pom.xml
index efb49ed..129de58 100755
--- a/typesystem/pom.xml
+++ b/typesystem/pom.xml
@@ -110,13 +110,8 @@
         </dependency>
 
         <dependency>
-            <groupId>com.google.inject</groupId>
-            <artifactId>guice</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-configuration</groupId>
-            <artifactId>commons-configuration</artifactId>
+            <groupId>org.apache.atlas</groupId>
+            <artifactId>atlas-common</artifactId>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/ApplicationProperties.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/ApplicationProperties.java b/typesystem/src/main/java/org/apache/atlas/ApplicationProperties.java
deleted file mode 100644
index 738ec53..0000000
--- a/typesystem/src/main/java/org/apache/atlas/ApplicationProperties.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.atlas;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.PropertiesConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Iterator;
-
-public class ApplicationProperties extends PropertiesConfiguration {
-    private static final Logger LOG = LoggerFactory.getLogger(ApplicationProperties.class);
-
-    public static final String APPLICATION_PROPERTIES = "application.properties";
-    public static final String CLIENT_PROPERTIES = "client.properties";
-
-    private static Configuration INSTANCE = null;
-
-    private ApplicationProperties(URL url) throws ConfigurationException {
-        super(url);
-    }
-
-    public static Configuration get() throws AtlasException {
-        if (INSTANCE == null) {
-            synchronized (ApplicationProperties.class) {
-                if (INSTANCE == null) {
-                    Configuration applicationProperties = get(APPLICATION_PROPERTIES);
-                    Configuration clientProperties = get(CLIENT_PROPERTIES);
-                    INSTANCE = new CompositeConfiguration(Arrays.asList(applicationProperties, clientProperties));
-                }
-            }
-        }
-        return INSTANCE;
-    }
-
-    public static Configuration get(String fileName) throws AtlasException {
-        String confLocation = System.getProperty("atlas.conf");
-        try {
-            URL url = confLocation == null ? ApplicationProperties.class.getResource("/" + fileName)
-                    : new File(confLocation, fileName).toURI().toURL();
-            LOG.info("Loading {} from {}", fileName, url);
-
-            Configuration configuration = new ApplicationProperties(url).interpolatedConfiguration();
-            logConfiguration(configuration);
-            return configuration;
-        } catch (Exception e) {
-            throw new AtlasException("Failed to load application properties", e);
-        }
-    }
-
-    private static void logConfiguration(Configuration configuration) {
-        if (LOG.isDebugEnabled()) {
-            Iterator<String> keys = configuration.getKeys();
-            LOG.debug("Configuration loaded:");
-            while (keys.hasNext()) {
-                String key = keys.next();
-                LOG.debug("{} = {}", key, configuration.getProperty(key));
-            }
-        }
-    }
-
-    public static final Configuration getSubsetConfiguration(Configuration inConf, String prefix) {
-        return inConf.subset(prefix);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/AtlasException.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/AtlasException.java b/typesystem/src/main/java/org/apache/atlas/AtlasException.java
deleted file mode 100755
index 2eb0658..0000000
--- a/typesystem/src/main/java/org/apache/atlas/AtlasException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.atlas;
-
-/**
- * Base Exception class for metadata API.
- */
-public class AtlasException extends Exception {
-
-    public AtlasException() {
-    }
-
-    public AtlasException(String message) {
-        super(message);
-    }
-
-    public AtlasException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    public AtlasException(Throwable cause) {
-        super(cause);
-    }
-
-    public AtlasException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
-        super(message, cause, enableSuppression, writableStackTrace);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/ParamChecker.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/ParamChecker.java b/typesystem/src/main/java/org/apache/atlas/ParamChecker.java
deleted file mode 100644
index e900ba3..0000000
--- a/typesystem/src/main/java/org/apache/atlas/ParamChecker.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.atlas;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-public class ParamChecker {
-
-    /**
-     * Check that a value is not null. If null throws an IllegalArgumentException.
-     *
-     * @param obj value.
-     * @param name parameter name for the exception message.
-     * @return the given value.
-     */
-    public static <T> T notNull(T obj, String name) {
-        if (obj == null) {
-            throw new IllegalArgumentException(name + " cannot be null");
-        }
-        return obj;
-    }
-
-    /**
-     * Check that a list is not null and that none of its elements is null. If null or if the list has emtpy elements
-     * throws an IllegalArgumentException.
-     *  @param list the list of T.
-     * @param name parameter name for the exception message.
-     */
-    public static <T> Collection<T> notNullElements(Collection<T> list, String name) {
-        notEmpty(list, name);
-        for (T ele : list) {
-            notNull(ele, String.format("Collection %s element %s", name, ele));
-        }
-        return list;
-    }
-
-    /**
-     * Check that a list is not null and that none of its elements is null. If null or if the list has emtpy elements
-     * throws an IllegalArgumentException.
-     *  @param array the array of T.
-     * @param name parameter name for the exception message.
-     */
-    public static <T> T[] notNullElements(T[] array, String name) {
-        notEmpty(Arrays.asList(array), name);
-        for (T ele : array) {
-            notNull(ele, String.format("Collection %s element %s", name, ele));
-        }
-        return array;
-    }
-
-    /**
-     * Check that a list is not null and not empty.
-     *  @param list the list of T.
-     * @param name parameter name for the exception message.
-     */
-    public static <T> Collection<T> notEmpty(Collection<T> list, String name) {
-        notNull(list, name);
-        if (list.isEmpty()) {
-            throw new IllegalArgumentException(String.format("Collection %s is empty", name));
-        }
-        return list;
-    }
-
-    /**
-     * Check that a string is not null and not empty. If null or emtpy throws an IllegalArgumentException.
-     *
-     * @param value value.
-     * @param name parameter name for the exception message.
-     * @return the given value.
-     */
-    public static String notEmpty(String value, String name) {
-        return notEmpty(value, name, null);
-    }
-
-    /**
-     * Check that a string is not empty if its not null.
-     *
-     * @param value value.
-     * @param name parameter name for the exception message.
-     * @return the given value.
-     */
-    public static String notEmptyIfNotNull(String value, String name) {
-        return notEmptyIfNotNull(value, name, null);
-    }
-
-    /**
-     * Check that a string is not empty if its not null.
-     *
-     * @param value value.
-     * @param name parameter name for the exception message.
-     * @return the given value.
-     */
-    public static String notEmptyIfNotNull(String value, String name, String info) {
-        if (value == null) {
-            return value;
-        }
-
-        if (value.trim().length() == 0) {
-            throw new IllegalArgumentException(name + " cannot be empty" + (info == null ? "" : ", " + info));
-        }
-        return value.trim();
-    }
-
-    /**
-     * Check that a string is not null and not empty. If null or emtpy throws an IllegalArgumentException.
-     *
-     * @param value value.
-     * @param name parameter name for the exception message.
-     * @param info additional information to be printed with the exception message
-     * @return the given value.
-     */
-    public static String notEmpty(String value, String name, String info) {
-        if (value == null) {
-            throw new IllegalArgumentException(name + " cannot be null" + (info == null ? "" : ", " + info));
-        }
-        return notEmptyIfNotNull(value, name, info);
-    }
-
-    /**
-     * Check that a list is not null and that none of its elements is null. If null or if the list has emtpy elements
-     * throws an IllegalArgumentException.
-     *  @param list the list of strings.
-     * @param name parameter name for the exception message.
-     */
-    public static Collection<String> notEmptyElements(Collection<String> list, String name) {
-        notEmpty(list, name);
-        for (String ele : list) {
-            notEmpty(ele, String.format("list %s element %s", name, ele));
-        }
-        return list;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/TypeExistsException.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/TypeExistsException.java b/typesystem/src/main/java/org/apache/atlas/TypeExistsException.java
deleted file mode 100644
index 1a2cb7c..0000000
--- a/typesystem/src/main/java/org/apache/atlas/TypeExistsException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.atlas;
-
-public class TypeExistsException extends AtlasException {
-    public TypeExistsException(String message) {
-        super(message);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/TypeNotFoundException.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/TypeNotFoundException.java b/typesystem/src/main/java/org/apache/atlas/TypeNotFoundException.java
deleted file mode 100644
index 348dd57..0000000
--- a/typesystem/src/main/java/org/apache/atlas/TypeNotFoundException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.atlas;
-
-/**
- * A simple wrapper for 404.
- */
-public class TypeNotFoundException extends AtlasException {
-    public TypeNotFoundException() {
-    }
-
-    public TypeNotFoundException(String message) {
-        super(message);
-    }
-
-    public TypeNotFoundException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    public TypeNotFoundException(Throwable cause) {
-        super(cause);
-    }
-
-    public TypeNotFoundException(String message, Throwable cause, boolean enableSuppression,
-            boolean writableStackTrace) {
-        super(message, cause, enableSuppression, writableStackTrace);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/typesystem/IInstance.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/IInstance.java b/typesystem/src/main/java/org/apache/atlas/typesystem/IInstance.java
index c903301..ffe40a7 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/IInstance.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/IInstance.java
@@ -33,6 +33,8 @@ public interface IInstance {
 
     void set(String attrName, Object val) throws AtlasException;
 
+    void setNull(String attrName) throws AtlasException;
+
     Map<String, Object> getValuesMap() throws AtlasException;
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/typesystem/ITypedInstance.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/ITypedInstance.java b/typesystem/src/main/java/org/apache/atlas/typesystem/ITypedInstance.java
index c951172..d7f4cb7 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/ITypedInstance.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/ITypedInstance.java
@@ -23,6 +23,7 @@ import org.apache.atlas.typesystem.types.FieldMapping;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.security.MessageDigest;
 import java.util.Date;
 
 /**
@@ -37,8 +38,6 @@ public interface ITypedInstance extends IInstance {
 
     FieldMapping fieldMapping();
 
-    void setNull(String attrName) throws AtlasException;
-
     boolean getBoolean(String attrName) throws AtlasException;
 
     byte getByte(String attrName) throws AtlasException;
@@ -82,4 +81,6 @@ public interface ITypedInstance extends IInstance {
     void setDate(String attrName, Date val) throws AtlasException;
 
     void setString(String attrName, String val) throws AtlasException;
+
+    String getSignatureHash(MessageDigest digester) throws AtlasException;
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java b/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
index aaf0aa4..b8dcc7e 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/Referenceable.java
@@ -24,7 +24,6 @@ import org.apache.atlas.AtlasException;
 import org.apache.atlas.classification.InterfaceAudience;
 import org.apache.atlas.typesystem.persistence.Id;
 
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -95,8 +94,10 @@ public class Referenceable extends Struct implements IReferenceableInstance {
      */
     @SuppressWarnings("unused")
     private Referenceable() {
-        this("", "", Collections.<String, Object>emptyMap(), Collections.<String>emptyList(),
-            Collections.<String, IStruct>emptyMap());
+        super(null, null);
+        id = null;
+        traitNames = ImmutableList.of();
+        traits = ImmutableMap.of();
     }
 
     @Override
@@ -114,6 +115,42 @@ public class Referenceable extends Struct implements IReferenceableInstance {
         return traits.get(typeName);
     }
 
+    /**
+     * Matches traits, values associated with this Referenceable and skips the id match
+     * @param o The Referenceable which needs to be matched with
+     * @return
+     */
+    public boolean equalsContents(Object o) {
+        if(this == o) {
+            return true;
+        }
+        if(o == null) {
+            return false;
+        }
+        if (o.getClass() != getClass()) {
+            return false;
+        }
+
+        if(!super.equalsContents(o)) {
+            return false;
+        }
+
+        Referenceable obj = (Referenceable)o;
+        if (!traitNames.equals(obj.getTraits())) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public String toString() {
+        return "{" +
+            "Id='" + id + '\'' +
+            ", traits=" + traitNames +
+            ", values=" + getValuesMap() +
+            '}';
+    }
+
     private static Map<String, IStruct> getTraits(IReferenceableInstance instance) throws AtlasException {
         Map<String, IStruct> traits = new HashMap<>();
         for (String traitName : instance.getTraits() ) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/51656991/typesystem/src/main/java/org/apache/atlas/typesystem/Struct.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/Struct.java b/typesystem/src/main/java/org/apache/atlas/typesystem/Struct.java
index d03e2c2..70deab2 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/Struct.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/Struct.java
@@ -18,6 +18,7 @@
 
 package org.apache.atlas.typesystem;
 
+import org.apache.atlas.AtlasException;
 import org.apache.atlas.classification.InterfaceAudience;
 
 import java.util.Collections;
@@ -67,7 +68,52 @@ public class Struct implements IStruct {
     }
 
     @Override
+    public void setNull(String attrName) throws AtlasException {
+        values.remove(attrName);
+    }
+
+    @Override
     public Map<String, Object> getValuesMap() {
         return values;
     }
+
+    @Override
+    public int hashCode() {
+        int result = typeName.hashCode();
+        result = 31 * result + values.hashCode();
+        return result;
+    }
+
+    /**
+     * equalContents instead of equals since values is a mutable attribute and could lead
+     * to incorrect behaviour when added to collections and mutated after that
+     * i.e when the attribute is mutated collections.contains(struct) returns false
+     * due to hashcode having changed for the struct.
+     * @param o
+     * @return
+     */
+    public boolean equalsContents(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null) {
+            return false;
+        }
+
+        if (o.getClass() != getClass()) {
+            return false;
+        }
+
+        Struct obj = (Struct)o;
+        if(!typeName.equals(obj.getTypeName())) {
+            return false;
+        }
+
+        if(!values.equals(obj.getValuesMap())) {
+            return false;
+        }
+
+        return true;
+    }
 }