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