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;
+ }
}