blob: 98df12bd6907e35f74beecbda9717661d4be4c87 [file] [log] [blame]
/**
* 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.web.adapters;
import org.apache.atlas.AtlasClient;
import org.apache.atlas.RequestContextV1;
import org.apache.atlas.TestModules;
import org.apache.atlas.TestUtilsV2;
import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
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.ClassificationAssociateRequest;
import org.apache.atlas.model.instance.EntityMutationResponse;
import org.apache.atlas.model.instance.EntityMutations;
import org.apache.atlas.model.typedef.AtlasTypesDef;
import org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
import org.apache.atlas.store.AtlasTypeDefStore;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.web.rest.EntityREST;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import javax.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Guice(modules = {TestModules.TestOnlyModule.class})
public class TestEntitiesREST {
private static final Logger LOG = LoggerFactory.getLogger(TestEntitiesREST.class);
@Inject
AtlasTypeRegistry typeRegistry;
@Inject
private AtlasTypeDefStore typeStore;
@Inject
private EntityREST entityREST;
private List<String> createdGuids = new ArrayList<>();
private AtlasEntity dbEntity;
private AtlasEntity tableEntity;
private List<AtlasEntity> columns;
@BeforeClass
public void setUp() throws Exception {
AtlasTypesDef[] testTypesDefs = new AtlasTypesDef[] { TestUtilsV2.defineHiveTypes() };
for (AtlasTypesDef typesDef : testTypesDefs) {
AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(typesDef, typeRegistry);
if (!typesToCreate.isEmpty()) {
typeStore.createTypesDef(typesToCreate);
}
}
dbEntity = TestUtilsV2.createDBEntity();
tableEntity = TestUtilsV2.createTableEntity(dbEntity);
final AtlasEntity colEntity = TestUtilsV2.createColumnEntity(tableEntity);
columns = new ArrayList<AtlasEntity>() {{ add(colEntity); }};
tableEntity.setAttribute("columns", getObjIdList(columns));
}
@AfterMethod
public void cleanup() throws Exception {
RequestContextV1.clear();
}
@Test
public void testCreateOrUpdateEntities() throws Exception {
AtlasEntitiesWithExtInfo entities = new AtlasEntitiesWithExtInfo();
entities.addEntity(dbEntity);
entities.addEntity(tableEntity);
for (AtlasEntity column : columns) {
entities.addReferredEntity(column);
}
EntityMutationResponse response = entityREST.createOrUpdate(entities);
List<AtlasEntityHeader> guids = response.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
Assert.assertNotNull(guids);
Assert.assertEquals(guids.size(), 3);
for (AtlasEntityHeader header : guids) {
createdGuids.add(header.getGuid());
}
}
@Test(dependsOnMethods = "testCreateOrUpdateEntities")
public void testTagToMultipleEntities() throws Exception{
AtlasClassification tag = new AtlasClassification(TestUtilsV2.CLASSIFICATION, new HashMap<String, Object>() {{ put("tag", "tagName"); }});
ClassificationAssociateRequest classificationAssociateRequest = new ClassificationAssociateRequest(createdGuids, tag);
entityREST.addClassification(classificationAssociateRequest);
for (String guid : createdGuids) {
final AtlasClassification result_tag = entityREST.getClassification(guid, TestUtilsV2.CLASSIFICATION);
Assert.assertNotNull(result_tag);
Assert.assertEquals(result_tag, tag);
}
}
@Test
public void testUpdateWithSerializedEntities() throws Exception {
//Check with serialization and deserialization of entity attributes for the case
// where attributes which are de-serialized into a map
AtlasEntity dbEntity = TestUtilsV2.createDBEntity();
AtlasEntity tableEntity = TestUtilsV2.createTableEntity(dbEntity);
final AtlasEntity colEntity = TestUtilsV2.createColumnEntity(tableEntity);
List<AtlasEntity> columns = new ArrayList<AtlasEntity>() {{ add(colEntity); }};
tableEntity.setAttribute("columns", getObjIdList(columns));
AtlasEntity newDBEntity = serDeserEntity(dbEntity);
AtlasEntity newTableEntity = serDeserEntity(tableEntity);
AtlasEntitiesWithExtInfo newEntities = new AtlasEntitiesWithExtInfo();
newEntities.addEntity(newDBEntity);
newEntities.addEntity(newTableEntity);
for (AtlasEntity column : columns) {
newEntities.addReferredEntity(serDeserEntity(column));
}
EntityMutationResponse response2 = entityREST.createOrUpdate(newEntities);
List<AtlasEntityHeader> newGuids = response2.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
Assert.assertNotNull(newGuids);
Assert.assertEquals(newGuids.size(), 3);
}
@Test(dependsOnMethods = "testCreateOrUpdateEntities")
public void testGetEntities() throws Exception {
final AtlasEntitiesWithExtInfo response = entityREST.getByGuids(createdGuids);
final List<AtlasEntity> entities = response.getEntities();
Assert.assertNotNull(entities);
Assert.assertEquals(entities.size(), 3);
verifyAttributes(entities);
}
/* Disabled until EntityREST.deleteByIds() is implemented
*
@Test(dependsOnMethods = "testGetEntities")
public void testDeleteEntities() throws Exception {
final EntityMutationResponse response = entityREST.deleteByGuids(createdGuids);
final List<AtlasEntityHeader> entities = response.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE);
Assert.assertNotNull(entities);
Assert.assertEquals(entities.size(), 3);
}
*
*/
private void verifyAttributes(List<AtlasEntity> retrievedEntities) throws Exception {
AtlasEntity retrievedDBEntity = null;
AtlasEntity retrievedTableEntity = null;
AtlasEntity retrievedColumnEntity = null;
for (AtlasEntity entity: retrievedEntities ) {
if ( entity.getTypeName().equals(TestUtilsV2.DATABASE_TYPE)) {
retrievedDBEntity = entity;
}
if ( entity.getTypeName().equals(TestUtilsV2.TABLE_TYPE)) {
retrievedTableEntity = entity;
}
if ( entity.getTypeName().equals(TestUtilsV2.COLUMN_TYPE)) {
retrievedColumnEntity = entity;
}
}
if ( retrievedDBEntity != null) {
LOG.info("verifying entity of type {} ", dbEntity.getTypeName());
verifyAttributes(retrievedDBEntity.getAttributes(), dbEntity.getAttributes());
}
if ( retrievedColumnEntity != null) {
LOG.info("verifying entity of type {} ", columns.get(0).getTypeName());
Assert.assertEquals(columns.get(0).getAttribute(AtlasClient.NAME), retrievedColumnEntity.getAttribute(AtlasClient.NAME));
Assert.assertEquals(columns.get(0).getAttribute("type"), retrievedColumnEntity.getAttribute("type"));
}
if ( retrievedTableEntity != null) {
LOG.info("verifying entity of type {} ", tableEntity.getTypeName());
//String
Assert.assertEquals(tableEntity.getAttribute(AtlasClient.NAME), retrievedTableEntity.getAttribute(AtlasClient.NAME));
//Map
Assert.assertEquals(tableEntity.getAttribute("parametersMap"), retrievedTableEntity.getAttribute("parametersMap"));
//enum
Assert.assertEquals(tableEntity.getAttribute("tableType"), retrievedTableEntity.getAttribute("tableType"));
//date
Assert.assertEquals(tableEntity.getAttribute("created"), retrievedTableEntity.getAttribute("created"));
//array of Ids
Assert.assertEquals(((List<AtlasObjectId>) retrievedTableEntity.getAttribute("columns")).get(0).getGuid(), retrievedColumnEntity.getGuid());
//array of structs
Assert.assertEquals(((List<AtlasStruct>) retrievedTableEntity.getAttribute("partitions")), tableEntity.getAttribute("partitions"));
}
}
public static void verifyAttributes(Map<String, Object> actual, Map<String, Object> expected) throws Exception {
for (String name : actual.keySet() ) {
LOG.info("verifying attribute {} ", name);
if ( expected.get(name) != null) {
Assert.assertEquals(actual.get(name), expected.get(name));
}
}
}
AtlasEntity serDeserEntity(AtlasEntity entity) throws IOException {
//Convert from json to object and back to trigger the case where it gets translated to a map for attributes instead of AtlasEntity
String jsonString = AtlasType.toJson(entity);
AtlasEntity newEntity = AtlasType.fromJson(jsonString, AtlasEntity.class);
return newEntity;
}
private List<AtlasObjectId> getObjIdList(Collection<AtlasEntity> entities) {
List<AtlasObjectId> ret = new ArrayList<>();
for (AtlasEntity entity : entities) {
ret.add(AtlasTypeUtil.getAtlasObjectId(entity));
}
return ret;
}
}