You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by su...@apache.org on 2015/10/26 05:47:49 UTC

incubator-atlas git commit: ATLAS-232 Fix the API incompatibility introduced in ATLAS-58 (shwetags via sumasai)

Repository: incubator-atlas
Updated Branches:
  refs/heads/master bbf48d90a -> 143f21039


ATLAS-232 Fix the API incompatibility introduced in ATLAS-58 (shwetags via sumasai)


Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/143f2103
Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/143f2103
Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/143f2103

Branch: refs/heads/master
Commit: 143f21039f264d523b9dc6bc88bca44e3ef6dc41
Parents: bbf48d9
Author: Suma Shivaprasad <su...@gmail.com>
Authored: Mon Oct 26 10:16:47 2015 +0530
Committer: Suma Shivaprasad <su...@gmail.com>
Committed: Mon Oct 26 10:16:47 2015 +0530

----------------------------------------------------------------------
 .../main/java/org/apache/atlas/AtlasClient.java |   5 +-
 release-log.txt                                 |   3 +-
 .../atlas/web/resources/EntitiesResource.java   | 133 -------------------
 .../atlas/web/resources/EntityResource.java     | 108 ++++++++++++++-
 .../web/resources/EntityJerseyResourceIT.java   |  24 +++-
 5 files changed, 128 insertions(+), 145 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/143f2103/client/src/main/java/org/apache/atlas/AtlasClient.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/atlas/AtlasClient.java b/client/src/main/java/org/apache/atlas/AtlasClient.java
index 06d9206..8f04653 100755
--- a/client/src/main/java/org/apache/atlas/AtlasClient.java
+++ b/client/src/main/java/org/apache/atlas/AtlasClient.java
@@ -67,7 +67,6 @@ public class AtlasClient {
     public static final String BASE_URI = "api/atlas/";
     public static final String TYPES = "types";
     public static final String URI_ENTITY = "entity";
-    public static final String URI_ENTITIES = "entities";
     public static final String URI_SEARCH = "discovery/search";
     public static final String URI_LINEAGE = "lineage/hive/table";
 
@@ -138,10 +137,10 @@ public class AtlasClient {
         LIST_TRAIT_TYPES(BASE_URI + TYPES + "?type=trait", HttpMethod.GET),
 
         //Entity operations
-        CREATE_ENTITY(BASE_URI + URI_ENTITIES, HttpMethod.POST),
+        CREATE_ENTITY(BASE_URI + URI_ENTITY, HttpMethod.POST),
         GET_ENTITY(BASE_URI + URI_ENTITY, HttpMethod.GET),
         UPDATE_ENTITY(BASE_URI + URI_ENTITY, HttpMethod.PUT),
-        LIST_ENTITIES(BASE_URI + URI_ENTITIES, HttpMethod.GET),
+        LIST_ENTITIES(BASE_URI + URI_ENTITY, HttpMethod.GET),
 
         //Trait operations
         ADD_TRAITS(BASE_URI + URI_ENTITY, HttpMethod.POST),

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/143f2103/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index b50ee43..3daa7c4 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -9,7 +9,8 @@ ATLAS-54 Rename configs in hive hook (shwethags)
 ATLAS-3 Mixed Index creation fails with Date types (sumasai via shwethags)
 
 ALL CHANGES:
-ATLAS1-98 Atlas UI Requires Internet Access(sanjayp via sumasai)
+ATLAS-232 Fix the API incompatibility introduced in ATLAS-58(shwethags via sumasai)
+ATLAS-198 Atlas UI Requires Internet Access(sanjayp via sumasai)
 ATLAS-201 Rename org.apache.atlas.Main to org.apache.atlas.Atlas (rishabhbhardwaj via shwethags)
 ATLAS-179 Atlas hook causes mem leak and hive server 2 crashes (shwethags)
 ATLAS-212 Remove test class usage of hive configuration property "atlas.rest.address" (jspeidel via shwethags)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/143f2103/webapp/src/main/java/org/apache/atlas/web/resources/EntitiesResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/EntitiesResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/EntitiesResource.java
deleted file mode 100644
index 8cff0c5..0000000
--- a/webapp/src/main/java/org/apache/atlas/web/resources/EntitiesResource.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * 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
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.resources;
-
-import com.google.common.base.Preconditions;
-import com.google.inject.Inject;
-import org.apache.atlas.AtlasClient;
-import org.apache.atlas.AtlasException;
-import org.apache.atlas.repository.EntityExistsException;
-import org.apache.atlas.services.MetadataService;
-import org.apache.atlas.typesystem.types.ValueConversionException;
-import org.apache.atlas.web.util.Servlets;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Singleton;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
-import java.net.URI;
-import java.util.List;
-
-@Path("entities")
-@Singleton
-public class EntitiesResource {
-    private static final Logger LOG = LoggerFactory.getLogger(EntitiesResource.class);
-
-    @Inject
-    private MetadataService metadataService;
-
-    @Context
-    UriInfo uriInfo;
-
-    /**
-     * Submits the entity definitions (instances).
-     * The body contains the JSONArray of entity json. The service takes care of de-duping the entities based on any
-     * unique attribute for the give type.
-     */
-    @POST
-    @Consumes(Servlets.JSON_MEDIA_TYPE)
-    @Produces(Servlets.JSON_MEDIA_TYPE)
-    public Response submit(@Context HttpServletRequest request) {
-        try {
-            final String entities = Servlets.getRequestPayload(request);
-            LOG.debug("submitting entities {} ", AtlasClient.toString(new JSONArray(entities)));
-
-            final String guids = metadataService.createEntities(entities);
-
-            UriBuilder ub = uriInfo.getAbsolutePathBuilder();
-            URI locationURI = ub.path(guids).build();
-
-            JSONObject response = new JSONObject();
-            response.put(AtlasClient.REQUEST_ID, Servlets.getRequestId());
-            response.put(AtlasClient.GUID, new JSONArray(guids));
-            response.put(AtlasClient.DEFINITION, metadataService.getEntityDefinition(new JSONArray(guids).getString(0)));
-
-            return Response.created(locationURI).entity(response).build();
-
-        } catch(EntityExistsException e) {
-            LOG.error("Unique constraint violation", e);
-            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.CONFLICT));
-        } catch (ValueConversionException ve) {
-            LOG.error("Unable to persist entity instance due to a desrialization error ", ve);
-            throw new WebApplicationException(Servlets.getErrorResponse(ve.getCause(), Response.Status.BAD_REQUEST));
-        } catch (AtlasException | IllegalArgumentException e) {
-            LOG.error("Unable to persist entity instance", e);
-            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.BAD_REQUEST));
-        } catch (Throwable e) {
-            LOG.error("Unable to persist entity instance", e);
-            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        }
-    }
-
-    /**
-     * Gets the list of entities for a given entity type.
-     *
-     * @param entityType name of a type which is unique
-     */
-    @GET
-    @Produces(Servlets.JSON_MEDIA_TYPE)
-    public Response getEntityListByType(@QueryParam("type") String entityType) {
-        try {
-            Preconditions.checkNotNull(entityType, "Entity type cannot be null");
-
-            LOG.debug("Fetching entity list for type={} ", entityType);
-            final List<String> entityList = metadataService.getEntityList(entityType);
-
-            JSONObject response = new JSONObject();
-            response.put(AtlasClient.REQUEST_ID, Servlets.getRequestId());
-            response.put(AtlasClient.TYPENAME, entityType);
-            response.put(AtlasClient.RESULTS, new JSONArray(entityList));
-            response.put(AtlasClient.COUNT, entityList.size());
-
-            return Response.ok(response).build();
-        } catch (NullPointerException e) {
-            LOG.error("Entity type cannot be null", e);
-            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.BAD_REQUEST));
-        } catch (AtlasException | IllegalArgumentException e) {
-            LOG.error("Unable to get entity list for type {}", entityType, e);
-            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.BAD_REQUEST));
-        } catch (Throwable e) {
-            LOG.error("Unable to get entity list for type {}", entityType, e);
-            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/143f2103/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
index d8ffe9f..0820d9c 100755
--- a/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java
@@ -23,10 +23,14 @@ import org.apache.atlas.AtlasClient;
 import org.apache.atlas.AtlasException;
 import org.apache.atlas.ParamChecker;
 import org.apache.atlas.TypeNotFoundException;
+import org.apache.atlas.repository.EntityExistsException;
 import org.apache.atlas.repository.EntityNotFoundException;
 import org.apache.atlas.services.MetadataService;
+import org.apache.atlas.typesystem.types.ValueConversionException;
 import org.apache.atlas.web.util.Servlets;
+import org.apache.commons.lang.StringUtils;
 import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -83,6 +87,57 @@ public class EntityResource {
 
 
     /**
+     * Submits the entity definitions (instances).
+     * The body contains the JSONArray of entity json. The service takes care of de-duping the entities based on any
+     * unique attribute for the give type.
+     */
+    @POST
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public Response submit(@Context HttpServletRequest request) {
+        try {
+            String entities = Servlets.getRequestPayload(request);
+
+            //Handle backward compatibility - if entities is not JSONArray, convert to JSONArray
+            try {
+                new JSONArray(entities);
+            } catch (JSONException e) {
+                final String finalEntities = entities;
+                entities = new JSONArray() {{
+                    put(finalEntities);
+                }}.toString();
+            }
+
+            LOG.debug("submitting entities {} ", AtlasClient.toString(new JSONArray(entities)));
+
+            final String guids = metadataService.createEntities(entities);
+
+            UriBuilder ub = uriInfo.getAbsolutePathBuilder();
+            URI locationURI = ub.path(guids).build();
+
+            JSONObject response = new JSONObject();
+            response.put(AtlasClient.REQUEST_ID, Servlets.getRequestId());
+            response.put(AtlasClient.GUID, new JSONArray(guids));
+            response.put(AtlasClient.DEFINITION, metadataService.getEntityDefinition(new JSONArray(guids).getString(0)));
+
+            return Response.created(locationURI).entity(response).build();
+
+        } catch(EntityExistsException e) {
+            LOG.error("Unique constraint violation", e);
+            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.CONFLICT));
+        } catch (ValueConversionException ve) {
+            LOG.error("Unable to persist entity instance due to a desrialization error ", ve);
+            throw new WebApplicationException(Servlets.getErrorResponse(ve.getCause(), Response.Status.BAD_REQUEST));
+        } catch (AtlasException | IllegalArgumentException e) {
+            LOG.error("Unable to persist entity instance", e);
+            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.BAD_REQUEST));
+        } catch (Throwable e) {
+            LOG.error("Unable to persist entity instance", e);
+            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
+        }
+    }
+
+    /**
      * Fetch the complete definition of an entity given its GUID.
      *
      * @param guid GUID for the entity
@@ -124,20 +179,61 @@ public class EntityResource {
     }
 
     /**
+     * Gets the list of entities for a given entity type.
+     *
+     * @param entityType name of a type which is unique
+     */
+    public Response getEntityListByType(String entityType) {
+        try {
+            Preconditions.checkNotNull(entityType, "Entity type cannot be null");
+
+            LOG.debug("Fetching entity list for type={} ", entityType);
+            final List<String> entityList = metadataService.getEntityList(entityType);
+
+            JSONObject response = new JSONObject();
+            response.put(AtlasClient.REQUEST_ID, Servlets.getRequestId());
+            response.put(AtlasClient.TYPENAME, entityType);
+            response.put(AtlasClient.RESULTS, new JSONArray(entityList));
+            response.put(AtlasClient.COUNT, entityList.size());
+
+            return Response.ok(response).build();
+        } catch (NullPointerException e) {
+            LOG.error("Entity type cannot be null", e);
+            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.BAD_REQUEST));
+        } catch (AtlasException | IllegalArgumentException e) {
+            LOG.error("Unable to get entity list for type {}", entityType, e);
+            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.BAD_REQUEST));
+        } catch (Throwable e) {
+            LOG.error("Unable to get entity list for type {}", entityType, e);
+            throw new WebApplicationException(Servlets.getErrorResponse(e, Response.Status.INTERNAL_SERVER_ERROR));
+        }
+    }
+
+    @GET
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public Response getEntity(@QueryParam("type") String entityType,
+                              @QueryParam("property") String attribute,
+                              @QueryParam("value") String value) {
+        if (StringUtils.isEmpty(attribute)) {
+            //List API
+            return getEntityListByType(entityType);
+        } else {
+            //Get entity by unique attribute
+            return getEntityDefinitionByAttribute(entityType, attribute, value);
+        }
+    }
+
+    /**
      * Fetch the complete definition of an entity given its qualified name.
      *
      * @param entityType
      * @param attribute
      * @param value
      */
-    @GET
-    @Produces(Servlets.JSON_MEDIA_TYPE)
-    public Response getEntityDefinitionByAttribute(@QueryParam("type") String entityType,
-                                                   @QueryParam("property") String attribute,
-                                                   @QueryParam("value") String value) {
+    public Response getEntityDefinitionByAttribute(String entityType, String attribute, String value) {
         try {
             LOG.debug("Fetching entity definition for type={}, qualified name={}", entityType, value);
-            ParamChecker.notEmpty(entityType, "type cannot be null");
+            ParamChecker.notEmpty(entityType, "Entity type cannot be null");
             ParamChecker.notEmpty(attribute, "attribute name cannot be null");
             ParamChecker.notEmpty(value, "attribute value cannot be null");
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/143f2103/webapp/src/test/java/org/apache/atlas/web/resources/EntityJerseyResourceIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/atlas/web/resources/EntityJerseyResourceIT.java b/webapp/src/test/java/org/apache/atlas/web/resources/EntityJerseyResourceIT.java
index 43ad941..e7fba6f 100755
--- a/webapp/src/test/java/org/apache/atlas/web/resources/EntityJerseyResourceIT.java
+++ b/webapp/src/test/java/org/apache/atlas/web/resources/EntityJerseyResourceIT.java
@@ -91,6 +91,26 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
         }
     }
 
+    @Test
+    public void testSubmitSingleEntity() throws Exception {
+        Referenceable databaseInstance = new Referenceable(DATABASE_TYPE);
+        databaseInstance.set("name", randomString());
+        databaseInstance.set("description", randomString());
+
+        ClientResponse clientResponse =
+                service.path("api/atlas/entity").accept(Servlets.JSON_MEDIA_TYPE).type(Servlets.JSON_MEDIA_TYPE)
+                        .method(HttpMethod.POST, ClientResponse.class,
+                                InstanceSerialization.toJson(databaseInstance, true));
+        Assert.assertEquals(clientResponse.getStatus(), Response.Status.CREATED.getStatusCode());
+
+        String responseAsString = clientResponse.getEntity(String.class);
+        Assert.assertNotNull(responseAsString);
+
+        JSONObject response = new JSONObject(responseAsString);
+        Assert.assertNotNull(response.get(AtlasClient.REQUEST_ID));
+        Assert.assertNotNull(response.get(AtlasClient.GUID));
+    }
+
     @DataProvider
     public Object[][] invalidAttrValues() {
         return new Object[][]{{null}, {""}};
@@ -264,7 +284,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
     @Test
     public void testGetEntityListForBadEntityType() throws Exception {
         ClientResponse clientResponse =
-                service.path("api/atlas/entities").queryParam("type", "blah").accept(Servlets.JSON_MEDIA_TYPE)
+                service.path("api/atlas/entity").queryParam("type", "blah").accept(Servlets.JSON_MEDIA_TYPE)
                         .type(Servlets.JSON_MEDIA_TYPE).method(HttpMethod.GET, ClientResponse.class);
         Assert.assertEquals(clientResponse.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
 
@@ -282,7 +302,7 @@ public class EntityJerseyResourceIT extends BaseResourceIT {
         String typeName = addNewType();
 
         ClientResponse clientResponse =
-                service.path("api/atlas/entities").queryParam("type", typeName).accept(Servlets.JSON_MEDIA_TYPE)
+                service.path("api/atlas/entity").queryParam("type", typeName).accept(Servlets.JSON_MEDIA_TYPE)
                         .type(Servlets.JSON_MEDIA_TYPE).method(HttpMethod.GET, ClientResponse.class);
         Assert.assertEquals(clientResponse.getStatus(), Response.Status.OK.getStatusCode());