/**
 * 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.repository.graph;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.apache.atlas.AtlasException;
import org.apache.atlas.CreateUpdateEntitiesResult;
import org.apache.atlas.GraphTransaction;
import org.apache.atlas.RequestContext;
import org.apache.atlas.TestOnlyModule;
import org.apache.atlas.TestUtils;
import org.apache.atlas.discovery.graph.GraphBackedDiscoveryService;
import org.apache.atlas.query.QueryParams;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.MetadataRepository;
import org.apache.atlas.repository.RepositoryException;
import org.apache.atlas.repository.graphdb.AtlasEdge;
import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
import org.apache.atlas.repository.graphdb.AtlasVertex;
import org.apache.atlas.type.AtlasTypeRegistry;
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.exception.TraitNotFoundException;
import org.apache.atlas.typesystem.persistence.AtlasSystemAttributes;
import org.apache.atlas.typesystem.persistence.Id;
import org.apache.atlas.typesystem.types.AttributeDefinition;
import org.apache.atlas.typesystem.types.ClassType;
import org.apache.atlas.typesystem.types.DataTypes;
import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition;
import org.apache.atlas.typesystem.types.Multiplicity;
import org.apache.atlas.typesystem.types.TraitType;
import org.apache.atlas.typesystem.types.TypeSystem;
import org.apache.atlas.typesystem.types.utils.TypesUtil;
import org.apache.commons.lang.RandomStringUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import static org.apache.atlas.typesystem.types.utils.TypesUtil.createClassTypeDef;
import static org.apache.atlas.typesystem.types.utils.TypesUtil.createUniqueRequiredAttrDef;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;

/**
 * GraphBackedMetadataRepository test
 *
 * Guice loads the dependencies and injects the necessary objects
 *
 */
@Guice(modules = TestOnlyModule.class)
public class GraphBackedMetadataRepositoryTest {

    @Inject
    private MetadataRepository repositoryService;

    @Inject
    private GraphBackedDiscoveryService discoveryService;

    private TypeSystem typeSystem;
    private String guid;
    private QueryParams queryParams = new QueryParams(100, 0);

    @BeforeClass
    public void setUp() throws Exception {
        typeSystem = TypeSystem.getInstance();
        typeSystem.reset();

        assertTrue(repositoryService instanceof GraphBackedMetadataRepository);
        repositoryService = TestUtils.addTransactionWrapper(repositoryService);
        new GraphBackedSearchIndexer(new AtlasTypeRegistry());

        TestUtils.defineDeptEmployeeTypes(typeSystem);
        TestUtils.createHiveTypes(typeSystem);
    }

    @BeforeMethod
    public void setupContext() {
        TestUtils.resetRequestContext();
    }

    @AfterClass
    public void tearDown() throws Exception {
        TypeSystem.getInstance().reset();
        AtlasGraphProvider.cleanup();
    }

    @Test
    //In some cases of parallel APIs, the edge is added, but get edge by label doesn't return the edge. ATLAS-1104
    public void testConcurrentCalls() throws Exception {
        final HierarchicalTypeDefinition<ClassType> refType =
                createClassTypeDef(randomString(), ImmutableSet.<String>of());
        HierarchicalTypeDefinition<ClassType> type =
                createClassTypeDef(randomString(), ImmutableSet.<String>of(),
                        new AttributeDefinition("ref", refType.typeName, Multiplicity.OPTIONAL, true, null));
        typeSystem.defineClassType(refType);
        typeSystem.defineClassType(type);

        String refId1 = createEntity(new Referenceable(refType.typeName)).get(0);
        String refId2 = createEntity(new Referenceable(refType.typeName)).get(0);

        final Referenceable instance1 = new Referenceable(type.typeName);
        instance1.set("ref", new Referenceable(refId1, refType.typeName, null));

        final Referenceable instance2 = new Referenceable(type.typeName);
        instance2.set("ref", new Referenceable(refId2, refType.typeName, null));

        ExecutorService executor = Executors.newFixedThreadPool(3);
        List<Future<Object>> futures = new ArrayList<>();
        futures.add(executor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                return createEntity(instance1).get(0);
            }
        }));
        futures.add(executor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                return createEntity(instance2).get(0);
            }
        }));
        futures.add(executor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                return discoveryService.searchByDSL(TestUtils.TABLE_TYPE, new QueryParams(10, 0));
            }
        }));

        String id1 = (String) futures.get(0).get();
        String id2 = (String) futures.get(1).get();
        futures.get(2).get();
        executor.shutdown();

        boolean validated1 = assertEdge(id1, type.typeName);
        boolean validated2 = assertEdge(id2, type.typeName);
        assertTrue(validated1 | validated2);
    }

    private boolean assertEdge(String id, String typeName) throws Exception {
        AtlasGraph graph = TestUtils.getGraph();
        Iterable<AtlasVertex> vertices = graph.query().has(Constants.GUID_PROPERTY_KEY, id).vertices();
        AtlasVertex AtlasVertex = vertices.iterator().next();
        Iterable<AtlasEdge> edges = AtlasVertex.getEdges(AtlasEdgeDirection.OUT, Constants.INTERNAL_PROPERTY_KEY_PREFIX + typeName + ".ref");
        if (!edges.iterator().hasNext()) {
            ITypedReferenceableInstance entity = repositoryService.getEntityDefinition(id);
            assertNotNull(entity.get("ref"));
            return true;
        }
        return false;
    }

    @Test
    public void testSubmitEntity() throws Exception {
        ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem);

        List<String> guids = repositoryService.createEntities(hrDept).getCreatedEntities();
        Assert.assertNotNull(guids);
        Assert.assertEquals(guids.size(), 5);
        guid = guids.get(4);
        Assert.assertNotNull(guid);
    }

    @Test
    public void testCreateEntityWithOneNestingLevel() throws AtlasException {

        List<Referenceable> toValidate = new ArrayList<>();
        Referenceable dept = new Referenceable(TestUtils.DEPARTMENT_TYPE);
        toValidate.add(dept);
        dept.set(TestUtils.NAME, "test1");

        Referenceable mike = new Referenceable(TestUtils.PERSON_TYPE);
        toValidate.add(mike);

        mike.set(TestUtils.NAME, "Mike");
        mike.set(TestUtils.DEPARTMENT_ATTR, dept);

        Referenceable mark = new Referenceable(TestUtils.PERSON_TYPE);
        toValidate.add(mark);
        mark.set(TestUtils.NAME, "Mark");
        mark.set(TestUtils.DEPARTMENT_ATTR, dept);

        dept.set(TestUtils.EMPLOYEES_ATTR, ImmutableList.of(mike, mark));
        Map<String,Referenceable> positions = new HashMap<>();
        final String JANITOR = "janitor";
        final String RECEPTIONIST = "receptionist";
        positions.put(JANITOR, mike);
        positions.put(RECEPTIONIST, mark);
        dept.set(TestUtils.POSITIONS_ATTR, positions);


        ClassType deptType = TypeSystem.getInstance().getDataType(ClassType.class, TestUtils.DEPARTMENT_TYPE);
        ITypedReferenceableInstance deptInstance = deptType.convert(dept, Multiplicity.REQUIRED);

        CreateUpdateEntitiesResult result = repositoryService.createEntities(deptInstance);

        validateGuidMapping(toValidate, result);
    }


    @Test
    public void testCreateEntityWithTwoNestingLevels() throws AtlasException {

        List<Referenceable> toVerify = new ArrayList<>();
        Referenceable dept = new Referenceable(TestUtils.DEPARTMENT_TYPE);
        toVerify.add(dept);
        dept.set(TestUtils.NAME, "test2");

        Referenceable wallace = new Referenceable(TestUtils.PERSON_TYPE);
        toVerify.add(wallace);
        wallace.set(TestUtils.NAME, "Wallace");
        wallace.set(TestUtils.DEPARTMENT_ATTR, dept);

        Referenceable wallaceComputer = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(wallaceComputer);
        wallaceComputer.set("name", "wallaceComputer");
        wallace.set(TestUtils.ASSETS_ATTR, ImmutableList.of(wallaceComputer));

        Referenceable jordan = new Referenceable(TestUtils.PERSON_TYPE);
        toVerify.add(jordan);
        jordan.set(TestUtils.NAME, "Jordan");
        jordan.set(TestUtils.DEPARTMENT_ATTR, dept);

        Referenceable jordanComputer = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(jordanComputer);
        jordanComputer.set("name", "jordanComputer");
        jordan.set(TestUtils.ASSETS_ATTR, ImmutableList.of(jordanComputer));

        dept.set(TestUtils.EMPLOYEES_ATTR, ImmutableList.of(wallace, jordan));
        Map<String,Referenceable> positions = new HashMap<>();
        final String JANITOR = "janitor";
        final String RECEPTIONIST = "receptionist";
        positions.put(JANITOR, wallace);
        positions.put(RECEPTIONIST, jordan);
        dept.set(TestUtils.POSITIONS_ATTR, positions);


        ClassType deptType = TypeSystem.getInstance().getDataType(ClassType.class, TestUtils.DEPARTMENT_TYPE);
        ITypedReferenceableInstance deptInstance = deptType.convert(dept, Multiplicity.REQUIRED);

        CreateUpdateEntitiesResult result = repositoryService.createEntities(deptInstance);
        validateGuidMapping(toVerify, result);
    }


    @Test
    public void testCreateEntityWithThreeNestingLevels() throws AtlasException {

        List<Referenceable> toVerify = new ArrayList<>();

        Referenceable dept = new Referenceable(TestUtils.DEPARTMENT_TYPE);
        toVerify.add(dept);
        dept.set(TestUtils.NAME, "test3");

        Referenceable barry = new Referenceable(TestUtils.PERSON_TYPE);
        toVerify.add(barry);
        barry.set(TestUtils.NAME, "barry");
        barry.set(TestUtils.DEPARTMENT_ATTR, dept);

        Referenceable barryComputer = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(barryComputer);
        barryComputer.set("name", "barryComputer");
        barry.set(TestUtils.ASSETS_ATTR, ImmutableList.of(barryComputer));

        Referenceable barryHardDrive = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(barryHardDrive);
        barryHardDrive.set("name", "barryHardDrive");

        Referenceable barryCpuFan = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(barryCpuFan);
        barryCpuFan.set("name", "barryCpuFan");

        Referenceable barryVideoCard = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(barryVideoCard);
        barryVideoCard.set("name", "barryVideoCard");

        barryComputer.set("childAssets", ImmutableList.of(barryHardDrive, barryVideoCard, barryCpuFan));


        Referenceable jacob = new Referenceable(TestUtils.PERSON_TYPE);
        toVerify.add(jacob);
        jacob.set(TestUtils.NAME, "jacob");
        jacob.set(TestUtils.DEPARTMENT_ATTR, dept);

        Referenceable jacobComputer = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(jacobComputer);
        jacobComputer.set("name", "jacobComputer");
        jacob.set(TestUtils.ASSETS_ATTR, ImmutableList.of(jacobComputer));

        Referenceable jacobHardDrive = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(jacobHardDrive);
        jacobHardDrive.set("name", "jacobHardDrive");

        Referenceable jacobCpuFan = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(jacobCpuFan);
        jacobCpuFan.set("name", "jacobCpuFan");

        Referenceable jacobVideoCard = new Referenceable(TestUtils.ASSET_TYPE);
        toVerify.add(jacobVideoCard);
        jacobVideoCard.set("name", "jacobVideoCard");

        jacobComputer.set("childAssets", ImmutableList.of(jacobHardDrive, jacobVideoCard, jacobCpuFan));

        dept.set(TestUtils.EMPLOYEES_ATTR, ImmutableList.of(barry, jacob));
        Map<String,Referenceable> positions = new HashMap<>();
        final String JANITOR = "janitor";
        final String RECEPTIONIST = "receptionist";
        positions.put(JANITOR, barry);
        positions.put(RECEPTIONIST, jacob);
        dept.set(TestUtils.POSITIONS_ATTR, positions);


        ClassType deptType = TypeSystem.getInstance().getDataType(ClassType.class, TestUtils.DEPARTMENT_TYPE);
        ITypedReferenceableInstance deptInstance = deptType.convert(dept, Multiplicity.REQUIRED);

        CreateUpdateEntitiesResult result = repositoryService.createEntities(deptInstance);

        assertEquals(result.getCreatedEntities().size(), toVerify.size());

        validateGuidMapping(toVerify, result);
    }

    private void validateGuidMapping(List<Referenceable> toVerify, CreateUpdateEntitiesResult result)
            throws AtlasException {
        Map<String,String> guids = result.getGuidMapping().getGuidAssignments();

        TestUtils.assertContentsSame(result.getCreatedEntities(), guids.values());
        assertEquals(guids.size(), toVerify.size());
        for(Referenceable r : toVerify) {
            loadAndDoSimpleValidation(guids.get(r.getId()._getId()), r);
        }
    }

    private ITypedReferenceableInstance loadAndDoSimpleValidation(String guid, Referenceable inst) throws AtlasException {
        return TestUtils.loadAndDoSimpleValidation(guid, inst, repositoryService);
    }


    @Test(dependsOnMethods = "testSubmitEntity")
    public void testGetEntityDefinitionForDepartment() throws Exception {
        ITypedReferenceableInstance entity = repositoryService.getEntityDefinition(guid);
        Assert.assertNotNull(entity);

        //entity state should be active by default
        Assert.assertEquals(entity.getId().getState(), Id.EntityState.ACTIVE);

        //System attributes created time and modified time should not be null
        AtlasSystemAttributes systemAttributes = entity.getSystemAttributes();
        Assert.assertNotNull(systemAttributes.createdTime);
        Assert.assertNotNull(systemAttributes.modifiedTime);
    }

    @Test(expectedExceptions = EntityNotFoundException.class)
    public void testGetEntityDefinitionNonExistent() throws Exception {
        repositoryService.getEntityDefinition("blah");
        Assert.fail();
    }

    @Test(dependsOnMethods = "testSubmitEntity")
    public void testGetEntityList() throws Exception {
        List<String> entityList = repositoryService.getEntityList(TestUtils.DEPARTMENT_TYPE);
        System.out.println("entityList = " + entityList);
        Assert.assertNotNull(entityList);
        Assert.assertTrue(entityList.contains(guid));
    }

    @Test
    public void testGetTypeAttributeName() throws Exception {
        Assert.assertEquals(repositoryService.getTypeAttributeName(), Constants.ENTITY_TYPE_PROPERTY_KEY);
    }

    @Test(dependsOnMethods = "testSubmitEntity")
    public void testGetTraitLabel() throws Exception {
        Assert.assertEquals(
                repositoryService.getTraitLabel(typeSystem.getDataType(ClassType.class, TestUtils.TABLE_TYPE),
                        TestUtils.CLASSIFICATION), TestUtils.CLASSIFICATION);
    }

    @Test
    public void testCreateEntity() throws Exception {
        Referenceable databaseInstance = new Referenceable(TestUtils.DATABASE_TYPE);
        databaseInstance.set("name", TestUtils.DATABASE_NAME);
        databaseInstance.set("description", "foo database");
        databaseInstance.set("created", new Date(TestUtils.TEST_DATE_IN_LONG));

        databaseInstance.set("namespace", "colo:cluster:hive:db");
        databaseInstance.set("cluster", "cluster-1");
        databaseInstance.set("colo", "colo-1");
        System.out.println("databaseInstance = " + databaseInstance);

        ClassType dbType = typeSystem.getDataType(ClassType.class, TestUtils.DATABASE_TYPE);
        ITypedReferenceableInstance db = dbType.convert(databaseInstance, Multiplicity.REQUIRED);
        System.out.println("db = " + db);

        //Reuse the same database instance without id, with the same unique attribute
        ITypedReferenceableInstance table = createHiveTableInstance(databaseInstance);
        List<String> guids = createEntities(db, table);
        Assert.assertEquals(guids.size(), 7);   //1 db + 5 columns + 1 table. Shouldn't create db again
        System.out.println("added db = " + guids.get(0));
        System.out.println("added table = " + guids.get(6));
    }

    @Test(dependsOnMethods = "testCreateEntity")
    public void testGetEntityDefinition() throws Exception {
        String guid = getGUID();

        ITypedReferenceableInstance table = repositoryService.getEntityDefinition(guid);
        Assert.assertEquals(table.getDate("created"), new Date(TestUtils.TEST_DATE_IN_LONG));
        System.out.println("*** table = " + table);
    }

    private List<String> createEntities(ITypedReferenceableInstance... instances) throws Exception {
        RequestContext.createContext();
        return repositoryService.createEntities(instances).getCreatedEntities();
    }

    private List<String> createEntity(Referenceable entity) throws Exception {
        ClassType type = typeSystem.getDataType(ClassType.class, entity.getTypeName());
        ITypedReferenceableInstance instance = type.convert(entity, Multiplicity.REQUIRED);
        return createEntities(instance);
    }

    @GraphTransaction
    String getGUID() {
        AtlasVertex tableVertex = getTableEntityVertex();

        String guid = GraphHelper.getSingleValuedProperty(tableVertex, Constants.GUID_PROPERTY_KEY, String.class);
        if (guid == null) {
            Assert.fail();
        }
        return guid;
    }

    @GraphTransaction
    AtlasVertex getTableEntityVertex() {
        AtlasGraph graph = TestUtils.getGraph();
        AtlasGraphQuery query = graph.query().has(Constants.ENTITY_TYPE_PROPERTY_KEY, ComparisionOperator.EQUAL, TestUtils.TABLE_TYPE);
        Iterator<AtlasVertex> results = query.vertices().iterator();
        // returning one since guid should be unique
        AtlasVertex tableVertex = results.hasNext() ? results.next() : null;
        if (tableVertex == null) {
            Assert.fail();
        }

        return tableVertex;
    }

    @Test(dependsOnMethods = "testCreateEntity")
    public void testGetTraitNames() throws Exception {
        final List<String> traitNames = repositoryService.getTraitNames(getGUID());
        Assert.assertEquals(traitNames.size(), 1);
        Assert.assertEquals(traitNames, Arrays.asList(new String[]{TestUtils.CLASSIFICATION}));
    }

    @Test
    public void testGetTraitNamesForEmptyTraits() throws Exception {
        final List<String> traitNames = repositoryService.getTraitNames(guid);
        Assert.assertEquals(traitNames.size(), 0);
    }

    @Test(expectedExceptions = EntityNotFoundException.class)
    public void testGetTraitNamesForBadEntity() throws Exception {
        repositoryService.getTraitNames(UUID.randomUUID().toString());
        Assert.fail();
    }

    @Test
    public void testMultipleTypesWithSameUniqueAttribute() throws Exception {
        //Two entities of different types(with same supertype that has the unique attribute) with same qualified name should succeed
        HierarchicalTypeDefinition<ClassType> supertype =
                createClassTypeDef(randomString(), ImmutableSet.<String>of(),
                        createUniqueRequiredAttrDef("name", DataTypes.STRING_TYPE));
        HierarchicalTypeDefinition<ClassType> t1 =
                createClassTypeDef(randomString(), ImmutableSet.of(supertype.typeName));
        HierarchicalTypeDefinition<ClassType> t2 =
                createClassTypeDef(randomString(), ImmutableSet.of(supertype.typeName));
        typeSystem.defineClassTypes(supertype, t1, t2);

        final String name = randomString();
        String id1 = createEntity(new Referenceable(t1.typeName) {{
            set("name", name);
        }}).get(0);
        String id2 = createEntity(new Referenceable(t2.typeName) {{
            set("name", name);
        }}).get(0);
        assertNotEquals(id1, id2);

        ITypedReferenceableInstance entity = repositoryService.getEntityDefinition(t1.typeName, "name", name);
        assertEquals(entity.getTypeName(), t1.typeName);
        assertEquals(entity.getId()._getId(), id1);

        entity = repositoryService.getEntityDefinition(t2.typeName, "name", name);
        assertEquals(entity.getTypeName(), t2.typeName);
        assertEquals(entity.getId()._getId(), id2);
    }

    @Test(dependsOnMethods = "testGetTraitNames")
    public void testAddTrait() throws Exception {
        final String aGUID = getGUID();
        AtlasVertex AtlasVertex = GraphHelper.getInstance().getVertexForGUID(aGUID);
        Long modificationTimestampPreUpdate = GraphHelper.getSingleValuedProperty(AtlasVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, Long.class);
        Assert.assertNotNull(modificationTimestampPreUpdate);

        List<String> traitNames = repositoryService.getTraitNames(aGUID);
        System.out.println("traitNames = " + traitNames);
        Assert.assertEquals(traitNames.size(), 1);
        Assert.assertTrue(traitNames.contains(TestUtils.CLASSIFICATION));
        Assert.assertFalse(traitNames.contains(TestUtils.PII));

        TraitType traitType = typeSystem.getDataType(TraitType.class, TestUtils.PII);
        ITypedStruct traitInstance = traitType.createInstance();

        repositoryService.addTrait(aGUID, traitInstance);

        // refresh trait names
        traitNames = repositoryService.getTraitNames(aGUID);
        Assert.assertEquals(traitNames.size(), 2);
        Assert.assertTrue(traitNames.contains(TestUtils.PII));
        Assert.assertTrue(traitNames.contains(TestUtils.CLASSIFICATION));

        // Verify modification timestamp was updated.
        GraphHelper.getInstance().getVertexForGUID(aGUID);
        Long modificationTimestampPostUpdate = GraphHelper.getSingleValuedProperty(AtlasVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, Long.class);
        Assert.assertNotNull(modificationTimestampPostUpdate);
    }

    @Test(dependsOnMethods = "testAddTrait")
    public void testAddTraitWithAttribute() throws Exception {
        final String aGUID = getGUID();
        final String traitName = "P_I_I";

        HierarchicalTypeDefinition<TraitType> piiTrait = TypesUtil
            .createTraitTypeDef(traitName, ImmutableSet.<String>of(),
                TypesUtil.createRequiredAttrDef("type", DataTypes.STRING_TYPE));
        TraitType traitType = typeSystem.defineTraitType(piiTrait);
        ITypedStruct traitInstance = traitType.createInstance();
        traitInstance.set("type", "SSN");

        repositoryService.addTrait(aGUID, traitInstance);

        TestUtils.dumpGraph(TestUtils.getGraph());

        // refresh trait names
        List<String> traitNames = repositoryService.getTraitNames(aGUID);
        Assert.assertEquals(traitNames.size(), 3);
        Assert.assertTrue(traitNames.contains(traitName));

        ITypedReferenceableInstance instance = repositoryService.getEntityDefinition(aGUID);
        IStruct traitInstanceRef = instance.getTrait(traitName);
        String type = (String) traitInstanceRef.get("type");
        Assert.assertEquals(type, "SSN");
    }

    @Test(expectedExceptions = NullPointerException.class)
    public void testAddTraitWithNullInstance() throws Exception {
        repositoryService.addTrait(getGUID(), null);
        Assert.fail();
    }

    @Test(dependsOnMethods = "testAddTrait", expectedExceptions = RepositoryException.class)
    public void testAddTraitForBadEntity() throws Exception {
        TraitType traitType = typeSystem.getDataType(TraitType.class, TestUtils.PII);
        ITypedStruct traitInstance = traitType.createInstance();

        repositoryService.addTrait(UUID.randomUUID().toString(), traitInstance);
        Assert.fail();
    }

    @Test(dependsOnMethods = "testAddTrait")
    public void testDeleteTrait() throws Exception {
        final String aGUID = getGUID();
        AtlasVertex AtlasVertex = GraphHelper.getInstance().getVertexForGUID(aGUID);
        Long modificationTimestampPreUpdate = GraphHelper.getSingleValuedProperty(AtlasVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, Long.class);
        Assert.assertNotNull(modificationTimestampPreUpdate);

        List<String> traitNames = repositoryService.getTraitNames(aGUID);
        Assert.assertEquals(traitNames.size(), 3);
        Assert.assertTrue(traitNames.contains(TestUtils.PII));
        Assert.assertTrue(traitNames.contains(TestUtils.CLASSIFICATION));
        Assert.assertTrue(traitNames.contains("P_I_I"));

        repositoryService.deleteTrait(aGUID, TestUtils.PII);

        // refresh trait names
        traitNames = repositoryService.getTraitNames(aGUID);
        Assert.assertEquals(traitNames.size(), 2);
        Assert.assertTrue(traitNames.contains(TestUtils.CLASSIFICATION));
        Assert.assertFalse(traitNames.contains(TestUtils.PII));

        // Verify modification timestamp was updated.
        GraphHelper.getInstance().getVertexForGUID(aGUID);
        Long modificationTimestampPostUpdate = GraphHelper.getSingleValuedProperty(AtlasVertex, Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY, Long.class);
        Assert.assertNotNull(modificationTimestampPostUpdate);
        Assert.assertTrue(modificationTimestampPostUpdate > modificationTimestampPreUpdate);
    }

    @Test(expectedExceptions = EntityNotFoundException.class)
    public void testDeleteTraitForNonExistentEntity() throws Exception {
        repositoryService.deleteTrait(UUID.randomUUID().toString(), TestUtils.PII);
        Assert.fail();
    }

    @Test(expectedExceptions = TraitNotFoundException.class)
    public void testDeleteTraitForNonExistentTrait() throws Exception {
        final String aGUID = getGUID();
        repositoryService.deleteTrait(aGUID, "PCI");
        Assert.fail();
    }

    @Test(dependsOnMethods = "testCreateEntity")
    public void testGetIdFromVertex() throws Exception {
        AtlasVertex tableVertex = getTableEntityVertex();

        String guid = GraphHelper.getSingleValuedProperty(tableVertex, Constants.GUID_PROPERTY_KEY, String.class);
        if (guid == null) {
            Assert.fail();
        }

        Id expected = new Id(guid, GraphHelper.getSingleValuedProperty(tableVertex, Constants.VERSION_PROPERTY_KEY, Integer.class), TestUtils.TABLE_TYPE);
        Assert.assertEquals(GraphHelper.getIdFromVertex(TestUtils.TABLE_TYPE, tableVertex), expected);
    }

    @Test(dependsOnMethods = "testCreateEntity")
    public void testGetTypeName() throws Exception {
        AtlasVertex tableVertex = getTableEntityVertex();
        Assert.assertEquals(GraphHelper.getTypeName(tableVertex), TestUtils.TABLE_TYPE);
    }

    @Test(dependsOnMethods = "testCreateEntity")
    public void testSearchByDSLQuery() throws Exception {
        String dslQuery = "hive_database as PII";
        System.out.println("Executing dslQuery = " + dslQuery);
        String jsonResults = discoveryService.searchByDSL(dslQuery, queryParams);
        Assert.assertNotNull(jsonResults);

        JSONObject results = new JSONObject(jsonResults);
        Assert.assertEquals(results.length(), 3);
        System.out.println("results = " + results);

        Object query = results.get("query");
        Assert.assertNotNull(query);

        JSONObject dataType = results.getJSONObject("dataType");
        Assert.assertNotNull(dataType);
        String typeName = dataType.getString("typeName");
        Assert.assertNotNull(typeName);

        JSONArray rows = results.getJSONArray("rows");
        Assert.assertNotNull(rows);
        Assert.assertTrue(rows.length() > 0);

        for (int index = 0; index < rows.length(); index++) {
            JSONObject row = rows.getJSONObject(index);
            String type = row.getString("$typeName$");
            Assert.assertEquals(type, "hive_database");

            String name = row.getString("name");
            Assert.assertEquals(name, TestUtils.DATABASE_NAME);
        }
    }

    @Test(dependsOnMethods = "testSubmitEntity")
    public void testSearchByDSLWithInheritance() throws Exception {
        String dslQuery = "Person where name = 'Jane'";
        System.out.println("Executing dslQuery = " + dslQuery);
        String jsonResults = discoveryService.searchByDSL(dslQuery, queryParams);
        Assert.assertNotNull(jsonResults);

        JSONObject results = new JSONObject(jsonResults);
        Assert.assertEquals(results.length(), 3);
        System.out.println("results = " + results);

        Object query = results.get("query");
        Assert.assertNotNull(query);

        JSONObject dataType = results.getJSONObject("dataType");
        Assert.assertNotNull(dataType);
        String typeName = dataType.getString("typeName");
        Assert.assertEquals(typeName, "Person");

        JSONArray rows = results.getJSONArray("rows");
        Assert.assertEquals(rows.length(), 1);

        JSONObject row = rows.getJSONObject(0);
        Assert.assertEquals(row.getString("$typeName$"), "Manager");
        Assert.assertEquals(row.getString("name"), "Jane");
    }

    @Test(dependsOnMethods = "testCreateEntity")
    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(TestUtils.getGraph());

        System.out.println("Executing dslQuery = " + dslQuery);
        String jsonResults = discoveryService.searchByDSL(dslQuery, queryParams);
        Assert.assertNotNull(jsonResults);

        JSONObject results = new JSONObject(jsonResults);
        Assert.assertEquals(results.length(), 3);
        System.out.println("results = " + results);

        Object query = results.get("query");
        Assert.assertNotNull(query);

        JSONObject dataType = results.getJSONObject("dataType");
        Assert.assertNotNull(dataType);

        JSONArray rows = results.getJSONArray("rows");
        Assert.assertEquals(rows.length(), 1);

    }

    /**
     * Full text search requires GraphBackedSearchIndexer, and GraphBackedSearchIndexer can't be enabled in
     * GraphBackedDiscoveryServiceTest because of its test data. So, test for full text search is in
     * GraphBackedMetadataRepositoryTest:(
     */
    @Test(dependsOnMethods = "testSubmitEntity")
    public void testFullTextSearch() throws Exception {
        //todo fix this
        //Weird: with lucene, the test passes without sleep
        //but with elasticsearch, doesn't work without sleep. why??
        long sleepInterval = 1000;

        TestUtils.dumpGraph(TestUtils.getGraph());

        //person in hr department whose name is john
        Thread.sleep(sleepInterval);
        String response = discoveryService.searchByFullText("john", queryParams);
        Assert.assertNotNull(response);
        JSONArray results = new JSONArray(response);
        Assert.assertEquals(results.length(), 1);
        JSONObject row = (JSONObject) results.get(0);
        Assert.assertEquals(row.get("typeName"), "Person");

        //person in hr department who lives in santa clara
        response = discoveryService.searchByFullText("Jane AND santa AND clara", queryParams);
        Assert.assertNotNull(response);
        results = new JSONArray(response);
        Assert.assertEquals(results.length(), 1);
        row = (JSONObject) results.get(0);
        Assert.assertEquals(row.get("typeName"), "Manager");

        //search for person in hr department whose name starts is john/jahn
        response = discoveryService.searchByFullText("hr AND (john OR jahn)", queryParams);
        Assert.assertNotNull(response);
        results = new JSONArray(response);
        Assert.assertEquals(results.length(), 1);
        row = (JSONObject) results.get(0);
        Assert.assertEquals(row.get("typeName"), "Person");

        //verify limit and offset
        //higher limit should return all results
        results = new JSONArray(discoveryService.searchByFullText("Department", queryParams));
        assertEquals(results.length(), 5);

        //smaller limit should return those many rows
        results = new JSONArray(discoveryService.searchByFullText("Department", new QueryParams(2, 0)));
        assertEquals(results.length(), 2);

        //offset should offset the results
        results = new JSONArray(discoveryService.searchByFullText("Department", new QueryParams(5, 2)));
        assertEquals(results.length(), 3);

        //higher offset shouldn't return any rows
        results = new JSONArray(discoveryService.searchByFullText("Department", new QueryParams(2, 6)));
        assertEquals(results.length(), 0);
    }

    private ITypedReferenceableInstance createHiveTableInstance(Referenceable databaseInstance) throws Exception {
        Referenceable tableInstance = new Referenceable(TestUtils.TABLE_TYPE, TestUtils.CLASSIFICATION);
        tableInstance.set("name", TestUtils.TABLE_NAME);
        tableInstance.set("description", "bar table");
        tableInstance.set("type", "managed");
        tableInstance.set("created", new Date(TestUtils.TEST_DATE_IN_LONG));
        tableInstance.set("tableType", 1); // enum

        // super type
        tableInstance.set("namespace", "colo:cluster:hive:db:table");
        tableInstance.set("cluster", "cluster-1");
        tableInstance.set("colo", "colo-1");

        // refer to an existing class
        tableInstance.set("database", databaseInstance);

        ArrayList<String> columnNames = new ArrayList<>();
        columnNames.add("first_name");
        columnNames.add("last_name");
        tableInstance.set("columnNames", columnNames);

        Struct traitInstance = (Struct) tableInstance.getTrait(TestUtils.CLASSIFICATION);
        traitInstance.set("tag", "foundation_etl");

        Struct serde1Instance = new Struct("serdeType");
        serde1Instance.set("name", "serde1");
        serde1Instance.set("serde", "serde1");
        tableInstance.set("serde1", serde1Instance);

        Struct serde2Instance = new Struct("serdeType");
        serde2Instance.set("name", "serde2");
        serde2Instance.set("serde", "serde2");
        tableInstance.set("serde2", serde2Instance);

        // HashMap<String, Referenceable> columnsMap = new HashMap<>();
        ArrayList<Referenceable> columns = new ArrayList<>();
        for (int index = 0; index < 5; index++) {
            Referenceable columnInstance = new Referenceable("column_type");
            final String name = "column_" + index;
            columnInstance.set("name", name);
            columnInstance.set("type", "string");

            columns.add(columnInstance);
            // columnsMap.put(name, columnInstance);
        }
        tableInstance.set("columns", columns);
        // tableInstance.set("columnsMap", columnsMap);

        //        HashMap<String, Struct> partitionsMap = new HashMap<>();
        ArrayList<Struct> partitions = new ArrayList<>();
        for (int index = 0; index < 5; index++) {
            Struct partitionInstance = new Struct(TestUtils.PARTITION_STRUCT_TYPE);
            final String name = "partition_" + index;
            partitionInstance.set("name", name);

            partitions.add(partitionInstance);
            //            partitionsMap.put(name, partitionInstance);
        }
        tableInstance.set("partitions", partitions);
        //        tableInstance.set("partitionsMap", partitionsMap);

        HashMap<String, String> parametersMap = new HashMap<>();
        parametersMap.put("foo", "bar");
        parametersMap.put("bar", "baz");
        parametersMap.put("some", "thing");
        tableInstance.set("parametersMap", parametersMap);

        ClassType tableType = typeSystem.getDataType(ClassType.class, TestUtils.TABLE_TYPE);
        return tableType.convert(tableInstance, Multiplicity.REQUIRED);
    }

    private String randomUTF() {
        return RandomStringUtils.random(10);
    }

    private String randomString() {
        return RandomStringUtils.randomAlphanumeric(10);
    }

    @Test
    public void testUTFValues() throws Exception {
        Referenceable hrDept = new Referenceable("Department");
        Referenceable john = new Referenceable("Person");
        john.set("name", randomUTF());
        john.set("department", hrDept);

        hrDept.set("name", randomUTF());
        hrDept.set("employees", ImmutableList.of(john));

        ClassType deptType = typeSystem.getDataType(ClassType.class, "Department");
        ITypedReferenceableInstance hrDept2 = deptType.convert(hrDept, Multiplicity.REQUIRED);

        List<String> guids = repositoryService.createEntities(hrDept2).getCreatedEntities();
        Assert.assertNotNull(guids);
        Assert.assertEquals(guids.size(), 2);
        Assert.assertNotNull(guids.get(0));
        Assert.assertNotNull(guids.get(1));
    }
}
