You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by me...@apache.org on 2021/06/14 05:31:16 UTC

[ranger] branch master updated: RANGER-3195 - Atlas Ranger Authorizer changes to add/update/remove classification on entities.

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

mehul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 4bd4290  RANGER-3195 - Atlas Ranger Authorizer changes to add/update/remove classification on entities.
4bd4290 is described below

commit 4bd42903161404552bd5867b376c4fb081df290d
Author: nixonrodrigues <ni...@apache.org>
AuthorDate: Tue Mar 2 18:22:15 2021 +0530

    RANGER-3195 - Atlas Ranger Authorizer changes to add/update/remove classification on entities.
    
    Change-Id: If1eb2882a52c669e9ed101fa58b65f94452e706b
    Signed-off-by: Mehul Parikh <me...@apache.org>
---
 .../service-defs/ranger-servicedef-atlas.json      |  42 ++-
 .../atlas/authorizer/RangerAtlasAuthorizer.java    |  40 +--
 .../ranger/services/atlas/RangerServiceAtlas.java  |   5 +-
 .../optimized/current/ranger_core_db_mysql.sql     |   1 +
 .../optimized/current/ranger_core_db_oracle.sql    |   1 +
 .../optimized/current/ranger_core_db_postgres.sql  |   1 +
 .../current/ranger_core_db_sqlanywhere.sql         |   2 +
 .../optimized/current/ranger_core_db_sqlserver.sql |   1 +
 ...PatchAtlasForClassificationResource_J10047.java | 308 +++++++++++++++++++++
 9 files changed, 370 insertions(+), 31 deletions(-)

diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-atlas.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-atlas.json
index d8331db..7495b79 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-atlas.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-atlas.json
@@ -38,7 +38,7 @@
 			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
 			"matcherOptions": {
 				"wildCard": "true",
-				"ignoreCase": "true"
+				"ignoreCase": "false"
 			},
 			"label": "Type Name",
 			"description": "Type Name",
@@ -56,7 +56,7 @@
 			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
 			"matcherOptions": {
 				"wildCard": "true",
-				"ignoreCase": "true"
+				"ignoreCase": "false"
 			},
 			"label": "Entity Type",
 			"description": "Entity Type"
@@ -74,7 +74,7 @@
 			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
 			"matcherOptions": {
 				"wildCard": "true",
-				"ignoreCase": "true"
+				"ignoreCase": "false"
 			},
 			"label": "Entity Classification",
 			"description": "Entity Classification"
@@ -97,7 +97,7 @@
 			},
 			"label": "Entity ID",
 			"description": "Entity ID",
-			"accessTypeRestrictions": ["entity-read", "entity-create", "entity-update", "entity-delete", "entity-add-classification", "entity-update-classification", "entity-remove-classification"]
+			"accessTypeRestrictions": ["entity-read", "entity-create", "entity-update", "entity-delete"]
 		},
 		{
 			"itemId": 6,
@@ -129,7 +129,7 @@
 			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
 			"matcherOptions": {
 					"wildCard": "true",
-					"ignoreCase": "true"
+					"ignoreCase": "false"
 			},
 			"label": "Relationship Type",
 			"description": "Relationship Type"
@@ -147,7 +147,7 @@
 			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
 			"matcherOptions": {
 				"wildCard": "true",
-				"ignoreCase": "true"
+				"ignoreCase": "false"
 			},
 			"label": "End1 Entity Type",
 			"description": "End1 Entity Type"
@@ -165,7 +165,7 @@
 			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
 			"matcherOptions": {
 				"wildCard": "true",
-				"ignoreCase": "true"
+				"ignoreCase": "false"
 			},
 			"label": "End1 Entity Classification",
 			"description": "End1 Entity Classification"
@@ -201,7 +201,7 @@
 			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
 			"matcherOptions": {
 				"wildCard": "true",
-				"ignoreCase": "true"
+				"ignoreCase": "false"
 			},
 			"label": "End2 Entity Type",
 			"description": "End2 Entity Type"
@@ -219,7 +219,7 @@
 			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
 			"matcherOptions": {
 				"wildCard": "true",
-				"ignoreCase": "true"
+				"ignoreCase": "false"
 			},
 			"label": "End2 Entity Classification",
 			"description": "End2 Entity Classification"
@@ -292,6 +292,30 @@
 			"accessTypeRestrictions": [
 				"entity-update-business-metadata"
 			]
+		},
+		{
+			"itemId": 16,
+			"name": "classification",
+			"type": "string",
+			"level": 40,
+			"mandatory": true,
+			"parent": "entity",
+			"isValidLeaf": true,
+			"lookupSupported": true,
+			"recursiveSupported": false,
+			"excludesSupported": true,
+			"matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+			"matcherOptions": {
+				"wildCard": "true",
+				"ignoreCase": "false"
+			},
+			"label": "Targetted classifications",
+			"description": "Targetted classifications",
+			"accessTypeRestrictions": [
+				"entity-add-classification",
+				"entity-update-classification",
+				"entity-remove-classification"
+			]
 		}
 	],
 	"accessTypes": [
diff --git a/plugin-atlas/src/main/java/org/apache/ranger/authorization/atlas/authorizer/RangerAtlasAuthorizer.java b/plugin-atlas/src/main/java/org/apache/ranger/authorization/atlas/authorizer/RangerAtlasAuthorizer.java
index 79ef604..2fe7338 100644
--- a/plugin-atlas/src/main/java/org/apache/ranger/authorization/atlas/authorizer/RangerAtlasAuthorizer.java
+++ b/plugin-atlas/src/main/java/org/apache/ranger/authorization/atlas/authorizer/RangerAtlasAuthorizer.java
@@ -57,6 +57,12 @@ public class RangerAtlasAuthorizer implements AtlasAuthorizer {
     private static final Log LOG      = LogFactory.getLog(RangerAtlasAuthorizer.class);
     private static final Log PERF_LOG = RangerPerfTracer.getPerfLogger("atlasauth.request");
 
+    private static final  Set<AtlasPrivilege> CLASSIFICATION_PRIVILEGES = new HashSet<AtlasPrivilege>() {{
+        add(AtlasPrivilege.ENTITY_ADD_CLASSIFICATION);
+        add(AtlasPrivilege.ENTITY_REMOVE_CLASSIFICATION);
+        add(AtlasPrivilege.ENTITY_UPDATE_CLASSIFICATION);
+    }};
+
     private static volatile RangerBasePlugin atlasPlugin = null;
 
     @Override
@@ -372,7 +378,7 @@ public class RangerAtlasAuthorizer implements AtlasAuthorizer {
             LOG.debug("==> isAccessAllowed(" + request + ")");
         }
 
-        boolean ret = true;
+        boolean ret = false;
 
         try {
             final String                   action         = request.getAction() != null ? request.getAction().getType() : null;
@@ -400,31 +406,25 @@ public class RangerAtlasAuthorizer implements AtlasAuthorizer {
                 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 (StringUtils.isNotEmpty(classification)) {
-                rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classification));
-
-                ret = checkAccess(rangerRequest, auditHandler);
-            }
-
-            if (ret) {
-                if (CollectionUtils.isNotEmpty(request.getEntityClassifications())) {
-                    // check authorization for each classification
-                    for (String classificationToAuthorize : request.getEntityClassifications()) {
-                        rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize));
+            if (CollectionUtils.isNotEmpty(request.getEntityClassifications())) {
+                // check authorization for each classification
+                for (String classificationToAuthorize : request.getEntityClassifications()) {
+                    rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, request.getClassificationTypeAndAllSuperTypes(classificationToAuthorize));
 
-                        ret = checkAccess(rangerRequest, auditHandler);
+                    ret = checkAccess(rangerRequest, auditHandler);
 
-                        if (!ret) {
-                            break;
-                        }
+                    if (!ret) {
+                        break;
                     }
-                } else {
-                    rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, ENTITY_NOT_CLASSIFIED);
-
-                    ret = checkAccess(rangerRequest, auditHandler);
                 }
+            } else {
+                rangerResource.setValue(RESOURCE_ENTITY_CLASSIFICATION, ENTITY_NOT_CLASSIFIED );
+
+                ret = checkAccess(rangerRequest, auditHandler);
             }
 
         } finally {
diff --git a/plugin-atlas/src/main/java/org/apache/ranger/services/atlas/RangerServiceAtlas.java b/plugin-atlas/src/main/java/org/apache/ranger/services/atlas/RangerServiceAtlas.java
index c13633a..4851d87 100644
--- a/plugin-atlas/src/main/java/org/apache/ranger/services/atlas/RangerServiceAtlas.java
+++ b/plugin-atlas/src/main/java/org/apache/ranger/services/atlas/RangerServiceAtlas.java
@@ -62,6 +62,7 @@ public class RangerServiceAtlas extends RangerBaseService {
 	public static final String RESOURCE_TYPE_NAME                     = "type";
 	public static final String RESOURCE_ENTITY_TYPE                   = "entity-type";
 	public static final String RESOURCE_ENTITY_CLASSIFICATION         = "entity-classification";
+	public static final String RESOURCE_CLASSIFICATION                = "classification";
 	public static final String RESOURCE_ENTITY_ID                     = "entity";
 	public static final String RESOURCE_ENTITY_LABEL                  = "entity-label";
 	public static final String RESOURCE_ENTITY_BUSINESS_METADATA      = "entity-business-metadata";
@@ -172,7 +173,7 @@ public class RangerServiceAtlas extends RangerBaseService {
             }
 
             // 2. add a policy-item for rangertagsync user with 'entity-read' permission in the policy for 'entity-type'
-            if (policyResources.containsKey(RangerServiceAtlas.RESOURCE_ENTITY_TYPE)) {
+            if (policyResources.containsKey(RESOURCE_ENTITY_TYPE) && !policyResources.containsKey(RESOURCE_CLASSIFICATION)) {
                 RangerPolicyItem policyItemForTagSyncUser = new RangerPolicyItem();
 
                 policyItemForTagSyncUser.setUsers(Collections.singletonList(tagSyncUser));
@@ -193,7 +194,7 @@ public class RangerServiceAtlas extends RangerBaseService {
 
 			if (defaultPolicy.getName().contains("all")
 					&& policyResources.containsKey(RangerServiceAtlas.RESOURCE_ENTITY_TYPE)
-					&& StringUtils.isNotBlank(lookUpUser)) {
+					&& StringUtils.isNotBlank(lookUpUser) && !policyResources.containsKey(RESOURCE_CLASSIFICATION)) {
 				RangerPolicyItem policyItemForLookupUser = new RangerPolicyItem();
 				policyItemForLookupUser.setUsers(Collections.singletonList(lookUpUser));
 				policyItemForLookupUser.setAccesses(Collections.singletonList(new RangerPolicyItemAccess(ACCESS_TYPE_ENTITY_READ)));
diff --git a/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql b/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
index 8934549..2024e62 100644
--- a/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
+++ b/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
@@ -1841,6 +1841,7 @@ INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10044',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10045',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10046',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
+INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10047',UTC_TIMESTAMP(),'Ranger 2.2.0',UTC_TIMESTAMP(),'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10049',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10050',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('JAVA_PATCHES',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
diff --git a/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql b/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
index 4cd84ee..d2c4f27 100644
--- a/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
+++ b/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
@@ -2056,6 +2056,7 @@ INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,act
 INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10044',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
 INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10045',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
 INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10046',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
+INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10047',sys_extract_utc(systimestamp),'Ranger 2.2.0',sys_extract_utc(systimestamp),'localhost','Y');
 INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10049',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
 INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'J10050',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
 INSERT INTO x_db_version_h (id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES (X_DB_VERSION_H_SEQ.nextval,'JAVA_PATCHES',sys_extract_utc(systimestamp),'Ranger 1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
diff --git a/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql b/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
index 0e3afbc..0feeb23 100644
--- a/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
+++ b/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
@@ -1980,6 +1980,7 @@ INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10044',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10045',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10046',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
+INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10047',current_timestamp,'Ranger 2.2.0',current_timestamp,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10049',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10050',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('JAVA_PATCHES',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
diff --git a/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql b/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
index aca913d..0ea76b9 100644
--- a/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
+++ b/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
@@ -2405,6 +2405,8 @@ INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active
 GO
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10046',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 GO
+INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10047',CURRENT_TIMESTAMP,'Ranger 2.2.0',CURRENT_TIMESTAMP,'localhost','Y');
+GO
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10049',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 GO
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10050',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
diff --git a/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql b/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
index 300308a..4eaa77c 100644
--- a/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
+++ b/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
@@ -4191,6 +4191,7 @@ INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10044',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10045',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10046',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
+INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10047',CURRENT_TIMESTAMP,'Ranger 2.2.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10049',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('J10050',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_db_version_h (version,inst_at,inst_by,updated_at,updated_by,active) VALUES ('JAVA_PATCHES',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
diff --git a/security-admin/src/main/java/org/apache/ranger/patch/PatchAtlasForClassificationResource_J10047.java b/security-admin/src/main/java/org/apache/ranger/patch/PatchAtlasForClassificationResource_J10047.java
new file mode 100644
index 0000000..e60ff73
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/patch/PatchAtlasForClassificationResource_J10047.java
@@ -0,0 +1,308 @@
+/*
+ * 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.ranger.patch;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.ListIterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Date;
+import org.apache.log4j.Logger;
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.RangerValidatorFactory;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.entity.XXService;
+import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
+import org.apache.ranger.plugin.model.validation.RangerValidator;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.springframework.stereotype.Component;
+import org.springframework.beans.factory.annotation.Autowired;
+import static org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_ATLAS_NAME;
+
+@Component
+public class PatchAtlasForClassificationResource_J10047 extends BaseLoader {
+
+
+    private static final Logger logger = Logger.getLogger(PatchAtlasForClassificationResource_J10047.class);
+
+
+    private static final List<String> ATLAS_RESOURCES = new ArrayList<>(
+            Arrays.asList( "classification"));
+
+    private static final List<String> ATLAS_ACCESS_TYPES = new ArrayList<>(
+            Arrays.asList("entity-remove-classification", "entity-add-classification", "entity-update-classification"));
+
+    private static final List<String> ATLAS_RESOURCE_ENTITY = new ArrayList<>(
+            Arrays.asList("entity-type", "entity-classification", "entity"));
+
+    private static final String ENTITY_CLASSIFICATION = "entity-classification";
+ 
+    private static final String CLASSIFICATION = "classification";
+
+    private static final String ENTITY = "entity";
+
+    private static final List<String> TYPES = new ArrayList<>(
+            Arrays.asList("type", "entity-type", "entity-classification", "relationship-type", "end-one-entity-type",
+                    "end-one-entity-classification","end-two-entity-type","end-two-entity-classification","entity-business-metadata"));
+
+    @Autowired
+    RangerDaoManager daoMgr;
+
+    @Autowired
+    ServiceDBStore svcDBStore;
+
+    @Autowired
+    RangerValidatorFactory validatorFactory;
+
+    @Autowired
+    ServiceDBStore svcStore;
+
+
+    public static void main(String[] args) {
+        logger.info("main()");
+        try {
+            PatchAtlasForClassificationResource_J10047 loader = (PatchAtlasForClassificationResource_J10047) org.apache.ranger.util.CLIUtil
+                    .getBean(PatchAtlasForClassificationResource_J10047.class);
+            loader.init();
+            while (loader.isMoreToProcess()) {
+                loader.load();
+            }
+            logger.info("Load complete. Exiting!!!");
+            System.exit(0);
+        } catch (Exception e) {
+            logger.error("Error loading", e);
+            System.exit(1);
+        }
+    }
+
+    @Override
+    public void init() throws Exception {
+        // Do Nothing
+    }
+
+    @Override
+    public void execLoad() {
+        logger.info("==> PatchAtlasForClassificationResource_J10047.execLoad()");
+        try {
+            addResourceClassificationsInServiceDef();
+            createAdditionalPolicyWithClassificationForExistingEntityClassificationPolicy();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Error while updating " + EMBEDDED_SERVICEDEF_ATLAS_NAME + " service-def");
+        }
+        logger.info("<== PatchAtlasForClassificationResource_J10047.execLoad()");
+    }
+
+    @Override
+    public void printStats() {
+        logger.info("PatchAtlasForClassificationResource_J10047 Logs");
+    }
+
+    private void addResourceClassificationsInServiceDef() throws Exception {
+        RangerServiceDef ret = null;
+        RangerServiceDef embeddedAtlasServiceDef = null;
+        XXServiceDef xXServiceDefObj = null;
+        RangerServiceDef dbAtlasServiceDef = null;
+
+
+        embeddedAtlasServiceDef = EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EMBEDDED_SERVICEDEF_ATLAS_NAME);
+        if (embeddedAtlasServiceDef != null) {
+            xXServiceDefObj = daoMgr.getXXServiceDef().findByName(EMBEDDED_SERVICEDEF_ATLAS_NAME);
+            if (xXServiceDefObj == null) {
+                logger.info(" service-def for "+ EMBEDDED_SERVICEDEF_ATLAS_NAME+" not found. No patching is needed");
+                return;
+            }
+
+            dbAtlasServiceDef = svcDBStore.getServiceDefByName(EMBEDDED_SERVICEDEF_ATLAS_NAME);
+
+            updateResourceInServiceDef(embeddedAtlasServiceDef, dbAtlasServiceDef);
+            updateTypeResourceWithIgnoreCase(dbAtlasServiceDef.getResources());
+            removeEntityResourceAccessTypeRestrictions(dbAtlasServiceDef.getResources());
+
+            RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
+            validator.validate(dbAtlasServiceDef, RangerValidator.Action.UPDATE);
+            ret = svcStore.updateServiceDef(dbAtlasServiceDef);
+            if (ret == null) {
+                logger.error("Error while updating "+EMBEDDED_SERVICEDEF_ATLAS_NAME+"  service-def");
+                throw new RuntimeException("Error while updating " + EMBEDDED_SERVICEDEF_ATLAS_NAME + " service-def");
+            }
+        }
+    }
+
+    private void updateResourceInServiceDef(RangerServiceDef embeddedAtlasServiceDef, RangerServiceDef dbAtlasServiceDef) {
+        List<RangerServiceDef.RangerResourceDef> embeddedAtlasResourceDefs;
+        List<RangerAccessTypeDef> embeddedAtlasAccessTypes;
+        embeddedAtlasResourceDefs = embeddedAtlasServiceDef.getResources();
+        embeddedAtlasAccessTypes = embeddedAtlasServiceDef.getAccessTypes();
+
+        if (!checkResourcePresent(dbAtlasServiceDef.getResources()) && checkResourcePresent(embeddedAtlasResourceDefs)) {
+            dbAtlasServiceDef.setResources(embeddedAtlasResourceDefs);
+            if (checkAccessPresent(embeddedAtlasAccessTypes)) {
+                dbAtlasServiceDef.setAccessTypes(embeddedAtlasAccessTypes);
+            }
+        } else {
+            logger.info("resource already present");
+        }
+    }
+
+    private boolean checkResourcePresent(List<RangerServiceDef.RangerResourceDef> resourceDefs) {
+        boolean ret = false;
+        for (RangerServiceDef.RangerResourceDef resourceDef : resourceDefs) {
+            if (ATLAS_RESOURCES.contains(resourceDef.getName())) {
+                ret = true;
+                break;
+            }
+        }
+        return ret;
+    }
+
+    private boolean checkAccessPresent(List<RangerServiceDef.RangerAccessTypeDef> embeddedAtlasAccessTypes) {
+        boolean ret = false;
+        for (RangerServiceDef.RangerAccessTypeDef accessDef : embeddedAtlasAccessTypes) {
+            if (ATLAS_ACCESS_TYPES.contains(accessDef.getName())) {
+                ret = true;
+                break;
+            }
+        }
+        return ret;
+    }
+
+    private void updateTypeResourceWithIgnoreCase(List<RangerServiceDef.RangerResourceDef> dbSerresourceDefs) {
+        for (RangerServiceDef.RangerResourceDef dbResourceDef : dbSerresourceDefs) {
+            if (TYPES.contains(dbResourceDef.getName())) {
+                dbResourceDef.getMatcherOptions().put("ignoreCase", "false");
+            }
+        }
+    }
+
+    private void removeEntityResourceAccessTypeRestrictions(List<RangerServiceDef.RangerResourceDef> dbSerresourceDefs) {
+        for (RangerServiceDef.RangerResourceDef dbResourceDef : dbSerresourceDefs) {
+            if (ENTITY.equals(dbResourceDef.getName())) {
+                dbResourceDef.getAccessTypeRestrictions().removeAll(ATLAS_ACCESS_TYPES);
+            }
+        }
+    }
+
+    private void createAdditionalPolicyWithClassificationForExistingEntityClassificationPolicy() throws Exception {
+
+        XXServiceDef xXServiceDefObj = daoMgr.getXXServiceDef().findByName(EMBEDDED_SERVICEDEF_ATLAS_NAME);
+
+        if (xXServiceDefObj == null) {
+            logger.debug("ServiceDef not found with name :" + EMBEDDED_SERVICEDEF_ATLAS_NAME);
+            return;
+        }
+
+        Long xServiceDefId = xXServiceDefObj.getId();
+        List<XXService> xxServices = daoMgr.getXXService().findByServiceDefId(xServiceDefId);
+
+        for (XXService xxService : xxServices) {
+
+            List<RangerPolicy> servicePolicies = svcStore.getServicePolicies(xxService.getId(), new SearchFilter());
+
+            for (RangerPolicy policy : servicePolicies) {
+
+                if(!isEntityResource(policy.getResources())){
+                    continue;
+                }
+
+                List<RangerPolicyItem> policyItems = policy.getPolicyItems();
+                List<RangerPolicyItem> denypolicyItems = policy.getDenyPolicyItems();
+
+                boolean policyItemCheck = checkAndFilterNonClassificationAccessTypeFromPolicy(policyItems);
+                boolean denyPolicyItemCheck =  checkAndFilterNonClassificationAccessTypeFromPolicy(denypolicyItems);
+
+                if (policyItemCheck || denyPolicyItemCheck) {
+                    policy.setName(policy.getName() + " - " + CLASSIFICATION);
+
+                    Map<String, RangerPolicyResource> xPolResMap = policy.getResources();
+
+                    RangerPolicyResource resource = xPolResMap.get(ENTITY_CLASSIFICATION);
+
+                    xPolResMap.put(CLASSIFICATION, resource);
+                    policy.setResources(xPolResMap);
+
+                    policy.setVersion(1L);
+                    policy.setGuid(null);
+                    policy.setId(null);
+                    policy.setCreateTime(new Date());
+                    policy.setUpdateTime(new Date());
+
+                    svcStore.createPolicy(policy);
+                    logger.info("New Additional policy created");
+                }
+            }
+        }
+        logger.info("<== createAdditionalPolicyWithClassificationForExistingPolicy");
+    }
+
+    private boolean isEntityResource(Map<String, RangerPolicyResource> xPolResMap) {
+        boolean ret = true;
+
+        if (xPolResMap != null && xPolResMap.size() == ATLAS_RESOURCE_ENTITY.size()){
+            for (String resourceName : ATLAS_RESOURCE_ENTITY) {
+                if (xPolResMap.get(resourceName) == null) {
+                    ret = false;
+                    break;
+                }
+            }
+        }else{
+            ret = false;
+        }
+
+        return ret;
+    }
+
+    private boolean checkAndFilterNonClassificationAccessTypeFromPolicy(List<RangerPolicyItem> policyItems) {
+
+        ListIterator<RangerPolicyItem> policyItemListIterator = policyItems.listIterator();
+        boolean isClassificationAccessTypeExist = false;
+
+        while (policyItemListIterator.hasNext()) {
+            RangerPolicyItem policyItem = policyItemListIterator.next();
+            ListIterator<RangerPolicyItemAccess> itemAccessListIterator = policyItem.getAccesses().listIterator();
+
+            boolean accessPresent = false;
+            while (itemAccessListIterator.hasNext()) {
+                RangerPolicyItemAccess access = itemAccessListIterator.next();
+                if (!ATLAS_ACCESS_TYPES.contains(access.getType())) {
+                    itemAccessListIterator.remove();
+                } else {
+                    accessPresent = true;
+                    isClassificationAccessTypeExist = true;
+                }
+            }
+            if (!accessPresent) {
+                policyItemListIterator.remove();
+            }
+        }
+
+        return isClassificationAccessTypeExist;
+    }
+
+}