Repository: incubator-atlas
Updated Branches:
  refs/heads/master 758b3d4df -> 33d60746a


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/33d60746/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java 
b/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java
index 543cbe2..768ef12 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntitiesREST.java
@@ -18,19 +18,29 @@
 package org.apache.atlas.web.rest;
 
 import com.google.inject.Inject;
+import org.apache.atlas.AtlasClient;
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.AtlasException;
 import org.apache.atlas.exception.AtlasBaseException;
-import org.apache.atlas.model.SearchFilter;
-import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.AtlasEntityWithAssociations;
 import org.apache.atlas.model.instance.EntityMutationResponse;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
 import org.apache.atlas.services.MetadataService;
 import org.apache.atlas.type.AtlasTypeRegistry;
-import org.apache.atlas.typesystem.types.TypeSystem;
+import org.apache.atlas.typesystem.ITypedReferenceableInstance;
+import org.apache.atlas.web.adapters.AtlasFormatConverters;
+import org.apache.atlas.web.adapters.AtlasInstanceRestAdapters;
 import org.apache.atlas.web.util.Servlets;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static 
org.apache.atlas.web.adapters.AtlasInstanceRestAdapters.toAtlasBaseException;
+import static 
org.apache.atlas.web.adapters.AtlasInstanceRestAdapters.toEntityMutationResponse;
+
 import javax.inject.Singleton;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
@@ -42,6 +52,8 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 
@@ -58,14 +70,16 @@ public class EntitiesREST {
     @Inject
     private MetadataService metadataService;
 
-    private TypeSystem typeSystem = TypeSystem.getInstance();
-
+    private AtlasTypeRegistry typeRegistry;
 
+    @Inject
+    AtlasInstanceRestAdapters restAdapters;
 
     @Inject
     public EntitiesREST(AtlasEntityStore entitiesStore, AtlasTypeRegistry 
atlasTypeRegistry) {
         LOG.info("EntitiesRest Init");
         this.entitiesStore = entitiesStore;
+        this.typeRegistry = atlasTypeRegistry;
     }
 
     /*******
@@ -78,7 +92,17 @@ public class EntitiesREST {
     @Consumes(Servlets.JSON_MEDIA_TYPE)
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public EntityMutationResponse createOrUpdate(List<AtlasEntity> entities) 
throws AtlasBaseException {
-        return null;
+        EntityMutationResponse response = null;
+        ITypedReferenceableInstance[] entitiesInOldFormat = 
restAdapters.getITypedReferenceables(entities);
+
+        try {
+            final AtlasClient.EntityResult result = 
metadataService.updateEntities(entitiesInOldFormat);
+            response = toEntityMutationResponse(result);
+        } catch (AtlasException e) {
+            LOG.error("Exception while getting a typed reference for the 
entity ", e);
+            throw AtlasInstanceRestAdapters.toAtlasBaseException(e);
+        }
+        return response;
     }
 
     /*******
@@ -90,15 +114,35 @@ public class EntitiesREST {
     @Consumes(Servlets.JSON_MEDIA_TYPE)
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public EntityMutationResponse update(List<AtlasEntity> entities) throws 
AtlasBaseException {
-        return null;
+       return createOrUpdate(entities);
     }
 
     @GET
     @Path("/guids")
     @Consumes(Servlets.JSON_MEDIA_TYPE)
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse getById(@QueryParam("guid") List<String> 
guids) throws AtlasBaseException {
-        return null;
+    public AtlasEntity.AtlasEntities getById(@QueryParam("guid") List<String> 
guids) throws AtlasBaseException {
+
+        if (CollectionUtils.isEmpty(guids)) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guids);
+        }
+
+        AtlasEntity.AtlasEntities entities = new AtlasEntity.AtlasEntities();
+
+        List<AtlasEntity> entityList = new ArrayList<>();
+
+        for (String guid : guids) {
+            try {
+               ITypedReferenceableInstance ref = 
metadataService.getEntityDefinition(guid);
+               AtlasEntity entity = restAdapters.getAtlasEntity(ref);
+               entityList.add(entity);
+            } catch (AtlasException e) {
+                throw toAtlasBaseException(e);
+            }
+        }
+
+        entities.setList(entityList);
+        return entities;
     }
 
     /*******
@@ -109,8 +153,17 @@ public class EntitiesREST {
     @Path("/guids")
     @Consumes(Servlets.JSON_MEDIA_TYPE)
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse deleteById(@QueryParam("guid") List<String> 
guids) throws AtlasBaseException {
-        return null;
+    public EntityMutationResponse deleteById(@QueryParam("guid") final 
List<String> guids) throws AtlasBaseException {
+
+        if (CollectionUtils.isEmpty(guids)) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guids);
+        }
+        try {
+            AtlasClient.EntityResult result = 
metadataService.deleteEntities(guids);
+            return toEntityMutationResponse(result);
+        } catch (AtlasException e) {
+            throw toAtlasBaseException(e);
+        }
     }
 
     /**
@@ -120,8 +173,9 @@ public class EntitiesREST {
      */
     @GET
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public AtlasEntity.AtlasEntities searchEntities() throws 
AtlasBaseException {
+    public AtlasEntityHeader.AtlasEntityHeaders searchEntities() throws 
AtlasBaseException {
         //SearchFilter searchFilter
+        //TODO: Need to handle getEntitiesByType for older API
         return null;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/33d60746/webapp/src/main/java/org/apache/atlas/web/rest/EntityRest.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntityRest.java 
b/webapp/src/main/java/org/apache/atlas/web/rest/EntityRest.java
index df5138e..6bbc69c 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/EntityRest.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntityRest.java
@@ -17,10 +17,30 @@
  */
 package org.apache.atlas.web.rest;
 
+import com.google.inject.Inject;
+import org.apache.atlas.AtlasClient;
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntityWithAssociations;
 import org.apache.atlas.model.instance.EntityMutationResponse;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.services.MetadataService;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasType;
+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.web.adapters.AtlasInstanceRestAdapters;
 import org.apache.atlas.web.util.Servlets;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.inject.Singleton;
 import javax.ws.rs.Consumes;
@@ -33,17 +53,30 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
 import java.util.List;
 
+import static 
org.apache.atlas.web.adapters.AtlasInstanceRestAdapters.toAtlasBaseException;
+import static 
org.apache.atlas.web.adapters.AtlasInstanceRestAdapters.toEntityMutationResponse;
+
 /**
  * REST for a single entity
  */
 @Path("v2/entity")
 @Singleton
-public class EntityRest {
+public class EntityREST {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(EntityREST.class);
+
+    @Inject
+    AtlasTypeRegistry typeRegistry;
 
+    @Inject
+    AtlasInstanceRestAdapters restAdapters;
+
+    @Inject
+    private MetadataService metadataService;
     /**
      * Create or Update an entity if it  already exists
      *
@@ -53,8 +86,18 @@ public class EntityRest {
     @POST
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse createOrUpdate(AtlasEntity entity) {
-        return null;
+    public EntityMutationResponse createOrUpdate(final AtlasEntity entity) 
throws AtlasBaseException {
+        EntityMutationResponse response = null;
+        ITypedReferenceableInstance[] entitiesInOldFormat = 
restAdapters.getITypedReferenceables(new ArrayList<AtlasEntity>() {{ 
add(entity); }});
+
+        try {
+            final AtlasClient.EntityResult result = 
metadataService.updateEntities(entitiesInOldFormat);
+            response = toEntityMutationResponse(result);
+        } catch (AtlasException e) {
+            LOG.error("Exception while getting a typed reference for the 
entity ", e);
+            throw AtlasInstanceRestAdapters.toAtlasBaseException(e);
+        }
+        return response;
     }
 
     /**
@@ -68,8 +111,8 @@ public class EntityRest {
     @Path("guid/{guid}")
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse updateByGuid(@PathParam("guid") String guid, 
AtlasEntity entity, @DefaultValue("false") @QueryParam("partialUpdate") boolean 
partialUpdate) {
-        return null;
+    public EntityMutationResponse updateByGuid(@PathParam("guid") String guid, 
AtlasEntity entity, @DefaultValue("false") @QueryParam("partialUpdate") boolean 
partialUpdate) throws AtlasBaseException {
+        return createOrUpdate(entity);
     }
 
 
@@ -81,11 +124,35 @@ public class EntityRest {
     @GET
     @Path("/guid/{guid}")
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public AtlasEntity getByGuid(@PathParam("guid") String guid) {
-        return null;
+    public AtlasEntity getById(@PathParam("guid") String guid) throws 
AtlasBaseException {
+        try {
+            ITypedReferenceableInstance ref = 
metadataService.getEntityDefinition(guid);
+            return restAdapters.getAtlasEntity(ref);
+        } catch (AtlasException e) {
+            throw toAtlasBaseException(e);
+        }
+    }
+
+    /**
+     * Fetch the complete definition of an entity given its GUID including its 
associations
+     * like classifications, terms etc.
+     *
+     * @param guid GUID for the entity
+     */
+    @GET
+    @Path("/guid/{guid}/associations")
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public AtlasEntityWithAssociations 
getWithAssociationsByGuid(@PathParam("guid") String guid) throws 
AtlasBaseException {
+        try {
+            ITypedReferenceableInstance ref = 
metadataService.getEntityDefinition(guid);
+            return restAdapters.getAtlasEntity(ref);
+        } catch (AtlasException e) {
+            throw toAtlasBaseException(e);
+        }
     }
 
 
+
     /**
      * Delete an entity identified by its GUID
      *
@@ -96,8 +163,16 @@ public class EntityRest {
     @Path("guid/{guid}")
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public EntityMutationResponse deleteByGuid(@PathParam("guid") String guid) 
{
-        return null;
+    public EntityMutationResponse deleteByGuid(@PathParam("guid") final String 
guid) throws AtlasBaseException {
+        if (StringUtils.isEmpty(guid)) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        }
+        try {
+            AtlasClient.EntityResult result = 
metadataService.deleteEntities(new ArrayList<String>() {{ add(guid); }});
+            return toEntityMutationResponse(result);
+        } catch (AtlasException e) {
+            throw toAtlasBaseException(e);
+        }
     }
 
 
@@ -115,7 +190,13 @@ public class EntityRest {
     public EntityMutationResponse 
partialUpdateByUniqueAttribute(@PathParam("typeName") String entityType,
         @PathParam("attrName") String attribute,
         @QueryParam("value") String value, AtlasEntity entity) throws 
Exception {
-        return null;
+
+        AtlasEntityType type = (AtlasEntityType) validateType(entityType, 
TypeCategory.ENTITY);
+        validateUniqueAttribute(type, attribute);
+
+        Referenceable ref = restAdapters.getReferenceable(entity);
+        AtlasClient.EntityResult result = 
metadataService.updateEntityByUniqueAttribute(entityType, attribute, value, 
ref);
+        return toEntityMutationResponse(result);
     }
 
     @Deprecated
@@ -126,7 +207,12 @@ public class EntityRest {
     public EntityMutationResponse 
deleteByUniqueAttribute(@PathParam("typeName") String entityType,
         @PathParam("attrName") String attribute,
         @QueryParam("value") String value) throws Exception {
-        return null;
+
+        AtlasEntityType type = (AtlasEntityType) validateType(entityType, 
TypeCategory.ENTITY);
+        validateUniqueAttribute(type, attribute);
+
+        final AtlasClient.EntityResult result = 
metadataService.deleteEntityByUniqueAttribute(entityType, attribute, value);
+        return toEntityMutationResponse(result);
     }
 
     /**
@@ -140,8 +226,17 @@ public class EntityRest {
     @Path("/uniqueAttribute/type/{typeName}/attribute/{attrName}")
     public AtlasEntity getByUniqueAttribute(@PathParam("typeName") String 
entityType,
         @PathParam("attrName") String attribute,
-        @QueryParam("value") String value) {
-        return null;
+        @QueryParam("value") String value) throws AtlasBaseException {
+
+        AtlasEntityType type = (AtlasEntityType) validateType(entityType, 
TypeCategory.ENTITY);
+        validateUniqueAttribute(type, attribute);
+
+        try {
+            final ITypedReferenceableInstance entityDefinitionReference = 
metadataService.getEntityDefinitionReference(entityType, attribute, value);
+            return restAdapters.getAtlasEntity(entityDefinitionReference);
+        } catch (AtlasException e) {
+            throw toAtlasBaseException(e);
+        }
     }
 
 
@@ -154,8 +249,21 @@ public class EntityRest {
     @GET
     @Path("/guid/{guid}/classification/{classificationName}")
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public AtlasClassification.AtlasClassifications 
getClassification(@PathParam("guid") String guid, 
@PathParam("classificationName") String classificationName) {
-        return null;
+    public AtlasClassification getClassification(@PathParam("guid") String 
guid, @PathParam("classificationName") String classificationName) throws 
AtlasBaseException {
+
+        if (StringUtils.isEmpty(guid)) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        }
+
+        validateType(classificationName, TypeCategory.CLASSIFICATION);
+
+        try {
+            IStruct trait = metadataService.getTraitDefinition(guid, 
classificationName);
+            return restAdapters.getClassification(trait);
+
+        } catch (AtlasException e) {
+            throw toAtlasBaseException(e);
+        }
     }
 
 
@@ -168,8 +276,28 @@ public class EntityRest {
     @GET
     @Path("/guid/{guid}/classifications")
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public AtlasClassification.AtlasClassifications 
getClassifications(@PathParam("guid") String guid) {
-        return null;
+    public AtlasClassification.AtlasClassifications 
getClassifications(@PathParam("guid") String guid) throws AtlasBaseException {
+
+        if (StringUtils.isEmpty(guid)) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        }
+
+        AtlasClassification.AtlasClassifications clss = new 
AtlasClassification.AtlasClassifications();
+
+        try {
+            List<AtlasClassification> clsList = new ArrayList<>();
+            for ( String traitName : metadataService.getTraitNames(guid) ) {
+                IStruct trait = metadataService.getTraitDefinition(guid, 
traitName);
+                AtlasClassification cls = 
restAdapters.getClassification(trait);
+                clsList.add(cls);
+            }
+
+            clss.setList(clsList);
+
+        } catch (AtlasException e) {
+            throw toAtlasBaseException(e);
+        }
+        return clss;
     }
 
     /**
@@ -185,7 +313,20 @@ public class EntityRest {
     @Path("/guid/{guid}/classifications")
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public void addClassifications(@PathParam("guid") final String guid, 
List<AtlasClassification> classifications) {
+    public void addClassifications(@PathParam("guid") final String guid, 
List<AtlasClassification> classifications) throws AtlasBaseException {
+
+        if (StringUtils.isEmpty(guid)) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        }
+
+        for (AtlasClassification classification:  classifications) {
+            final ITypedStruct trait = restAdapters.getTrait(classification);
+            try {
+                metadataService.addTrait(guid, trait);
+            } catch (AtlasException e) {
+                throw toAtlasBaseException(e);
+            }
+        }
     }
 
     /**
@@ -198,7 +339,12 @@ public class EntityRest {
     @Path("/guid/{guid}/classifications")
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public void updateClassifications(@PathParam("guid") final String guid, 
List<AtlasClassification> classifications) {
+    public void updateClassifications(@PathParam("guid") final String guid, 
List<AtlasClassification> classifications) throws AtlasBaseException {
+        //Not supported in old API
+
+        if (StringUtils.isEmpty(guid)) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        }
     }
 
     /**
@@ -212,6 +358,43 @@ public class EntityRest {
     @Consumes({Servlets.JSON_MEDIA_TYPE, MediaType.APPLICATION_JSON})
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public void deleteClassification(@PathParam("guid") String guid,
-        @PathParam("classificationName") String classificationName) {
+        @PathParam("classificationName") String classificationName) throws 
AtlasBaseException {
+
+        if (StringUtils.isEmpty(guid)) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        }
+
+        validateType(classificationName, TypeCategory.CLASSIFICATION);
+
+        try {
+            metadataService.deleteTrait(guid, classificationName);
+        } catch (AtlasException e) {
+            throw toAtlasBaseException(e);
+        }
+    }
+
+    private AtlasType validateType(String entityType, TypeCategory 
expectedCategory) throws AtlasBaseException {
+        if ( StringUtils.isEmpty(entityType) ) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, 
entityType);
+        }
+
+        AtlasType type = typeRegistry.getType(entityType);
+        if (type.getTypeCategory() != expectedCategory) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_CATEGORY_INVALID, 
type.getTypeCategory().name(), expectedCategory.name());
+        }
+
+        return type;
+    }
+
+    /**
+     * Validate that attribute is unique attribute
+     * @param entityType     the entity type
+     * @param attributeName  the name of the attribute
+     */
+    private void validateUniqueAttribute(AtlasEntityType entityType, String 
attributeName) throws AtlasBaseException {
+        AtlasStructDef.AtlasAttributeDef attribute = 
entityType.getAttributeDef(attributeName);
+        if (!attribute.getIsUnique()) {
+            throw new 
AtlasBaseException(AtlasErrorCode.ATTRIBUTE_UNIQUE_INVALID, 
entityType.getTypeName(), attributeName);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/33d60746/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
new file mode 100644
index 0000000..f8e18bf
--- /dev/null
+++ b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntitiesREST.java
@@ -0,0 +1,216 @@
+/**
+ * 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 com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.atlas.AtlasClient;
+import org.apache.atlas.RepositoryMetadataModule;
+import org.apache.atlas.RequestContext;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+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.AtlasTypesDef;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.web.rest.EntitiesREST;
+
+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.AfterClass;
+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.List;
+import java.util.Map;
+
+@Guice(modules = {AtlasFormatConvertersModule.class, 
RepositoryMetadataModule.class})
+public class TestEntitiesREST {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(TestEntitiesREST.class);
+
+    @Inject
+    private AtlasTypeDefStore typeStore;
+
+    @Inject
+    private EntitiesREST entitiesREST;
+
+    private List<String> createdGuids = new ArrayList<>();
+
+    private AtlasEntity dbEntity;
+
+    private AtlasEntity tableEntity;
+
+    private List<AtlasEntity> columns;
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        AtlasTypesDef typesDef = TestUtilsV2.defineHiveTypes();
+        typeStore.createTypesDef(typesDef);
+        dbEntity = TestUtilsV2.createDBEntity();
+
+        tableEntity = TestUtilsV2.createTableEntity(dbEntity.getGuid());
+        final AtlasEntity colEntity = TestUtilsV2.createColumnEntity();
+        columns = new ArrayList<AtlasEntity>() {{ add(colEntity); }};
+        tableEntity.setAttribute("columns", columns);
+    }
+
+    @AfterMethod
+    public void cleanup() throws Exception {
+        RequestContext.clear();
+    }
+
+    @AfterClass
+    public void tearDown() throws Exception {
+        AtlasGraphProvider.cleanup();
+    }
+
+    @Test
+    public void testCreateOrUpdateEntities() throws Exception {
+        List<AtlasEntity> entities = new ArrayList<AtlasEntity>();
+        entities.add(dbEntity);
+        entities.add(tableEntity);
+
+        EntityMutationResponse response = 
entitiesREST.createOrUpdate(entities);
+        List<AtlasEntityHeader> guids = 
response.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE_OR_UPDATE);
+
+        Assert.assertNotNull(guids);
+        Assert.assertEquals(guids.size(), 3);
+
+        for (AtlasEntityHeader header : guids) {
+            createdGuids.add(header.getGuid());
+        }
+    }
+
+    @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.getGuid());
+        final AtlasEntity colEntity = TestUtilsV2.createColumnEntity();
+        List<AtlasEntity> columns = new ArrayList<AtlasEntity>() {{ 
add(colEntity); }};
+        tableEntity.setAttribute("columns", columns);
+
+        AtlasEntity newDBEntity = serDeserEntity(dbEntity);
+        AtlasEntity newTableEntity = serDeserEntity(tableEntity);
+
+        List<AtlasEntity> newEntities = new ArrayList<AtlasEntity>();
+        newEntities.add(newDBEntity);
+        newEntities.add(newTableEntity);
+        EntityMutationResponse response2 = 
entitiesREST.createOrUpdate(newEntities);
+
+        List<AtlasEntityHeader> newGuids = 
response2.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE_OR_UPDATE);
+        Assert.assertNotNull(newGuids);
+        Assert.assertEquals(newGuids.size(), 3);
+    }
+
+    @Test(dependsOnMethods = "testCreateOrUpdateEntities")
+    public void testGetEntities() throws Exception {
+
+        final AtlasEntity.AtlasEntities response = 
entitiesREST.getById(createdGuids);
+        final List<AtlasEntity> entities = response.getList();
+
+        Assert.assertNotNull(entities);
+        Assert.assertEquals(entities.size(), 3);
+        verifyAttributes(entities);
+    }
+
+    @Test(dependsOnMethods = "testGetEntities")
+    public void testDeleteEntities() throws Exception {
+
+        final EntityMutationResponse response = 
entitiesREST.deleteById(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(dbEntity.getAttributes(), 
retrievedDBEntity.getAttributes());
+        }
+
+        if ( retrievedColumnEntity != null) {
+            LOG.info("verifying entity of type {} ", 
columns.get(0).getTypeName());
+            verifyAttributes(columns.get(0).getAttributes(), 
retrievedColumnEntity.getAttributes());
+        }
+
+        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<AtlasEntity>) 
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> sourceAttrs, 
Map<String, Object> targetAttributes) throws Exception {
+        for (String name : sourceAttrs.keySet() ) {
+            LOG.info("verifying attribute {} ", name);
+            Assert.assertEquals(targetAttributes.get(name), 
sourceAttrs.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
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, 
false);
+        String entityJson = mapper.writeValueAsString(entity);
+        //JSON from String to Object
+        AtlasEntity newEntity = mapper.readValue(entityJson, 
AtlasEntity.class);
+        return newEntity;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/33d60746/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java
----------------------------------------------------------------------
diff --git 
a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java 
b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java
new file mode 100644
index 0000000..6dd21d1
--- /dev/null
+++ b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityREST.java
@@ -0,0 +1,181 @@
+/**
+ * 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.RepositoryMetadataModule;
+import org.apache.atlas.RequestContext;
+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.AtlasEntityHeader;
+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.model.typedef.AtlasTypesDef;
+import org.apache.atlas.repository.graph.AtlasGraphProvider;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.web.rest.EntityREST;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+import org.testng.internal.Invoker;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+@Guice(modules = {AtlasFormatConvertersModule.class, 
RepositoryMetadataModule.class})
+public class TestEntityREST {
+
+    @Inject
+    private AtlasTypeDefStore typeStore;
+
+    @Inject
+    private EntityREST entityREST;
+
+    private AtlasEntity dbEntity;
+
+    private String dbGuid;
+
+    private AtlasClassification testClassification;
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        AtlasTypesDef typesDef = TestUtilsV2.defineHiveTypes();
+        typeStore.createTypesDef(typesDef);
+        dbEntity = TestUtilsV2.createDBEntity();
+    }
+
+    @AfterClass
+    public void tearDown() throws Exception {
+        AtlasGraphProvider.cleanup();
+    }
+
+    @AfterMethod
+    public void cleanup() throws Exception {
+        RequestContext.clear();
+    }
+
+    @Test
+    public void testCreateOrUpdateEntity() throws Exception {
+        final EntityMutationResponse response = 
entityREST.createOrUpdate(dbEntity);
+
+        Assert.assertNotNull(response);
+        List<AtlasEntityHeader> entitiesMutated = 
response.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE_OR_UPDATE);
+
+        Assert.assertNotNull(entitiesMutated);
+        Assert.assertEquals(entitiesMutated.size(), 1);
+        Assert.assertNotNull(entitiesMutated.get(0));
+        dbGuid = entitiesMutated.get(0).getGuid();
+        Assert.assertEquals(entitiesMutated.size(), 1);
+    }
+
+    @Test(dependsOnMethods = "testCreateOrUpdateEntity")
+    public void testGetEntityById() throws Exception {
+
+        final AtlasEntity response = entityREST.getById(dbGuid);
+
+        Assert.assertNotNull(response);
+        TestEntitiesREST.verifyAttributes(response.getAttributes(), 
dbEntity.getAttributes());
+    }
+
+    @Test(dependsOnMethods = "testCreateOrUpdateEntity")
+    public void  testAddAndGetClassification() throws Exception {
+
+        List<AtlasClassification> classifications = new ArrayList<>();
+        testClassification = new 
AtlasClassification(TestUtilsV2.CLASSIFICATION, new HashMap<String, Object>() 
{{ put("tag", "tagName"); }});
+        classifications.add(testClassification);
+        entityREST.addClassifications(dbGuid, classifications);
+
+        final AtlasClassification.AtlasClassifications 
retrievedClassifications = entityREST.getClassifications(dbGuid);
+        Assert.assertNotNull(retrievedClassifications);
+        final List<AtlasClassification> retrievedClassificationsList = 
retrievedClassifications.getList();
+        Assert.assertNotNull(retrievedClassificationsList);
+
+        Assert.assertEquals(classifications, retrievedClassificationsList);
+
+        final AtlasClassification retrievedClassification = 
entityREST.getClassification(dbGuid, TestUtilsV2.CLASSIFICATION);
+
+        Assert.assertNotNull(retrievedClassification);
+        Assert.assertEquals(retrievedClassification, testClassification);
+
+    }
+
+    @Test(dependsOnMethods = "testAddAndGetClassification")
+    public void  testGetEntityWithAssociations() throws Exception {
+
+        AtlasEntityWithAssociations entity = 
entityREST.getWithAssociationsByGuid(dbGuid);
+        final List<AtlasClassification> retrievedClassifications = 
entity.getClassifications();
+
+        Assert.assertNotNull(retrievedClassifications);
+        Assert.assertEquals(new ArrayList<AtlasClassification>() {{ 
add(testClassification); }}, retrievedClassifications);
+    }
+
+    @Test(dependsOnMethods = "testGetEntityWithAssociations")
+    public void  testDeleteClassification() throws Exception {
+
+        entityREST.deleteClassification(dbGuid, TestUtilsV2.CLASSIFICATION);
+        final AtlasClassification.AtlasClassifications 
retrievedClassifications = entityREST.getClassifications(dbGuid);
+
+        Assert.assertNotNull(retrievedClassifications);
+        Assert.assertEquals(retrievedClassifications.getList().size(), 0);
+    }
+
+    @Test(dependsOnMethods = "testDeleteClassification")
+    public void  testDeleteEntityById() throws Exception {
+
+        EntityMutationResponse response = entityREST.deleteByGuid(dbGuid);
+        List<AtlasEntityHeader> entitiesMutated = 
response.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE);
+        Assert.assertNotNull(entitiesMutated);
+        Assert.assertEquals(entitiesMutated.get(0).getGuid(), dbGuid);
+    }
+
+    @Test
+    public void  testUpdateGetDeleteEntityByUniqueAttribute() throws Exception 
{
+
+        AtlasEntity dbEntity = TestUtilsV2.createDBEntity();
+        entityREST.createOrUpdate(dbEntity);
+
+        final String prevDBName = (String) 
dbEntity.getAttribute(TestUtilsV2.NAME);
+        final String updatedDBName = "updatedDBName";
+
+        dbEntity.setAttribute(TestUtilsV2.NAME, updatedDBName);
+
+        final EntityMutationResponse response = 
entityREST.partialUpdateByUniqueAttribute(TestUtilsV2.DATABASE_TYPE, 
TestUtilsV2.NAME, prevDBName, dbEntity);
+        String dbGuid = 
response.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE_OR_UPDATE).get(0).getGuid();
+        Assert.assertTrue(AtlasEntity.isAssigned(dbGuid));
+
+        //Get By unique attribute
+        AtlasEntity entity = 
entityREST.getByUniqueAttribute(TestUtilsV2.DATABASE_TYPE, TestUtilsV2.NAME, 
updatedDBName);
+        Assert.assertNotNull(entity);
+        Assert.assertNotNull(entity.getGuid());
+        Assert.assertEquals(entity.getGuid(), dbGuid);
+        TestEntitiesREST.verifyAttributes(entity.getAttributes(), 
dbEntity.getAttributes());
+
+        final EntityMutationResponse deleteResponse = 
entityREST.deleteByUniqueAttribute(TestUtilsV2.DATABASE_TYPE, TestUtilsV2.NAME, 
(String) dbEntity.getAttribute(TestUtilsV2.NAME));
+
+        
Assert.assertNotNull(deleteResponse.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE));
+        
Assert.assertEquals(deleteResponse.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE).size(),
 1);
+        
Assert.assertEquals(deleteResponse.getEntitiesByOperation(EntityMutations.EntityOperation.DELETE).get(0).getGuid(),
 dbGuid);
+    }
+
+}


Reply via email to