atlas-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From suma...@apache.org
Subject [1/2] incubator-atlas git commit: ATLAS-1257 Map Entity REST APIs to ATLAS v1 backend (sumasai)
Date Mon, 14 Nov 2016 21:02:00 GMT
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);
+    }
+
+}



Mime
View raw message