From 0230ae887a6819f0000f597971fb1a7f5d94c96e Mon Sep 17 00:00:00 2001 From: ektavarma10 Date: Mon, 27 Nov 2023 11:02:23 +0530 Subject: [PATCH 1/2] Add parallelisation for classification level access --- .../authorizer/RangerAtlasAuthorizer.java | 136 ++++++++++++------ .../authorizer/RangerAtlasAuthorizerUtil.java | 2 + 2 files changed, 96 insertions(+), 42 deletions(-) diff --git a/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizer.java b/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizer.java index dd645b473b..63375f2d18 100644 --- a/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizer.java +++ b/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizer.java @@ -61,6 +61,10 @@ import java.util.ListIterator; import java.util.Map; import java.util.Set; +import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import static org.apache.atlas.authorization.atlas.authorizer.RangerAtlasAuthorizerUtil.*; import static org.apache.atlas.authorize.AtlasAuthorizationUtils.getCurrentUserGroups; @@ -81,6 +85,8 @@ public class RangerAtlasAuthorizer implements AtlasAuthorizer { add(AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION); }}; + private static final ExecutorService classification_access_threadpool = Executors.newFixedThreadPool(NUM_THREADS); + @Override public void init() { if (LOG.isDebugEnabled()) { @@ -657,61 +663,41 @@ private boolean isAccessAllowed(AtlasEntityAccessRequest request, RangerAtlasAud boolean ret = false; try { - final String action = request.getAction() != null ? request.getAction().getType() : null; - final Set entityTypes = request.getEntityTypeAndAllSuperTypes(); - final String entityId = request.getEntityId(); - final String classification = request.getClassification() != null ? request.getClassification().getTypeName() : null; - final RangerAccessRequestImpl rangerRequest = new RangerAccessRequestImpl(); - final RangerAccessResourceImpl rangerResource = new RangerAccessResourceImpl(); - final String ownerUser = request.getEntity() != null ? (String) request.getEntity().getAttribute(RESOURCE_ENTITY_OWNER) : null; - - rangerResource.setValue(RESOURCE_ENTITY_TYPE, entityTypes); - rangerResource.setValue(RESOURCE_ENTITY_ID, entityId); - rangerResource.setOwnerUser(ownerUser); - rangerRequest.setAccessType(action); - rangerRequest.setAction(action); - rangerRequest.setUser(request.getUser()); - rangerRequest.setUserGroups(request.getUserGroups()); - rangerRequest.setClientIPAddress(request.getClientIPAddress()); - rangerRequest.setAccessTime(request.getAccessTime()); - rangerRequest.setResource(rangerResource); - rangerRequest.setForwardedAddresses(request.getForwardedAddresses()); - rangerRequest.setRemoteIPAddress(request.getRemoteIPAddress()); - - if (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) { - rangerResource.setValue(RESOURCE_ENTITY_LABEL, request.getLabel()); - } else if (AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA.equals(request.getAction())) { - rangerResource.setValue(RESOURCE_ENTITY_BUSINESS_METADATA, request.getBusinessMetadata()); - } else if (StringUtils.isNotEmpty(classification) && CLASSIFICATION_PRIVILEGES.contains(request.getAction())) { - rangerResource.setValue(RESOURCE_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classification)); - } if (CollectionUtils.isNotEmpty(request.getEntityClassifications())) { Set entityClassifications = request.getEntityClassifications(); - Map contextOjb = rangerRequest.getContext(); Set rangerTagForEval = getRangerServiceTag(entityClassifications); - if (contextOjb == null) { - Map contextOjb1 = new HashMap(); - contextOjb1.put("CLASSIFICATIONS", rangerTagForEval); - rangerRequest.setContext(contextOjb1); - } else { - contextOjb.put("CLASSIFICATIONS", rangerTagForEval); - rangerRequest.setContext(contextOjb); - } + List> completableFutures = new ArrayList<>(); // check authorization for each classification for (AtlasClassification classificationToAuthorize : request.getEntityClassifications()) { - rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize.getTypeName())); - ret = checkAccess(rangerRequest, auditHandler); + RangerAccessRequestImpl rangerRequest = createRangerAccessRequest(request, classificationToAuthorize, rangerTagForEval); - if (!ret) { - break; - } + completableFutures.add(CompletableFuture.supplyAsync(()->checkAccess(rangerRequest, auditHandler), classification_access_threadpool)); } + + // wait for all threads to complete their execution + CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).join(); + + // if all checkAccess calls return true, then ret is true, else it is false + ret = completableFutures + .stream() + .map(CompletableFuture::join) + .allMatch(result -> result == true); + } else { + + RangerAccessRequestImpl rangerRequest = new RangerAccessRequestImpl(); + RangerAccessResourceImpl rangerResource = new RangerAccessResourceImpl(); + + initRangerRequest(rangerRequest, request); + initRangerResource(rangerResource, request); + + rangerRequest.setResource(rangerResource); + rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, ENTITY_NOT_CLASSIFIED ); ret = checkAccess(rangerRequest, auditHandler); @@ -730,6 +716,72 @@ private boolean isAccessAllowed(AtlasEntityAccessRequest request, RangerAtlasAud return ret; } + private RangerAccessRequestImpl createRangerAccessRequest(AtlasEntityAccessRequest request, + AtlasClassification classificationToAuthorize, + Set rangerTagForEval) { + + RangerAccessRequestImpl rangerRequest = new RangerAccessRequestImpl(); + RangerAccessResourceImpl rangerResource = new RangerAccessResourceImpl(); + + initRangerRequest(rangerRequest, request); + initRangerResource(rangerResource, request); + + rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize.getTypeName())); + + rangerRequest.setResource(rangerResource); + + setClassificationContextForRanger(rangerTagForEval, rangerRequest); + + return rangerRequest; + + } + + private static void setClassificationContextForRanger(Set rangerTagForEval, RangerAccessRequestImpl rangerRequest) { + Map contextOjb = rangerRequest.getContext(); + + if (contextOjb == null) { + Map contextOjb1 = new HashMap(); + contextOjb1.put("CLASSIFICATIONS", rangerTagForEval); + rangerRequest.setContext(contextOjb1); + } else { + contextOjb.put("CLASSIFICATIONS", rangerTagForEval); + rangerRequest.setContext(contextOjb); + } + } + + private void initRangerRequest(RangerAccessRequestImpl rangerRequest, AtlasEntityAccessRequest request) { + final String action = request.getAction() != null ? request.getAction().getType() : null; + + rangerRequest.setAccessType(action); + rangerRequest.setAction(action); + rangerRequest.setUser(request.getUser()); + rangerRequest.setUserGroups(request.getUserGroups()); + rangerRequest.setClientIPAddress(request.getClientIPAddress()); + rangerRequest.setAccessTime(request.getAccessTime()); + rangerRequest.setForwardedAddresses(request.getForwardedAddresses()); + rangerRequest.setRemoteIPAddress(request.getRemoteIPAddress()); + } + + private void initRangerResource(RangerAccessResourceImpl rangerResource, AtlasEntityAccessRequest request) { + final Set entityTypes = request.getEntityTypeAndAllSuperTypes(); + final String entityId = request.getEntityId(); + final String ownerUser = request.getEntity() != null ? (String) request.getEntity().getAttribute(RESOURCE_ENTITY_OWNER) : null; + final String classification = request.getClassification() != null ? request.getClassification().getTypeName() : null; + + rangerResource.setValue(RESOURCE_ENTITY_TYPE, entityTypes); + rangerResource.setValue(RESOURCE_ENTITY_ID, entityId); + rangerResource.setOwnerUser(ownerUser); + + if (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) { + rangerResource.setValue(RESOURCE_ENTITY_LABEL, request.getLabel()); + } else if (AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA.equals(request.getAction())) { + rangerResource.setValue(RESOURCE_ENTITY_BUSINESS_METADATA, request.getBusinessMetadata()); + } else if (StringUtils.isNotEmpty(classification) && CLASSIFICATION_PRIVILEGES.contains(request.getAction())) { + rangerResource.setValue(RESOURCE_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classification)); + } + + } + private void setClassificationsToRequestContext(Set entityClassifications, RangerAccessRequestImpl rangerRequest) { Map contextOjb = rangerRequest.getContext(); diff --git a/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizerUtil.java b/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizerUtil.java index c78e986581..1a81bb180e 100644 --- a/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizerUtil.java +++ b/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizerUtil.java @@ -43,6 +43,8 @@ public class RangerAtlasAuthorizerUtil { + public static Integer NUM_THREADS = 5; + static void toRangerRequest(AtlasEntityAccessRequest request, RangerAccessRequestImpl rangerRequest, RangerAccessResourceImpl rangerResource){ final String action = request.getAction() != null ? request.getAction().getType() : null; From 5956234721b174800d97958c2a58f4ba1c9567fb Mon Sep 17 00:00:00 2001 From: ektavarma10 Date: Mon, 27 Nov 2023 15:27:58 +0530 Subject: [PATCH 2/2] Minor Refactoring --- .../authorizer/RangerAtlasAuthorizer.java | 104 +++++++++--------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizer.java b/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizer.java index 63375f2d18..6ad01e932b 100644 --- a/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizer.java +++ b/auth-plugin-atlas/src/main/java/org/apache/atlas/authorization/atlas/authorizer/RangerAtlasAuthorizer.java @@ -85,7 +85,7 @@ public class RangerAtlasAuthorizer implements AtlasAuthorizer { add(AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION); }}; - private static final ExecutorService classification_access_threadpool = Executors.newFixedThreadPool(NUM_THREADS); + private static final ExecutorService classificationAccessThreadpool = Executors.newFixedThreadPool(NUM_THREADS); @Override public void init() { @@ -674,9 +674,15 @@ private boolean isAccessAllowed(AtlasEntityAccessRequest request, RangerAtlasAud // check authorization for each classification for (AtlasClassification classificationToAuthorize : request.getEntityClassifications()) { - RangerAccessRequestImpl rangerRequest = createRangerAccessRequest(request, classificationToAuthorize, rangerTagForEval); + RangerAccessResourceImpl rangerResource = createRangerResourceRequest(request); + RangerAccessRequestImpl rangerRequest = createRangerAccessRequest(request, rangerResource); - completableFutures.add(CompletableFuture.supplyAsync(()->checkAccess(rangerRequest, auditHandler), classification_access_threadpool)); + rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, + request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize.getTypeName())); + setClassificationContextForRanger(rangerTagForEval, rangerRequest); + + completableFutures.add(CompletableFuture.supplyAsync( + () -> checkAccess(rangerRequest, auditHandler), classificationAccessThreadpool)); } // wait for all threads to complete their execution @@ -690,13 +696,9 @@ private boolean isAccessAllowed(AtlasEntityAccessRequest request, RangerAtlasAud } else { - RangerAccessRequestImpl rangerRequest = new RangerAccessRequestImpl(); - RangerAccessResourceImpl rangerResource = new RangerAccessResourceImpl(); - - initRangerRequest(rangerRequest, request); - initRangerResource(rangerResource, request); + RangerAccessResourceImpl rangerResource = createRangerResourceRequest(request); - rangerRequest.setResource(rangerResource); + RangerAccessRequestImpl rangerRequest = createRangerAccessRequest(request, rangerResource); rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, ENTITY_NOT_CLASSIFIED ); @@ -716,40 +718,38 @@ private boolean isAccessAllowed(AtlasEntityAccessRequest request, RangerAtlasAud return ret; } - private RangerAccessRequestImpl createRangerAccessRequest(AtlasEntityAccessRequest request, - AtlasClassification classificationToAuthorize, - Set rangerTagForEval) { - - RangerAccessRequestImpl rangerRequest = new RangerAccessRequestImpl(); + private RangerAccessResourceImpl createRangerResourceRequest(AtlasEntityAccessRequest request) { RangerAccessResourceImpl rangerResource = new RangerAccessResourceImpl(); - initRangerRequest(rangerRequest, request); - initRangerResource(rangerResource, request); - - rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize.getTypeName())); - - rangerRequest.setResource(rangerResource); + final Set entityTypes = request.getEntityTypeAndAllSuperTypes(); + final String entityId = request.getEntityId(); + final String ownerUser = request.getEntity() != null ? + (String) request.getEntity().getAttribute(RESOURCE_ENTITY_OWNER) : null; + final String classification = request.getClassification() != null ? + request.getClassification().getTypeName() : null; - setClassificationContextForRanger(rangerTagForEval, rangerRequest); + rangerResource.setValue(RESOURCE_ENTITY_TYPE, entityTypes); + rangerResource.setValue(RESOURCE_ENTITY_ID, entityId); + rangerResource.setOwnerUser(ownerUser); - return rangerRequest; + if (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || + AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) { + rangerResource.setValue(RESOURCE_ENTITY_LABEL, request.getLabel()); + } else if (AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA.equals(request.getAction())) { + rangerResource.setValue(RESOURCE_ENTITY_BUSINESS_METADATA, request.getBusinessMetadata()); + } else if (StringUtils.isNotEmpty(classification) && CLASSIFICATION_PRIVILEGES.contains(request.getAction())) { + rangerResource.setValue(RESOURCE_CLASSIFICATION, + request.getClassificationTypeAndAllSuperTypes(classification)); + } + return rangerResource; } - private static void setClassificationContextForRanger(Set rangerTagForEval, RangerAccessRequestImpl rangerRequest) { - Map contextOjb = rangerRequest.getContext(); + private RangerAccessRequestImpl createRangerAccessRequest(AtlasEntityAccessRequest request, + RangerAccessResourceImpl rangerResource) { - if (contextOjb == null) { - Map contextOjb1 = new HashMap(); - contextOjb1.put("CLASSIFICATIONS", rangerTagForEval); - rangerRequest.setContext(contextOjb1); - } else { - contextOjb.put("CLASSIFICATIONS", rangerTagForEval); - rangerRequest.setContext(contextOjb); - } - } + RangerAccessRequestImpl rangerRequest = new RangerAccessRequestImpl(); - private void initRangerRequest(RangerAccessRequestImpl rangerRequest, AtlasEntityAccessRequest request) { final String action = request.getAction() != null ? request.getAction().getType() : null; rangerRequest.setAccessType(action); @@ -760,29 +760,25 @@ private void initRangerRequest(RangerAccessRequestImpl rangerRequest, AtlasEntit rangerRequest.setAccessTime(request.getAccessTime()); rangerRequest.setForwardedAddresses(request.getForwardedAddresses()); rangerRequest.setRemoteIPAddress(request.getRemoteIPAddress()); - } + rangerRequest.setResource(rangerResource); - private void initRangerResource(RangerAccessResourceImpl rangerResource, AtlasEntityAccessRequest request) { - final Set entityTypes = request.getEntityTypeAndAllSuperTypes(); - final String entityId = request.getEntityId(); - final String ownerUser = request.getEntity() != null ? (String) request.getEntity().getAttribute(RESOURCE_ENTITY_OWNER) : null; - final String classification = request.getClassification() != null ? request.getClassification().getTypeName() : null; + return rangerRequest; - rangerResource.setValue(RESOURCE_ENTITY_TYPE, entityTypes); - rangerResource.setValue(RESOURCE_ENTITY_ID, entityId); - rangerResource.setOwnerUser(ownerUser); + } - if (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) { - rangerResource.setValue(RESOURCE_ENTITY_LABEL, request.getLabel()); - } else if (AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA.equals(request.getAction())) { - rangerResource.setValue(RESOURCE_ENTITY_BUSINESS_METADATA, request.getBusinessMetadata()); - } else if (StringUtils.isNotEmpty(classification) && CLASSIFICATION_PRIVILEGES.contains(request.getAction())) { - rangerResource.setValue(RESOURCE_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classification)); - } + private static void setClassificationContextForRanger(Set rangerTagForEval, RangerAccessRequestImpl rangerRequest) { + Map contextOjb = rangerRequest.getContext(); + if (contextOjb == null) { + Map contextOjb1 = new HashMap(); + contextOjb1.put("CLASSIFICATIONS", rangerTagForEval); + rangerRequest.setContext(contextOjb1); + } else { + contextOjb.put("CLASSIFICATIONS", rangerTagForEval); + rangerRequest.setContext(contextOjb); + } } - private void setClassificationsToRequestContext(Set entityClassifications, RangerAccessRequestImpl rangerRequest) { Map contextOjb = rangerRequest.getContext(); @@ -955,10 +951,12 @@ public RangerAtlasAuditHandler(AtlasEntityAccessRequest request, RangerServiceDe rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, strClassifications); rangerResource.setValue(RESOURCE_ENTITY_ID, request.getEntityId()); - if (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) { + if (AtlasPrivilege.ENTITY_ADD_LABEL.equals(request.getAction()) || + AtlasPrivilege.ENTITY_REMOVE_LABEL.equals(request.getAction())) { rangerResource.setValue(RESOURCE_ENTITY_LABEL, "label=" + request.getLabel()); } else if (AtlasPrivilege.ENTITY_UPDATE_BUSINESS_METADATA.equals(request.getAction())) { - rangerResource.setValue(RESOURCE_ENTITY_BUSINESS_METADATA, "business-metadata=" + request.getBusinessMetadata()); + rangerResource.setValue(RESOURCE_ENTITY_BUSINESS_METADATA, + "business-metadata=" + request.getBusinessMetadata()); } auditEvents = new HashMap<>();