You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by si...@apache.org on 2021/05/26 20:55:50 UTC

[atlas] branch branch-2.0 updated: ATLAS-4307 Atlas bulk clarification REST enhanced to associate classification to bulk entities with uniq attribute and type as well

This is an automated email from the ASF dual-hosted git repository.

sidmishra pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new b30437a  ATLAS-4307 Atlas bulk clarification REST enhanced to associate classification to bulk entities with uniq attribute and type as well
b30437a is described below

commit b30437a3c3dc72951d80868dab42b5b72ba1c65d
Author: sidmishra <si...@cloudera.com>
AuthorDate: Tue May 25 17:14:24 2021 -0700

    ATLAS-4307 Atlas bulk clarification REST enhanced to associate classification to bulk entities with uniq attribute and type as well
    
    Signed-off-by: sidmishra <si...@apache.org>
    (cherry picked from commit 6648af332a234d606145a0440ac94da00782acc9)
---
 .../instance/ClassificationAssociateRequest.java   | 52 ++++++++++++++++++---
 .../java/org/apache/atlas/web/rest/EntityREST.java | 53 ++++++++++++++++++++--
 2 files changed, 94 insertions(+), 11 deletions(-)

diff --git a/intg/src/main/java/org/apache/atlas/model/instance/ClassificationAssociateRequest.java b/intg/src/main/java/org/apache/atlas/model/instance/ClassificationAssociateRequest.java
index 3f946ef..f225213 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/ClassificationAssociateRequest.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/ClassificationAssociateRequest.java
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 
 import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.commons.collections.CollectionUtils;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
@@ -32,6 +33,7 @@ import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
 import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@@ -40,8 +42,10 @@ import java.util.Objects;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.PROPERTY)
 public class ClassificationAssociateRequest {
-    private AtlasClassification classification;
-    private List<String>        entityGuids;
+    private AtlasClassification         classification;
+    private List<String>                entityGuids;
+    private List<Map<String, Object>>   entitiesUniqueAttributes;
+    private String                      entityTypeName;
 
     public ClassificationAssociateRequest() {
         this(null, null);
@@ -52,6 +56,35 @@ public class ClassificationAssociateRequest {
         setClassification(classification);
     }
 
+    public ClassificationAssociateRequest(String entityTypeName, List<Map<String, Object>> entitiesUniqueAttributes, AtlasClassification classification) {
+        setEntitiesUniqueAttributes(entitiesUniqueAttributes);
+        setClassification(classification);
+        setEntityTypeName(entityTypeName);
+    }
+
+    public ClassificationAssociateRequest(List<String> entityGuids, String entityTypeName, List<Map<String, Object>> entitiesUniqueAttributes, AtlasClassification classification) {
+        setEntityGuids(entityGuids);
+        setEntitiesUniqueAttributes(entitiesUniqueAttributes);
+        setClassification(classification);
+        setEntityTypeName(entityTypeName);
+    }
+
+    public String getEntityTypeName() {
+        return entityTypeName;
+    }
+
+    public void setEntityTypeName(String entityTypeName) {
+        this.entityTypeName = entityTypeName;
+    }
+
+    public List<Map<String, Object>> getEntitiesUniqueAttributes() {
+        return entitiesUniqueAttributes;
+    }
+
+    public void setEntitiesUniqueAttributes(List<Map<String, Object>> entitiesUniqueAttributes) {
+        this.entitiesUniqueAttributes = entitiesUniqueAttributes;
+    }
+
     public AtlasClassification getClassification() { return classification; }
 
     public void setClassification(AtlasClassification classification) { this.classification = classification; }
@@ -68,12 +101,12 @@ public class ClassificationAssociateRequest {
 
         ClassificationAssociateRequest that = (ClassificationAssociateRequest) o;
 
-        return Objects.equals(classification, that.classification) && Objects.equals(entityGuids, that.entityGuids);
+        return Objects.equals(classification, that.classification) && Objects.equals(entityGuids, that.entityGuids) && CollectionUtils.isEqualCollection(entitiesUniqueAttributes, that.entitiesUniqueAttributes);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(classification, entityGuids);
+        return Objects.hash(classification, entityGuids, entitiesUniqueAttributes);
     }
 
     public StringBuilder toString(StringBuilder sb) {
@@ -86,9 +119,17 @@ public class ClassificationAssociateRequest {
         if (classification != null) {
             classification.toString(sb);
         }
-        sb.append(", entityGuids=[");
+        sb.append("', entityGuids=[");
         AtlasBaseTypeDef.dumpObjects(entityGuids, sb);
         sb.append("]");
+        sb.append(", entityTypeName=[");
+        if (entityTypeName != null) {
+            sb.append(entityTypeName);
+        }
+        sb.append("]");
+        sb.append(", entitiesUniqueAttributes=[");
+        AtlasBaseTypeDef.dumpObjects(entitiesUniqueAttributes, sb);
+        sb.append("]");
         sb.append('}');
 
         return sb;
@@ -98,5 +139,4 @@ public class ClassificationAssociateRequest {
     public String toString() {
         return toString(new StringBuilder()).toString();
     }
-
 }
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 ec893f2..05d7d13 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
@@ -21,6 +21,7 @@ import com.sun.jersey.core.header.FormDataContentDisposition;
 import com.sun.jersey.multipart.FormDataParam;
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.EntityAuditEvent;
+import org.apache.atlas.RequestContext;
 import org.apache.atlas.annotation.Timed;
 import org.apache.atlas.authorize.AtlasAuthorizationUtils;
 import org.apache.atlas.authorize.AtlasEntityAccessRequest;
@@ -790,7 +791,10 @@ public class EntityREST {
     }
 
     /**
-     * Bulk API to associate a tag to multiple entities
+     * Bulk API to associate a tag to multiple entities.
+     * Option 1: List of GUIDs to associate a tag
+     * Option 2: Typename and list of uniq attributes for entities to associate a tag
+     * Option 3: List of GUIDs and Typename with list of uniq attributes for entities to associate a tag
      */
     @POST
     @Path("/bulk/classification")
@@ -803,15 +807,49 @@ public class EntityREST {
                 perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityREST.addClassification(" + request  + ")");
             }
 
-            AtlasClassification classification = request == null ? null : request.getClassification();
-            List<String>        entityGuids    = request == null ? null : request.getEntityGuids();
+            AtlasClassification       classification           = request == null ? null : request.getClassification();
+            List<String>              entityGuids              = request == null ? null : request.getEntityGuids();
+            List<Map<String, Object>> entitiesUniqueAttributes = request == null ? null : request.getEntitiesUniqueAttributes();
+            String                    entityTypeName           = request == null ? null : request.getEntityTypeName();
 
             if (classification == null || StringUtils.isEmpty(classification.getTypeName())) {
                 throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "no classification");
             }
 
-            if (CollectionUtils.isEmpty(entityGuids)) {
-                throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "empty guid list");
+            if (hasNoGUIDAndTypeNameAttributes(request)) {
+                throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "Need either list of GUIDs or entity type and list of qualified Names");
+            }
+
+            if (CollectionUtils.isNotEmpty(entitiesUniqueAttributes) && entityTypeName != null) {
+                AtlasEntityType entityType = ensureEntityType(entityTypeName);
+
+                if (CollectionUtils.isEmpty(entityGuids)) {
+                    entityGuids = new ArrayList<>();
+                }
+
+                for (Map<String, Object> eachEntityAttributes : entitiesUniqueAttributes) {
+                    try {
+                        String guid = entitiesStore.getGuidByUniqueAttributes(entityType, eachEntityAttributes);
+
+                        if (guid != null) {
+                            entityGuids.add(guid);
+                        }
+                    } catch (AtlasBaseException e) {
+                        if (RequestContext.get().isSkipFailedEntities()) {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("getByIds(): ignoring failure for entity with unique attributes {} and typeName {}: error code={}, message={}", eachEntityAttributes, entityTypeName, e.getAtlasErrorCode(), e.getMessage());
+                            }
+
+                            continue;
+                        }
+
+                        throw e;
+                    }
+                }
+
+                if (CollectionUtils.isEmpty(entityGuids)) {
+                    throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "No guid found for given entity Type Name and list of attributes");
+                }
             }
 
             entitiesStore.addClassification(entityGuids, classification);
@@ -1298,4 +1336,9 @@ public class EntityREST {
 
         return ret;
     }
+
+    private boolean hasNoGUIDAndTypeNameAttributes(ClassificationAssociateRequest request) {
+        return (request == null || (CollectionUtils.isEmpty(request.getEntityGuids()) &&
+                (CollectionUtils.isEmpty(request.getEntitiesUniqueAttributes()) || request.getEntityTypeName() == null)));
+    }
 }