You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by dh...@apache.org on 2026/08/15 19:04:16 UTC
(ranger) branch master updated: RANGER-5349: Test Cases for agents-common Module: Packages (plugin.service, plugin.store) (#762)
This is an automated email from the ASF dual-hosted git repository.
dhavalshah9131 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 8cf92131c RANGER-5349: Test Cases for agents-common Module: Packages (plugin.service, plugin.store) (#762)
8cf92131c is described below
commit 8cf92131c8189e777f80573da40ca26ba6ce3057
Author: Rakesh Gupta <ra...@gmail.com>
AuthorDate: Sun Aug 16 00:34:10 2026 +0530
RANGER-5349: Test Cases for agents-common Module: Packages (plugin.service, plugin.store) (#762)
---
.../plugin/service/TestRangerAuthContext.java | 136 +++
.../plugin/service/TestRangerBasePlugin.java | 475 ++++++++-
.../plugin/service/TestRangerBaseService.java | 265 +++++
.../plugin/service/TestRangerChainedPlugin.java | 127 +++
.../service/TestRangerDefaultRequestProcessor.java | 335 +++++++
.../plugin/service/TestRangerDefaultService.java | 53 +
.../plugin/service/TestResourceLookupContext.java | 64 ++
.../ranger/plugin/store/TestAbstractGdsStore.java | 151 +++
.../plugin/store/TestAbstractPredicateUtil.java | 573 +++++++++++
.../plugin/store/TestAbstractServiceStore.java | 1047 ++++++++++++++++++++
.../ranger/plugin/store/TestAbstractTagStore.java | 541 ++++++++++
.../plugin/store/TestEmbeddedServiceDefsUtil.java | 347 +++++++
.../org/apache/ranger/plugin/store/TestPList.java | 101 ++
.../store/TestRangerServiceResourceSignature.java | 116 +++
.../ranger/plugin/store/TestRolePredicateUtil.java | 123 +++
.../store/TestSecurityZonePredicateUtil.java | 67 ++
.../plugin/store/TestServicePredicateUtil.java | 331 +++++++
.../plugin/store/TestStoredServiceResource.java | 61 ++
.../ranger/plugin/store/TestTagPredicateUtil.java | 106 ++
.../ranger/plugin/store/TestTagValidator.java | 315 ++++++
.../store/file/TestGeolocationFileStore.java | 258 +++++
21 files changed, 5590 insertions(+), 2 deletions(-)
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerAuthContext.java b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerAuthContext.java
new file mode 100644
index 000000000..ecfa4352d
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerAuthContext.java
@@ -0,0 +1,136 @@
+/*
+ * 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.plugin.service;
+
+import org.apache.ranger.plugin.model.RangerRole;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
+import org.apache.ranger.plugin.util.RangerRoles;
+import org.apache.ranger.plugin.util.RangerUserStore;
+import org.apache.ranger.ugsyncutil.transform.Mapper;
+import org.apache.ranger.ugsyncutil.util.UgsyncCommonConstants;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for RangerAuthContext class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerAuthContext {
+ public static class NoopMapper implements Mapper {
+ @Override
+ public void init(String baseProperty, List<String> regexPatterns, String regexSeparator) {
+ }
+
+ @Override
+ public String transform(String attrValue) {
+ return attrValue;
+ }
+ }
+
+ @Test
+ public void test1_RoleAggregationForUserAndGroups() {
+ RangerRole roleA = new RangerRole();
+ roleA.setName("roleA");
+ roleA.setUsers(Collections.singletonList(new RangerRole.RoleMember("u1", false)));
+
+ RangerRole roleB = new RangerRole();
+ roleB.setName("roleB");
+ roleB.setGroups(Collections.singletonList(new RangerRole.RoleMember("g1", false)));
+
+ RangerRole roleC = new RangerRole();
+ roleC.setName("roleC");
+ roleC.setGroups(Collections.singletonList(new RangerRole.RoleMember(RangerPolicyEngine.GROUP_PUBLIC, false)));
+
+ Set<RangerRole> rset = new HashSet<>();
+ rset.add(roleA);
+ rset.add(roleB);
+ rset.add(roleC);
+
+ RangerRoles roles = new RangerRoles();
+ roles.setRoleVersion(5L);
+ roles.setRangerRoles(rset);
+
+ RangerAuthContext ctx = new RangerAuthContext(new HashMap<>(), null, roles, new RangerUserStore());
+
+ Set<String> rolesOut = ctx.getRolesForUserAndGroups("u1", Collections.singleton("g1"));
+ assertTrue(rolesOut.contains("roleA"));
+ assertTrue(rolesOut.contains("roleB"));
+ assertTrue(rolesOut.contains("roleC"));
+ assertEquals(5L, ctx.getRoleVersion());
+ }
+
+ @Test
+ public void test2_OnServiceConfigsUpdateSetsTransformers() {
+ RangerAuthContext ctx = new RangerAuthContext(new HashMap<>(), null, new RangerRoles(), new RangerUserStore());
+ Map<String, String> cfg = new HashMap<>();
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_USERNAME_CASE_CONVERSION_PARAM, "lower");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_GROUPNAME_CASE_CONVERSION_PARAM, "upper");
+ ctx.onServiceConfigsUpdate(cfg);
+ assertNotNull(ctx.getUserNameCaseConversion());
+ assertNotNull(ctx.getGroupNameCaseConversion());
+ assertEquals(UgsyncCommonConstants.CaseConversion.TO_LOWER, ctx.getUserNameCaseConversion());
+ assertEquals(UgsyncCommonConstants.CaseConversion.TO_UPPER, ctx.getGroupNameCaseConversion());
+ }
+
+ @Test
+ public void test3_OnServiceConfigsUpdateRegexPatternsAggregation() {
+ RangerAuthContext ctx = new RangerAuthContext(new HashMap<>(), null, new RangerRoles(), new RangerUserStore());
+ Map<String, String> cfg = new HashMap<>();
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_USERNAME_HANDLER, this.getClass().getName() + "$NoopMapper");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_USERNAME, "^(.+)@example\\.com$");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_USERNAME + ".1", "^user_(.+)$");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_SEPARATOR, ":");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_GROUPNAME_HANDLER, this.getClass().getName() + "$NoopMapper");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_GROUPNAME, "^grp_(.+)$");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_GROUPNAME + ".1", "^team_(.+)$");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_SEPARATOR, ":");
+
+ ctx.onServiceConfigsUpdate(cfg);
+
+ // handlers should be set
+ assertNotNull(ctx.getUserNameTransformer());
+ assertNotNull(ctx.getGroupNameTransformer());
+ }
+
+ @Test
+ public void test4_UserStoreVersionPassThrough() {
+ RangerUserStore us = new RangerUserStore();
+ us.setUserStoreVersion(42L);
+ RangerAuthContext ctx = new RangerAuthContext(new HashMap<>(), null, new RangerRoles(), us);
+ assertEquals(42L, ctx.getUserStoreVersion());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBasePlugin.java b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBasePlugin.java
index cd56715cc..674a870e2 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBasePlugin.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBasePlugin.java
@@ -26,17 +26,23 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.audit.provider.AuditHandler;
import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerRole;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerAccessResultProcessor;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs.AccessResult;
+import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.RangerRoles;
@@ -45,15 +51,24 @@
import org.apache.ranger.plugin.util.ServiceGdsInfo;
import org.apache.ranger.plugin.util.ServicePolicies;
import org.apache.ranger.plugin.util.ServiceTags;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -62,7 +77,16 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for RangerBasePlugin class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
public class TestRangerBasePlugin {
static Gson gsonBuilder;
static RangerPolicyEngineOptions peOptions;
@@ -84,10 +108,457 @@ public static void setUpBeforeClass() throws Exception {
}
@Test
- public void testBasePluginHive() throws Exception {
+ public void test1_BasePluginHive() throws Exception {
runTestsFromResourceFile("/plugin/test_base_plugin_hive.json");
}
+ @Test
+ public void test2_MergedResourceACLs() {
+ RangerResourceACLs base = new RangerResourceACLs();
+ RangerResourceACLs chained = new RangerResourceACLs();
+
+ // craft simple ACL entries to verify merge logic does not throw and returns base reference
+ base.setUserAccessInfo("u1", "select", 1, null);
+ chained.setUserAccessInfo("u2", "select", 1, null);
+ base.getDatasets().add("d1");
+ chained.getDatasets().add("d2");
+ base.getProjects().add("p1");
+ chained.getProjects().add("p2");
+
+ RangerResourceACLs merged = RangerBasePlugin.getMergedResourceACLs(base, chained);
+ assertNotNull(merged);
+ assertEquals(base, merged);
+ assertEquals(2, merged.getDatasets().size());
+ assertEquals(2, merged.getProjects().size());
+ assertNotNull(merged.getUserACLs().get("u1"));
+ }
+
+ @Test
+ public void test3_CreateAdminClient_UsesCustomImplIfConfiguredElseFallsBack() {
+ RangerPolicyEngineOptions peOptionsLocal = new RangerPolicyEngineOptions();
+ peOptionsLocal.disablePolicyRefresher = true;
+ peOptionsLocal.disableTagRetriever = true;
+ peOptionsLocal.disableUserStoreRetriever = true;
+ peOptionsLocal.disableGdsInfoRetriever = true;
+
+ RangerPluginConfig cfg = new RangerPluginConfig("hbase", "svc", "app", null, null, peOptionsLocal);
+
+ // Provide REST URL to avoid empty URLs list in REST client
+ cfg.set("ranger.plugin.hbase.policy.rest.url", "http://localhost:6080");
+
+ // invalid class first -> fallback to REST client
+ cfg.set("ranger.plugin.hbase.policy.source.impl", "com.example.DoesNotExist");
+ assertNotNull(RangerBasePlugin.createAdminClient(cfg));
+
+ // set to a valid test implementation
+ cfg.set("ranger.plugin.hbase.policy.source.impl", "org.apache.ranger.plugin.policyengine.RangerAdminClientImpl");
+ assertNotNull(RangerBasePlugin.createAdminClient(cfg));
+ }
+
+ @Test
+ public void test4_GetServiceDefIdWhenNull() {
+ RangerPolicyEngineOptions peOptionsLocal = new RangerPolicyEngineOptions();
+ peOptionsLocal.disablePolicyRefresher = true;
+ RangerPluginConfig pluginConfig = new RangerPluginConfig("dummy", "svc", "app", null, null, peOptionsLocal);
+ RangerBasePlugin plugin = new RangerBasePlugin(pluginConfig);
+ // don't initialize policy engine; getServiceDef() returns null
+ assertEquals(-1, plugin.getServiceDefId());
+ }
+
+ @Test
+ public void test5_LogErrorMessageRateLimit() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("dummy", "svc", "app", null, null, opts);
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+
+ boolean first = plugin.logErrorMessage("E1");
+ boolean second = plugin.logErrorMessage("E1");
+
+ assertEquals(true, first);
+ assertEquals(false, second);
+ }
+
+ @Test
+ public void test6_UGILogin_KeytabMissingThrows() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ RangerPluginConfig cfg = new RangerPluginConfig("dummy", "svc", "app", null, null, opts);
+ String prefix = cfg.getPropertyPrefix() + ".ugi";
+ cfg.set(prefix + ".initialize", "true");
+ cfg.set(prefix + ".login.type", "keytab");
+ // Intentionally do not set principal/keytab to trigger exception
+ assertThrows(RuntimeException.class, () -> new RangerBasePlugin(cfg));
+ }
+
+ @Test
+ public void test7_UGILogin_JaasMissingThrows() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ RangerPluginConfig cfg = new RangerPluginConfig("dummy", "svc", "app", null, null, opts);
+ String prefix = cfg.getPropertyPrefix() + ".ugi";
+ cfg.set(prefix + ".initialize", "true");
+ cfg.set(prefix + ".login.type", "jaas");
+ // Intentionally do not set jaas appconfig to trigger exception
+ assertThrows(RuntimeException.class, () -> new RangerBasePlugin(cfg));
+ }
+
+ @Test
+ public void test8_UGILogin_InvalidTypeNoThrow() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("dummy", "svc", "app", null, null, opts);
+ String prefix = cfg.getPropertyPrefix() + ".ugi";
+ cfg.set(prefix + ".initialize", "true");
+ cfg.set(prefix + ".login.type", "unknown");
+ new RangerBasePlugin(cfg); // should not throw
+ }
+
+ @Test
+ public void test9_IsAccessAllowedCollection_SynchronousRefreshAndResultProcessorCalled() throws Exception {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+ // Build minimal policies with serviceDef and serviceConfig to enable synchronous refresh
+ ServicePolicies policies = new ServicePolicies();
+ policies.setServiceName("svc");
+ policies.setServiceDef(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME));
+ HashMap<String, String> sc = new HashMap<>();
+ sc.put(cfg.getPropertyPrefix() + ".policy.refresh.synchronous", "true");
+ policies.setServiceConfig(sc);
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ plugin.setPolicies(policies);
+
+ RangerAccessResourceImpl res = new RangerAccessResourceImpl();
+ res.setValue("database", "db1");
+ RangerAccessRequestImpl r1 = new RangerAccessRequestImpl();
+ r1.setResource(res);
+ r1.setAccessType("select");
+ RangerAccessRequestImpl r2 = new RangerAccessRequestImpl();
+ r2.setResource(res);
+ r2.setAccessType("update");
+
+ RangerAccessResultProcessor rp = Mockito.mock(RangerAccessResultProcessor.class);
+ List<RangerAccessRequest> reqs = new ArrayList<>();
+ reqs.add(r1);
+ reqs.add(r2);
+
+ Collection<RangerAccessResult> results = plugin.isAccessAllowed(reqs, rp);
+ assertNotNull(results);
+ verify(rp, times(1)).processResults(results);
+ }
+
+ @Test
+ public void test10_MergedACLs_PriorityAndDenyWins() {
+ RangerResourceACLs base = new RangerResourceACLs();
+ RangerResourceACLs chained = new RangerResourceACLs();
+
+ // Prepare policies with different priorities
+ RangerPolicy basePolicyNormal = new RangerPolicy();
+ basePolicyNormal.setPolicyPriority(RangerPolicy.POLICY_PRIORITY_NORMAL);
+ RangerPolicy chainedHigher = new RangerPolicy();
+ chainedHigher.setPolicyPriority(RangerPolicy.POLICY_PRIORITY_OVERRIDE);
+
+ // Case 1: base missing access -> chained should be used
+ chained.setUserAccessInfo("uA", "select", RangerPolicyEvaluator.ACCESS_ALLOWED, chainedHigher);
+ RangerBasePlugin.getMergedResourceACLs(base, chained);
+ AccessResult ar1 = base.getUserACLs().get("uA").get("select");
+ assertNotNull(ar1);
+ assertEquals(RangerPolicyEvaluator.ACCESS_ALLOWED, ar1.getResult());
+
+ // Case 2: both present, chained lower priority and denied -> lower priority should not override higher-priority base allow
+ RangerPolicy basePolicyOverride = new RangerPolicy();
+ basePolicyOverride.setPolicyPriority(RangerPolicy.POLICY_PRIORITY_OVERRIDE);
+ base.setGroupAccessInfo("g1", "update", RangerPolicyEvaluator.ACCESS_ALLOWED, basePolicyOverride);
+ RangerPolicy chainedLower = new RangerPolicy();
+ chainedLower.setPolicyPriority(RangerPolicy.POLICY_PRIORITY_NORMAL);
+ chained.setGroupAccessInfo("g1", "update", RangerPolicyEvaluator.ACCESS_DENIED, chainedLower);
+ RangerBasePlugin.getMergedResourceACLs(base, chained);
+ AccessResult ar2 = base.getGroupACLs().get("g1").get("update");
+ assertEquals(RangerPolicyEvaluator.ACCESS_ALLOWED, ar2.getResult());
+
+ // Case 3: same priority and both allowed -> chained used per code path
+ base.setRoleAccessInfo("r1", "create", RangerPolicyEvaluator.ACCESS_ALLOWED, basePolicyNormal);
+ chained.setRoleAccessInfo("r1", "create", RangerPolicyEvaluator.ACCESS_ALLOWED, chainedLower);
+ RangerBasePlugin.getMergedResourceACLs(base, chained);
+ AccessResult ar3 = base.getRoleACLs().get("r1").get("create");
+ assertEquals(RangerPolicyEvaluator.ACCESS_ALLOWED, ar3.getResult());
+
+ // Case 4: same priority but chained denies and base allowed -> deny should override
+ base.setUserAccessInfo("uB", "drop", RangerPolicyEvaluator.ACCESS_ALLOWED, basePolicyNormal);
+ chained.setUserAccessInfo("uB", "drop", RangerPolicyEvaluator.ACCESS_DENIED, chainedLower);
+ RangerBasePlugin.getMergedResourceACLs(base, chained);
+ AccessResult ar4 = base.getUserACLs().get("uB").get("drop");
+ assertEquals(RangerPolicyEvaluator.ACCESS_DENIED, ar4.getResult());
+ }
+
+ @Test
+ public void test11_RegisterAuthContextListener_NotifiesOnAuthContextChange() throws Exception {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+
+ ServicePolicies policies = new ServicePolicies();
+ policies.setServiceName("svc");
+ policies.setServiceDef(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME));
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+
+ // simple listener that flips a flag when notified
+ final boolean[] notified = new boolean[] {false};
+ plugin.registerAuthContextEventListener(new RangerAuthContextListener() {
+ @Override
+ public void contextChanged() {
+ notified[0] = true;
+ }
+ });
+
+ plugin.setPolicies(policies);
+ assertEquals(true, notified[0]);
+ }
+
+ @Test
+ public void test12_GettersDefaultValuesWithoutPolicyEngine() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("dummy", "svc", "app", null, null, opts);
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+
+ assertEquals(-1L, plugin.getPoliciesVersion());
+ assertEquals(-1L, plugin.getTagsVersion());
+ assertEquals(-1L, plugin.getRolesVersion());
+ assertEquals(-1L, plugin.getUserStoreVersion());
+ assertEquals(null, plugin.getResourceAccessInfo(null));
+ assertEquals(null, plugin.getResourceACLs(null));
+ assertEquals(null, plugin.getRolesFromUserAndGroups("u", new HashSet<>()));
+ assertEquals(null, plugin.getRangerRoles());
+ assertEquals(false, plugin.isServiceAdmin("u"));
+ }
+
+ @Test
+ public void test13_EnrichersReturnNullByDefault() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("dummy", "svc", "app", null, null, opts);
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+
+ assertEquals(null, plugin.getTagEnricher());
+ assertEquals(null, plugin.getUserStoreEnricher());
+ assertEquals(null, plugin.getGdsEnricher());
+ assertEquals(null, plugin.getGdsPolicyEngine());
+ }
+
+ @Test
+ public void test14_IsAccessAllowedSingleRequest_ProcessorIsCalled() throws Exception {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+
+ ServicePolicies policies = new ServicePolicies();
+ policies.setServiceName("svc");
+ policies.setServiceDef(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME));
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ plugin.setPolicies(policies);
+
+ RangerAccessResourceImpl res = new RangerAccessResourceImpl();
+ res.setValue("database", "db1");
+ RangerAccessRequestImpl req = new RangerAccessRequestImpl();
+ req.setResource(res);
+ req.setAccessType("select");
+
+ RangerAccessResultProcessor rp = Mockito.mock(RangerAccessResultProcessor.class);
+ RangerAccessResult ret = plugin.isAccessAllowed(req, rp);
+ assertNotNull(ret);
+ verify(rp, times(1)).processResult(Mockito.any(RangerAccessResult.class));
+ }
+
+ @Test
+ public void test15_GetResourceAccessInfoNonNullWhenInitialized() throws Exception {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+
+ ServicePolicies policies = new ServicePolicies();
+ policies.setServiceName("svc");
+ policies.setServiceDef(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME));
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ plugin.setPolicies(policies);
+
+ RangerAccessResourceImpl res = new RangerAccessResourceImpl();
+ res.setValue("database", "db1");
+ RangerAccessRequestImpl req = new RangerAccessRequestImpl();
+ req.setResource(res);
+ req.setAccessType("select");
+
+ assertNotNull(plugin.getResourceAccessInfo(req));
+ }
+
+ @Test
+ public void test16_GetAuditProviderAlwaysNonNull() {
+ AuditHandler h = RangerBasePlugin.getAuditProvider("svc");
+ assertNotNull(h);
+ }
+
+ @Test
+ public void test17_GetServiceConfigsEmptyByDefault() throws Exception {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+
+ ServicePolicies policies = new ServicePolicies();
+ policies.setServiceName("svc");
+ policies.setServiceDef(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME));
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ plugin.setPolicies(policies);
+ assertEquals(0, plugin.getServiceConfigs().size());
+ }
+
+ @Test
+ public void test18_SetPoliciesNullUsesDefaultPoliciesCreatesEngine() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ // passing null should use default embedded service def for given serviceType
+ plugin.setPolicies(null);
+ assertNotNull(plugin.getServiceDef());
+ assertEquals("svc", plugin.getServiceName());
+ }
+
+ @Test
+ public void test19_RolesMappingAPIsReturnExpected() throws Exception {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+
+ ServicePolicies policies = new ServicePolicies();
+ policies.setServiceName("svc");
+ policies.setServiceDef(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME));
+
+ // build roles: role1 with user u1 and group g1
+ RangerRole role1 = new RangerRole();
+ role1.setName("role1");
+ List<RangerRole.RoleMember> users = new ArrayList<>();
+ users.add(new RangerRole.RoleMember("u1", false));
+ role1.setUsers(users);
+ List<RangerRole.RoleMember> groups = new ArrayList<>();
+ groups.add(new RangerRole.RoleMember("g1", false));
+ role1.setGroups(groups);
+
+ RangerRoles rangerRoles = new RangerRoles();
+ Set<RangerRole> rrset = new HashSet<>();
+ rrset.add(role1);
+ rangerRoles.setRangerRoles(rrset);
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ plugin.setPolicies(policies);
+ plugin.setRoles(rangerRoles);
+
+ Set<String> groupsInput = new HashSet<>();
+ groupsInput.add("gX");
+ Set<String> rolesFromUser = plugin.getRolesFromUserAndGroups("u1", groupsInput);
+ assertNotNull(rolesFromUser);
+ // u1 maps to role1 via users
+ Assertions.assertTrue(rolesFromUser.contains("role1"));
+
+ Set<String> rolesFromGroup = plugin.getRolesFromUserAndGroups(null, new HashSet<>(Arrays.asList("g1")));
+ assertNotNull(rolesFromGroup);
+ Assertions.assertTrue(rolesFromGroup.contains("role1"));
+
+ Set<RangerRole> byUser = plugin.getRangerRoleForPrincipal("u1", "USER");
+ assertNotNull(byUser);
+ Assertions.assertTrue(byUser.stream().anyMatch(r -> "role1".equals(r.getName())));
+
+ Set<RangerRole> byGroup = plugin.getRangerRoleForPrincipal("g1", "GROUP");
+ assertNotNull(byGroup);
+ Assertions.assertTrue(byGroup.stream().anyMatch(r -> "role1".equals(r.getName())));
+ }
+
+ @Test
+ public void test20_EvalAuditPolicies_NoThrowOnNullOrRealResult() throws Exception {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+
+ ServicePolicies policies = new ServicePolicies();
+ policies.setServiceName("svc");
+ policies.setServiceDef(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME));
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ plugin.setPolicies(policies);
+
+ RangerAccessResourceImpl res = new RangerAccessResourceImpl();
+ res.setValue("database", "db1");
+ RangerAccessRequestImpl req = new RangerAccessRequestImpl();
+ req.setResource(res);
+ req.setAccessType("select");
+
+ RangerAccessResult result = plugin.isAccessAllowed(req);
+ plugin.evalAuditPolicies(result);
+ }
+
+ @Test
+ public void test21_BasicGettersNonNull() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ RangerPluginConfig cfg = new RangerPluginConfig("svcType", "svc", "appId", null, null, opts);
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ assertEquals("svcType", plugin.getServiceType());
+ assertEquals("appId", plugin.getAppId());
+ assertNotNull(plugin.getConfig());
+ }
+
+ @Test
+ public void test22_CreateRangerAuthContextNotNullAfterPolicies() throws Exception {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("hive", "svc", "app", null, null, opts);
+
+ ServicePolicies policies = new ServicePolicies();
+ policies.setServiceName("svc");
+ policies.setServiceDef(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HIVE_NAME));
+
+ RangerBasePlugin plugin = new RangerBasePlugin(cfg);
+ plugin.setPolicies(policies);
+ assertNotNull(plugin.createRangerAuthContext());
+ assertNotNull(plugin.getCurrentRangerAuthContext());
+ }
+
private void runTestsFromResourceFile(String resourceFile) throws Exception {
InputStream inStream = this.getClass().getResourceAsStream(resourceFile);
InputStreamReader reader = new InputStreamReader(inStream);
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBaseService.java b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBaseService.java
new file mode 100644
index 000000000..9dd1255f8
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerBaseService.java
@@ -0,0 +1,265 @@
+/*
+ * 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.plugin.service;
+
+import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for RangerBaseService class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerBaseService {
+ public static class DummyService extends RangerBaseService {
+ @Override
+ public Map<String, Object> validateConfig() {
+ Map<String, Object> m = new HashMap<>();
+ m.put("ok", Boolean.TRUE);
+ return m;
+ }
+
+ @Override
+ public List<String> lookupResource(ResourceLookupContext context) {
+ return Collections.singletonList("X");
+ }
+ }
+
+ private RangerServiceDef buildServiceDef() {
+ RangerServiceDef def = new RangerServiceDef();
+ def.setId(1L);
+ def.setName("dummy");
+
+ List<RangerResourceDef> resources = new ArrayList<>();
+ RangerResourceDef db = new RangerResourceDef();
+ db.setName("database");
+ db.setLevel(1);
+ db.setRecursiveSupported(Boolean.TRUE);
+ db.setMandatory(Boolean.TRUE);
+ db.setIsValidLeaf(Boolean.FALSE);
+ RangerResourceDef table = new RangerResourceDef();
+ table.setName("table");
+ table.setLevel(2);
+ table.setParent("database");
+ table.setRecursiveSupported(Boolean.TRUE);
+ table.setMandatory(Boolean.TRUE);
+ table.setIsValidLeaf(Boolean.TRUE);
+ resources.add(db);
+ resources.add(table);
+ def.setResources(resources);
+
+ List<RangerAccessTypeDef> accessTypes = new ArrayList<>();
+ RangerAccessTypeDef select = new RangerAccessTypeDef();
+ select.setName("select");
+ RangerAccessTypeDef update = new RangerAccessTypeDef();
+ update.setName("update");
+ accessTypes.add(select);
+ accessTypes.add(update);
+ def.setAccessTypes(accessTypes);
+
+ Map<String, String> options = new HashMap<>();
+ options.put("create.default.policy.per.hierarchy", "true");
+ def.setOptions(options);
+
+ return def;
+ }
+
+ private RangerService buildService(Map<String, String> configs) {
+ RangerService svc = new RangerService();
+ svc.setName("svc1");
+ svc.setType("dummy");
+ svc.setConfigs(configs);
+ return svc;
+ }
+
+ @Test
+ public void test1_DefaultPoliciesCreatedPerHierarchy() throws Exception {
+ DummyService svc = new DummyService();
+ RangerServiceDef def = buildServiceDef();
+ RangerService service = buildService(new LinkedHashMap<>());
+
+ svc.init(def, service);
+
+ List<RangerPolicy> policies = svc.getDefaultRangerPolicies();
+ assertNotNull(policies);
+ assertTrue(policies.size() >= 1);
+ RangerPolicy p0 = policies.get(0);
+ assertEquals("svc1", p0.getService());
+ assertTrue(p0.getResources().containsKey("database"));
+ assertTrue(p0.getResources().containsKey("table"));
+ assertTrue(p0.getPolicyItems().get(0).getAccesses().stream().anyMatch(a -> "select".equals(a.getType())));
+ }
+
+ @Test
+ public void test2_CreateDefaultPolicyResourceAndAllowedAccesses() {
+ DummyService svc = new DummyService();
+ RangerServiceDef def = buildServiceDef();
+ RangerService service = buildService(new LinkedHashMap<>());
+ svc.init(def, service);
+
+ RangerServiceDefHelper helper = new RangerServiceDefHelper(def);
+ Set<List<RangerResourceDef>> hierarchies = helper.filterHierarchies_containsOnlyMandatoryResources(RangerPolicy.POLICY_TYPE_ACCESS);
+ assertTrue(!hierarchies.isEmpty());
+ List<RangerResourceDef> first = hierarchies.iterator().next();
+
+ Map<String, RangerPolicy.RangerPolicyResource> res = svc.createDefaultPolicyResource(first);
+ assertTrue(res.containsKey("database"));
+ assertTrue(res.get("database").getIsRecursive());
+
+ List<RangerPolicy.RangerPolicyItemAccess> accesses = svc.getAllowedAccesses(res);
+ assertTrue(accesses.stream().anyMatch(a -> "select".equals(a.getType())));
+ assertTrue(accesses.stream().anyMatch(a -> "update".equals(a.getType())));
+ }
+
+ @Test
+ public void test3_CustomDefaultPoliciesFromConfigs() throws Exception {
+ DummyService svc = new DummyService();
+ RangerServiceDef def = buildServiceDef();
+ Map<String, String> cfg = new LinkedHashMap<>();
+ cfg.put("default-policy.1.name", "p-custom");
+ cfg.put("default-policy.1.description", "desc");
+ cfg.put("default-policy.1.isDenyAllElse", "true");
+ cfg.put("default-policy.1.resource.database", "db1,db2");
+ cfg.put("default-policy.1.resource.table", "t1");
+ cfg.put("default-policy.1.policyItem.1.users", "u1,u2");
+ cfg.put("default-policy.1.policyItem.1.groups", "g1");
+ cfg.put("default-policy.1.policyItem.1.roles", "r1");
+ cfg.put("default-policy.1.policyItem.1.accessTypes", "select,update");
+ cfg.put("default-policy.1.policyItem.1.isDelegateAdmin", "true");
+
+ RangerService service = buildService(cfg);
+ svc.init(def, service);
+
+ List<RangerPolicy> policies = svc.getDefaultRangerPolicies();
+ assertNotNull(policies);
+ boolean found = policies.stream().anyMatch(p -> p.getResources().containsKey("database")
+ && p.getResources().containsKey("table")
+ && p.getPolicyItems() != null
+ && p.getPolicyItems().stream().anyMatch(pi -> pi.getAccesses() != null && pi.getAccesses().stream().anyMatch(a -> "select".equals(a.getType()) || "update".equals(a.getType()))));
+ assertTrue(found);
+ }
+
+ @Test
+ public void test4_GetLookupUserKerberosBranches() throws IOException {
+ DummyService svc = new DummyService();
+ RangerAdminConfig rac = RangerAdminConfig.getInstance();
+ String user = svc.getLookupUser("kerberos", rac.get("ranger.lookup.kerberos.principal"), rac.get("ranger.lookup.kerberos.keytab"));
+ assertEquals(null, user);
+ }
+
+ @Test
+ public void test5_CreateDefaultPolicyPerHierarchy_FromServiceAndServiceDefOptions() throws Exception {
+ DummyService svc = new DummyService();
+ RangerServiceDef def = buildServiceDef();
+ // remove option from service-def to test default true
+ def.setOptions(new HashMap<>());
+ Map<String, String> cfg1 = new LinkedHashMap<>();
+ // no explicit config -> should fallback to default true
+ RangerService service1 = buildService(cfg1);
+ svc.init(def, service1);
+ List<RangerPolicy> p1 = svc.getDefaultRangerPolicies();
+ assertFalse(p1.isEmpty());
+
+ // now set service config to false to suppress creation
+ Map<String, String> cfg2 = new LinkedHashMap<>();
+ cfg2.put("create.default.policy.per.hierarchy", "false");
+ RangerService service2 = buildService(cfg2);
+ svc.init(def, service2);
+ List<RangerPolicy> p2 = svc.getDefaultRangerPolicies();
+ assertTrue(p2.isEmpty());
+ }
+
+ @Test
+ public void test6_GetResourcesForPrefix_WithFlags() throws Exception {
+ DummyService svc = new DummyService();
+ RangerServiceDef def = buildServiceDef();
+ Map<String, String> cfg = new LinkedHashMap<>();
+ cfg.put("default-policy.1.name", "p1");
+ cfg.put("default-policy.1.resource.database", "db1,db2");
+ cfg.put("default-policy.1.resource.database.is-excludes", "true");
+ cfg.put("default-policy.1.resource.database.is-recursive", "true");
+ cfg.put("default-policy.1.policyItem.1.users", "u1");
+ cfg.put("default-policy.1.policyItem.1.accessTypes", "select");
+ cfg.put("setup.additional.default.policies", "true");
+ RangerService service = buildService(cfg);
+ svc.init(def, service);
+ List<RangerPolicy> policies = svc.getDefaultRangerPolicies();
+ assertTrue(policies.stream().anyMatch(p -> Boolean.TRUE.equals(p.getResources().get("database").getIsExcludes())
+ && Boolean.TRUE.equals(p.getResources().get("database").getIsRecursive())));
+ }
+
+ @Test
+ public void test7_GetUserAndGroupLists_MergesServiceConfigs() {
+ DummyService svc = new DummyService();
+ RangerServiceDef def = buildServiceDef();
+ Map<String, String> cfg = new LinkedHashMap<>();
+ cfg.put("username", "svcUser");
+ cfg.put("default.policy.users", "u1,u2");
+ cfg.put("default.policy.groups", "g1,g2");
+ RangerService service = buildService(cfg);
+ svc.init(def, service);
+
+ // access private via public API: getDefaultRangerPolicies should include these in first policy item
+ List<RangerPolicy> policies;
+ try {
+ policies = svc.getDefaultRangerPolicies();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ RangerPolicy first = policies.get(0);
+ List<String> users = first.getPolicyItems().get(0).getUsers();
+ List<String> groups = first.getPolicyItems().get(0).getGroups();
+ assertTrue(users.contains("svcUser"));
+ assertTrue(users.contains("u1") && users.contains("u2"));
+ assertTrue(groups.contains("g1") && groups.contains("g2"));
+ }
+
+ @Test
+ public void test8_GetLookupUser_SimpleAuthReturnsNull() throws IOException {
+ DummyService svc = new DummyService();
+ String user = svc.getLookupUser("simple", null, null);
+ assertEquals(null, user);
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerChainedPlugin.java b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerChainedPlugin.java
new file mode 100644
index 000000000..e463d34bd
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerChainedPlugin.java
@@ -0,0 +1,127 @@
+/*
+ * 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.plugin.service;
+
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for RangerChainedPlugin class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerChainedPlugin {
+ private static class NoopChainedPlugin extends RangerChainedPlugin {
+ protected NoopChainedPlugin(RangerBasePlugin rootPlugin, String serviceType, String serviceName) {
+ super(rootPlugin, serviceType, serviceName);
+ }
+
+ @Override
+ public RangerAccessResult isAccessAllowed(RangerAccessRequest request) {
+ return null;
+ }
+
+ @Override
+ public Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests) {
+ return new ArrayList<>();
+ }
+
+ @Override
+ public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
+ return null;
+ }
+
+ @Override
+ public RangerResourceACLs getResourceACLs(RangerAccessRequest request, Integer policyType) {
+ return null;
+ }
+
+ @Override
+ protected RangerBasePlugin buildChainedPlugin(String serviceType, String serviceName, String appId) {
+ return new RangerBasePlugin(new RangerPluginConfig(serviceType, serviceName, appId, null, null, new RangerPolicyEngineOptions())) {
+ @Override
+ public void init() {
+ // no-op to avoid threads
+ }
+ };
+ }
+ }
+
+ @Test
+ public void test1_InitAndBypassFlagDefaultFalse() {
+ // Disable background components via policy engine options in config
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("dummy", "svc", "app", null, null, opts);
+ RangerBasePlugin root = new RangerBasePlugin(cfg) {
+ @Override
+ public void init() {
+ // no-op
+ }
+ };
+ NoopChainedPlugin cp = new NoopChainedPlugin(root, "dummy", "svc2");
+ // Do not call cp.init() to avoid starting threads; just assert defaults and no-ops
+ assertEquals(false, cp.skipAccessCheckIfAlreadyDetermined);
+ assertNull(cp.evalDataMaskPolicies(null));
+ assertNull(cp.evalRowFilterPolicies(null));
+ assertNotNull(cp.isAccessAllowed(new ArrayList<>()));
+ }
+
+ @Test
+ public void test2_IsAuthorizeOnlyWithChainedPluginDefaultFalseAndInitDelegation() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+ opts.disableTagRetriever = true;
+ opts.disableUserStoreRetriever = true;
+ opts.disableGdsInfoRetriever = true;
+ RangerPluginConfig cfg = new RangerPluginConfig("dummy", "svc", "app", null, null, opts);
+
+ RangerBasePlugin root = new RangerBasePlugin(cfg) {
+ @Override
+ public void init() {
+ // no-op
+ }
+ };
+ NoopChainedPlugin cp = new NoopChainedPlugin(root, "dummy", "svc2");
+
+ // call init which should delegate to inner plugin.init() but overridden to no-op
+ cp.init();
+ assertEquals(false, cp.isAuthorizeOnlyWithChainedPlugin());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerDefaultRequestProcessor.java b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerDefaultRequestProcessor.java
new file mode 100644
index 000000000..9b4411722
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerDefaultRequestProcessor.java
@@ -0,0 +1,335 @@
+/*
+ * 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.plugin.service;
+
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
+import org.apache.ranger.plugin.model.RangerRole;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.PolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerMutableResource;
+import org.apache.ranger.plugin.policyengine.RangerPluginContext;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
+import org.apache.ranger.plugin.util.RangerRoles;
+import org.apache.ranger.plugin.util.RangerUserStore;
+import org.apache.ranger.ugsyncutil.transform.Mapper;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for RangerDefaultRequestProcessor class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerDefaultRequestProcessor {
+ private static class TestResource implements RangerMutableResource {
+ private RangerServiceDef serviceDef;
+
+ @Override
+ public void setOwnerUser(String ownerUser) {
+ }
+
+ @Override
+ public void setValue(String type, Object value) {
+ }
+
+ @Override
+ public void setServiceDef(RangerServiceDef serviceDef) {
+ this.serviceDef = serviceDef;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef() {
+ return serviceDef;
+ }
+
+ @Override
+ public Map<String, Object> getAsMap() {
+ return new HashMap<>();
+ }
+
+ @Override
+ public String getAsString() {
+ return "";
+ }
+
+ @Override
+ public Set<String> getKeys() {
+ return new HashSet<>();
+ }
+
+ @Override
+ public Object getValue(String resourceElement) {
+ return null;
+ }
+
+ @Override
+ public String getOwnerUser() {
+ return null;
+ }
+
+ @Override
+ public boolean exists(String name) {
+ return false;
+ }
+
+ @Override
+ public String getLeafName() {
+ return null;
+ }
+
+ @Override
+ public String getCacheKey() {
+ return "";
+ }
+
+ @Override
+ public RangerAccessResource getReadOnlyCopy() {
+ return this;
+ }
+ }
+
+ public static class NoopMapper implements Mapper {
+ @Override
+ public void init(String baseProperty, List<String> regexPatterns, String regexSeparator) {
+ }
+
+ @Override
+ public String transform(String attrValue) {
+ return attrValue;
+ }
+ }
+
+ @Test
+ public void test1_PreProcessSetsClusterAndEmailConversionAndGroups() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+
+ RangerPluginConfig mockCfg = Mockito.mock(RangerPluginConfig.class);
+ Mockito.when(mockCfg.isUseRangerGroups()).thenReturn(true);
+ Mockito.when(mockCfg.isUseOnlyRangerGroups()).thenReturn(false);
+ Mockito.when(mockCfg.isConvertEmailToUsername()).thenReturn(false);
+
+ RangerPluginContext mockPluginCtx = Mockito.mock(RangerPluginContext.class);
+ Mockito.when(mockPluginCtx.getConfig()).thenReturn(mockCfg);
+ Mockito.when(mockPluginCtx.getClusterName()).thenReturn("clX");
+ Mockito.when(mockPluginCtx.getClusterType()).thenReturn("typeY");
+
+ RangerServiceDef sd = new RangerServiceDef();
+ sd.setName("dummy");
+
+ PolicyEngine pe = Mockito.mock(PolicyEngine.class);
+ Mockito.when(pe.getPluginContext()).thenReturn(mockPluginCtx);
+ Mockito.when(pe.getUseForwardedIPAddress()).thenReturn(false);
+ Mockito.when(pe.getTrustedProxyAddresses()).thenReturn(null);
+
+ RangerUserStore us = new RangerUserStore();
+ Map<String, Map<String, String>> userAttrs = new HashMap<>();
+ Map<String, String> attrs = new HashMap<>();
+ attrs.put(RangerCommonConstants.SCRIPT_FIELD__EMAIL_ADDRESS, "user1@example.com");
+ userAttrs.put("user1", attrs);
+ us.setUserAttrMapping(userAttrs);
+ Map<String, Set<String>> ug = new HashMap<>();
+ ug.put("user1@example.com", new HashSet<>(Collections.singletonList("rg1")));
+ us.setUserGroupMapping(ug);
+
+ RangerAuthContext ac = new RangerAuthContext(new HashMap<>(), null, new RangerRoles(), us);
+ Mockito.when(mockPluginCtx.getAuthContext()).thenReturn(ac);
+
+ RangerDefaultRequestProcessor rp = new RangerDefaultRequestProcessor(pe);
+
+ RangerAccessRequestImpl req = new RangerAccessRequestImpl();
+ TestResource tr = new TestResource();
+ tr.setServiceDef(sd);
+ req.setResource(tr);
+ req.setUser("user1@example.com");
+ req.setUserGroups(new HashSet<>(Collections.singletonList("g0")));
+
+ rp.preProcess(req);
+
+ assertEquals("clX", req.getClusterName());
+ assertEquals("typeY", req.getClusterType());
+ assertEquals("user1@example.com", req.getUser());
+ assertNotNull(req.getUserGroups());
+ assertTrue(req.getUserGroups().contains("g0"));
+ assertEquals("user1@example.com", RangerAccessRequestUtil.getCurrentUserFromContext(req.getContext()));
+ }
+
+ @Test
+ public void test2_PreProcessConvertsEmailAndReplacesGroupsAndSetsRoles() {
+ RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();
+ opts.disablePolicyRefresher = true;
+
+ RangerPluginConfig mockCfg = Mockito.mock(RangerPluginConfig.class);
+ Mockito.when(mockCfg.isUseRangerGroups()).thenReturn(true);
+ Mockito.when(mockCfg.isUseOnlyRangerGroups()).thenReturn(true);
+ Mockito.when(mockCfg.isConvertEmailToUsername()).thenReturn(true);
+
+ // Enable name transformation feature flag to allow transformation steps
+ Mockito.when(mockCfg.getPropertyPrefix()).thenReturn("ranger.plugin.dummy");
+ Mockito.when(mockCfg.getBoolean("ranger.plugin.dummy" + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_NAME_TRANSFORMATION, false)).thenReturn(true);
+
+ RangerPluginContext mockPluginCtx = Mockito.mock(RangerPluginContext.class);
+ Mockito.when(mockPluginCtx.getConfig()).thenReturn(mockCfg);
+ Mockito.when(mockPluginCtx.getClusterName()).thenReturn("clA");
+ Mockito.when(mockPluginCtx.getClusterType()).thenReturn("typeB");
+
+ RangerServiceDef sd = new RangerServiceDef();
+ sd.setName("dummy");
+
+ PolicyEngine pe = Mockito.mock(PolicyEngine.class);
+ Mockito.when(pe.getPluginContext()).thenReturn(mockPluginCtx);
+ Mockito.when(pe.getUseForwardedIPAddress()).thenReturn(false);
+ Mockito.when(pe.getTrustedProxyAddresses()).thenReturn(null);
+ Mockito.when(pe.getServiceDef()).thenReturn(sd);
+
+ // Prepare user store mapping for email->username and ranger groups for username
+ RangerUserStore us = new RangerUserStore();
+ Map<String, Map<String, String>> userAttrs = new HashMap<>();
+ Map<String, String> attrs = new HashMap<>();
+ attrs.put(RangerCommonConstants.SCRIPT_FIELD__EMAIL_ADDRESS, "u2@example.com");
+ userAttrs.put("u2", attrs);
+ us.setUserAttrMapping(userAttrs);
+ Map<String, Set<String>> ug = new HashMap<>();
+ ug.put("u2", new HashSet<>(Collections.singletonList("rg9")));
+ us.setUserGroupMapping(ug);
+
+ // Set roles so that roles are computed and populated onto the request when empty
+ RangerRoles roles = new RangerRoles();
+ Set<RangerRole> roleSet = new HashSet<>();
+ RangerRole r = new RangerRole();
+ r.setName("roleX");
+ r.setUsers(Collections.singletonList(new RangerRole.RoleMember("u2", false)));
+ roleSet.add(r);
+ roles.setRangerRoles(roleSet);
+
+ RangerAuthContext ac = new RangerAuthContext(new HashMap<>(), null, roles, us);
+ Mockito.when(mockPluginCtx.getAuthContext()).thenReturn(ac);
+
+ RangerDefaultRequestProcessor rp = new RangerDefaultRequestProcessor(pe);
+
+ RangerAccessRequestImpl req = new RangerAccessRequestImpl();
+ TestResource tr = new TestResource();
+ req.setResource(tr); // serviceDef is null initially to exercise setResourceServiceDef
+ req.setUser("u2@example.com");
+ req.setUserGroups(new HashSet<>(Collections.singletonList("g1")));
+
+ rp.preProcess(req);
+
+ assertEquals("u2", req.getUser()); // email converted to username via user store
+ assertNotNull(req.getUserGroups());
+ assertEquals(1, req.getUserGroups().size());
+ assertTrue(req.getUserGroups().contains("rg9")); // replaced with only ranger groups
+ assertNotNull(req.getUserRoles());
+ assertTrue(req.getUserRoles().contains("roleX"));
+ assertNotNull(((RangerMutableResource) req.getResource()).getServiceDef());
+ }
+
+ @Test
+ public void test3_PreProcessEarlyReturnWhenAlreadyPreprocessed() {
+ RangerPluginContext mockPluginCtx = Mockito.mock(RangerPluginContext.class);
+ RangerPluginConfig mockCfg = Mockito.mock(RangerPluginConfig.class);
+ Mockito.when(mockPluginCtx.getConfig()).thenReturn(mockCfg);
+
+ PolicyEngine pe = Mockito.mock(PolicyEngine.class);
+ Mockito.when(pe.getPluginContext()).thenReturn(mockPluginCtx);
+
+ RangerDefaultRequestProcessor rp = new RangerDefaultRequestProcessor(pe);
+
+ RangerAccessRequestImpl req = new RangerAccessRequestImpl();
+ TestResource tr = new TestResource();
+ req.setResource(tr);
+
+ // mark as already preprocessed
+ RangerAccessRequestUtil.setIsRequestPreprocessed(req.getContext(), Boolean.TRUE);
+
+ rp.preProcess(req);
+
+ // cluster should remain unset due to early return
+ assertEquals(null, req.getClusterName());
+ assertEquals(null, req.getClusterType());
+ }
+
+ @Test
+ public void test4_NameAndGroupCaseConversionWithoutMapper() {
+ RangerPluginConfig mockCfg = Mockito.mock(RangerPluginConfig.class);
+ Mockito.when(mockCfg.isUseRangerGroups()).thenReturn(false);
+ Mockito.when(mockCfg.isUseOnlyRangerGroups()).thenReturn(false);
+ Mockito.when(mockCfg.isConvertEmailToUsername()).thenReturn(false);
+ Mockito.when(mockCfg.getPropertyPrefix()).thenReturn("ranger.plugin.svc");
+ Mockito.when(mockCfg.getBoolean("ranger.plugin.svc" + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_NAME_TRANSFORMATION, false)).thenReturn(true);
+
+ RangerPluginContext mockPluginCtx = Mockito.mock(RangerPluginContext.class);
+ Mockito.when(mockPluginCtx.getConfig()).thenReturn(mockCfg);
+ Mockito.when(mockPluginCtx.getClusterName()).thenReturn("clZ");
+ Mockito.when(mockPluginCtx.getClusterType()).thenReturn("typeZ");
+
+ PolicyEngine pe = Mockito.mock(PolicyEngine.class);
+ Mockito.when(pe.getPluginContext()).thenReturn(mockPluginCtx);
+ Mockito.when(pe.getUseForwardedIPAddress()).thenReturn(false);
+ Mockito.when(pe.getTrustedProxyAddresses()).thenReturn(null);
+
+ RangerAuthContext ac = new RangerAuthContext(new HashMap<>(), null, new RangerRoles(), new RangerUserStore());
+ Map<String, String> cfg = new HashMap<>();
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_USERNAME_CASE_CONVERSION_PARAM, "lower");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_GROUPNAME_CASE_CONVERSION_PARAM, "upper");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_GROUPNAME_HANDLER, this.getClass().getName() + "$NoopMapper");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_GROUPNAME, "(.*)");
+ cfg.put(RangerCommonConstants.PLUGINS_CONF_MAPPING_SEPARATOR, ":");
+ ac.onServiceConfigsUpdate(cfg);
+ Mockito.when(mockPluginCtx.getAuthContext()).thenReturn(ac);
+
+ RangerDefaultRequestProcessor rp = new RangerDefaultRequestProcessor(pe);
+
+ RangerAccessRequestImpl req = new RangerAccessRequestImpl();
+ TestResource tr = new TestResource();
+ req.setResource(tr);
+ req.setUser("USERX");
+ Set<String> groups = new HashSet<>();
+ groups.add("grp");
+ groups.add("Grp2");
+ req.setUserGroups(groups);
+
+ rp.preProcess(req);
+
+ assertEquals("userx", req.getUser());
+ assertTrue(req.getUserGroups().contains("GRP"));
+ assertTrue(req.getUserGroups().contains("GRP2"));
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerDefaultService.java b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerDefaultService.java
new file mode 100644
index 000000000..b09dd9dd4
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestRangerDefaultService.java
@@ -0,0 +1,53 @@
+/*
+ * 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.plugin.service;
+
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for RangerDefaultService class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerDefaultService {
+ @Test
+ public void test1_validateConfigThrows() {
+ RangerDefaultService svc = new RangerDefaultService();
+ Exception ex = assertThrows(Exception.class, svc::validateConfig);
+ assertEquals(RangerDefaultService.ERROR_MSG_VALIDATE_CONFIG_NOT_IMPLEMENTED, ex.getMessage());
+ }
+
+ @Test
+ public void test2_lookupResourceReturnsEmptyList() throws Exception {
+ RangerDefaultService svc = new RangerDefaultService();
+ List<String> res = svc.lookupResource(new ResourceLookupContext());
+ assertEquals(0, res.size());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/service/TestResourceLookupContext.java b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestResourceLookupContext.java
new file mode 100644
index 000000000..eb463303b
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/service/TestResourceLookupContext.java
@@ -0,0 +1,64 @@
+/*
+ * 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.plugin.service;
+
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for ResourceLookupContext class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestResourceLookupContext {
+ @Test
+ public void test1_GettersSettersAndToString() {
+ ResourceLookupContext ctx = new ResourceLookupContext();
+ ctx.setUserInput("abc");
+ ctx.setResourceName("table");
+
+ Map<String, List<String>> resources = new HashMap<>();
+ List<String> vals = new ArrayList<>();
+ vals.add("v1");
+ resources.put("key", vals);
+ ctx.setResources(resources);
+
+ assertEquals("abc", ctx.getUserInput());
+ assertEquals("table", ctx.getResourceName());
+ assertEquals(1, ctx.getResources().get("key").size());
+
+ String s = ctx.toString();
+ assertTrue(s.contains("resourceName=table"));
+ assertTrue(s.contains("userInput=abc"));
+ assertTrue(s.contains("resources={key=[v1]"));
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractGdsStore.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractGdsStore.java
new file mode 100644
index 000000000..cc0cf1c5c
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractGdsStore.java
@@ -0,0 +1,151 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerGds;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for AbstractGdsStore class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestAbstractGdsStore {
+ private static class MyGdsStore extends AbstractGdsStore {
+ @Override
+ public void deleteAllGdsObjectsForService(Long serviceId) {
+ }
+
+ @Override
+ public void deleteAllGdsObjectsForSecurityZone(Long zoneId) {
+ }
+
+ @Override
+ public void onSecurityZoneUpdate(Long zoneId, Collection<String> updatedServices,
+ Collection<String> removedServices) {
+ }
+
+ @Override
+ public List<RangerPolicy> getProjectPolicies(Long projectId) throws Exception {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy addDatasetPolicy(Long datasetId, RangerPolicy policy) throws Exception {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy updateDatasetPolicy(Long datasetId, RangerPolicy policy) throws Exception {
+ return null;
+ }
+
+ @Override
+ public void deleteDatasetPolicy(Long datasetId, Long policyId) throws Exception {
+ }
+
+ @Override
+ public void deleteDatasetPolicies(Long datasetId) throws Exception {
+ }
+
+ @Override
+ public RangerPolicy getDatasetPolicy(Long datasetId, Long policyId) throws Exception {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getDatasetPolicies(Long datasetId) throws Exception {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy addProjectPolicy(Long projectId, RangerPolicy policy) throws Exception {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy updateProjectPolicy(Long projectId, RangerPolicy policy) throws Exception {
+ return null;
+ }
+
+ @Override
+ public void deleteProjectPolicy(Long projectId, Long policyId) throws Exception {
+ }
+
+ @Override
+ public void deleteProjectPolicies(Long projectId) throws Exception {
+ }
+
+ @Override
+ public RangerPolicy getProjectPolicy(Long projectId, Long policyId) throws Exception {
+ return null;
+ }
+ }
+
+ @Test
+ public void test01_defaultReturnsNullsAndNoThrow() throws Exception {
+ MyGdsStore s = new MyGdsStore();
+ Assertions.assertNull(s.createDataset(new RangerGds.RangerDataset()));
+ Assertions.assertNull(s.updateDataset(new RangerGds.RangerDataset()));
+ s.deleteDataset(1L, true);
+ Assertions.assertNull(s.getDataset(1L));
+ Assertions.assertNull(s.getDatasetByName("n"));
+ Assertions.assertNull(s.getDatasetNames(new SearchFilter()));
+ Assertions.assertNull(s.searchDatasets(new SearchFilter()));
+ Assertions.assertNull(s.createProject(new RangerGds.RangerProject()));
+ Assertions.assertNull(s.updateProject(new RangerGds.RangerProject()));
+ s.deleteProject(1L, true);
+ Assertions.assertNull(s.getProject(1L));
+ Assertions.assertNull(s.getProjectByName("p"));
+ Assertions.assertNull(s.getProjectNames(new SearchFilter()));
+ Assertions.assertNull(s.searchProjects(new SearchFilter()));
+ Assertions.assertNull(s.createDataShare(new RangerGds.RangerDataShare()));
+ Assertions.assertNull(s.updateDataShare(new RangerGds.RangerDataShare()));
+ s.deleteDataShare(1L, true);
+ Assertions.assertNull(s.getDataShare(1L));
+ Assertions.assertNull(s.searchDataShares(new SearchFilter()));
+ Assertions.assertNull(s.addSharedResources(null));
+ Assertions.assertNull(s.updateSharedResource(new RangerGds.RangerSharedResource()));
+ s.removeSharedResources(null);
+ Assertions.assertNull(s.getSharedResource(1L));
+ Assertions.assertNull(s.searchSharedResources(new SearchFilter()));
+ Assertions.assertNull(s.addDataShareInDataset(new RangerGds.RangerDataShareInDataset()));
+ Assertions.assertNull(s.updateDataShareInDataset(new RangerGds.RangerDataShareInDataset()));
+ s.removeDataShareInDataset(1L);
+ Assertions.assertNull(s.getDataShareInDataset(1L));
+ Assertions.assertNull(s.searchDataShareInDatasets(new SearchFilter()));
+ Assertions.assertNull(s.addDatasetInProject(new RangerGds.RangerDatasetInProject()));
+ Assertions.assertNull(s.updateDatasetInProject(new RangerGds.RangerDatasetInProject()));
+ s.removeDatasetInProject(1L);
+ Assertions.assertNull(s.getDatasetInProject(1L));
+ Assertions.assertNull(s.searchDatasetInProjects(new SearchFilter()));
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractPredicateUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractPredicateUtil.java
new file mode 100644
index 000000000..9af269dab
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractPredicateUtil.java
@@ -0,0 +1,573 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for AbstractPredicateUtil class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestAbstractPredicateUtil {
+ @Test
+ public void test01_basicFilterByServiceAndPolicy() {
+ RangerPolicy p1 = new RangerPolicy();
+ p1.setId(1L);
+ p1.setService("svc1");
+ p1.setName("read-policy");
+
+ RangerPolicy p2 = new RangerPolicy();
+ p2.setId(2L);
+ p2.setService("svc2");
+ p2.setName("write-policy");
+
+ List<RangerPolicy> list = new ArrayList<>(Arrays.asList(p1, p2));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.SERVICE_NAME, "svc1");
+ f.setParam(SearchFilter.POLICY_NAME_PARTIAL, "read");
+ util.applyFilter(list, f);
+
+ Assertions.assertEquals(1, list.size());
+ Assertions.assertEquals("svc1", list.get(0).getService());
+ }
+
+ @Test
+ public void test02_sortingByPolicyIdDesc() {
+ RangerPolicy p1 = new RangerPolicy();
+ p1.setId(1L);
+ RangerPolicy p2 = new RangerPolicy();
+ p2.setId(3L);
+ RangerPolicy p3 = new RangerPolicy();
+ p3.setId(2L);
+ List<RangerPolicy> list = new ArrayList<>(Arrays.asList(p1, p2, p3));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setSortBy(SearchFilter.POLICY_ID);
+ f.setSortType("desc");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(3L, list.get(0).getId().longValue());
+ Assertions.assertEquals(1L, list.get(2).getId().longValue());
+ }
+
+ @Test
+ public void test03_filterResourcesWildcardMatch() {
+ RangerPolicy p = new RangerPolicy();
+ Map<String, RangerPolicyResource> res = new HashMap<>();
+ res.put("path", new RangerPolicyResource("/data/*"));
+ p.setResources(res);
+ List<RangerPolicy> list = new ArrayList<>(Collections.singletonList(p));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.RESOURCE_PREFIX + "path", "/data/2024");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+ }
+
+ @Test
+ public void test04_rolePredicateUtilByUserGroupRole() {
+ RangerPolicyItem item = new RangerPolicyItem();
+ item.addUser("alice");
+ item.addGroup("analytics");
+ item.addRole("analyst");
+ RangerPolicy p = new RangerPolicy();
+ p.addPolicyItem(item);
+ List<RangerPolicy> policies = new ArrayList<>(Collections.singletonList(p));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.USER, "ali");
+ f.setParam(SearchFilter.GROUP, "lyt");
+ f.setParam(SearchFilter.ROLE, "ana");
+ util.applyFilter(policies, f);
+ Assertions.assertEquals(1, policies.size());
+ }
+
+ @Test
+ public void test05_servicePredicateUtilUsesServiceStore() throws Exception {
+ ServiceStore stub = new ServiceStore() {
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
+ return null;
+ }
+
+ @Override
+ public void deleteServiceDef(Long id, Boolean forceDelete) {
+ }
+
+ @Override
+ public void updateTagServiceDefForAccessTypes() {
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByName(String name) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByDisplayName(String name) {
+ return null;
+ }
+
+ @Override
+ public List<RangerServiceDef> getServiceDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerServiceDef> getPaginatedServiceDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerService createService(RangerService service) {
+ return null;
+ }
+
+ @Override
+ public RangerService updateService(RangerService service, Map<String, Object> options) {
+ return null;
+ }
+
+ @Override
+ public void deleteService(Long id) {
+ }
+
+ @Override
+ public boolean serviceExists(String name) {
+ return false;
+ }
+
+ @Override
+ public RangerService getService(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerService getServiceByName(String name) {
+ RangerService s = new RangerService();
+ s.setName(name);
+ s.setId(100L);
+ s.setType("hive");
+ return s;
+ }
+
+ @Override
+ public RangerService getServiceByDisplayName(String displayName) {
+ return null;
+ }
+
+ @Override
+ public List<RangerService> getServices(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerService> getPaginatedServices(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createDefaultPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy updatePolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy, RangerService service) {
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy) {
+ }
+
+ @Override
+ public boolean policyExists(Long id) {
+ return false;
+ }
+
+ @Override
+ public RangerPolicy getPolicy(Long id) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPolicies(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public Long getPolicyId(Long serviceId, String policyName, Long zoneId) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedPolicies(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesByResourceSignature(String serviceName, String policySignature,
+ Boolean isPolicyEnabled) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(Long serviceId, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(Long serviceId, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(String serviceName, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(String serviceName, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePoliciesIfUpdated(String serviceName,
+ Long lastKnownVersion, boolean needsBackwardCompatibility) {
+ return null;
+ }
+
+ @Override
+ public Long getServicePolicyVersion(String serviceName) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltasOrPolicies(String serviceName,
+ Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltas(String serviceName,
+ Long lastKnownVersion, Long cachedPolicyVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicies(String serviceName,
+ Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy getPolicyFromEventTime(String eventTimeStr, Long policyId) {
+ return null;
+ }
+
+ @Override
+ public Boolean getPopulateExistingBaseFields() {
+ return null;
+ }
+
+ @Override
+ public void setPopulateExistingBaseFields(Boolean populateExistingBaseFields) {
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(String name) {
+ return null;
+ }
+
+ @Override
+ public long getPoliciesCount(String serviceName) {
+ return 0;
+ }
+
+ @Override
+ public Map<String, String> getServiceConfigForPlugin(Long serviceId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesWithMetaAttributes(List<RangerPolicy> policies) {
+ return null;
+ }
+ };
+
+ ServicePredicateUtil util = new ServicePredicateUtil(stub);
+ RangerPolicy pol = new RangerPolicy();
+ pol.setService("svc1");
+ List<RangerPolicy> list = new ArrayList<>(Collections.singletonList(pol));
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.SERVICE_TYPE, "hive");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+ }
+
+ @Test
+ public void test06_securityZonePredicateUtil() {
+ RangerSecurityZone z = new RangerSecurityZone();
+ z.setId(1L);
+ z.setName("zone-a");
+ Map<String, RangerSecurityZone.RangerSecurityZoneService> services = new HashMap<>();
+ services.put("svc1", new RangerSecurityZone.RangerSecurityZoneService());
+ z.setServices(services);
+ z.setCreatedBy("admin");
+ List<RangerSecurityZone> zones = new ArrayList<>(Collections.singletonList(z));
+
+ SecurityZonePredicateUtil util = new SecurityZonePredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.SERVICE_NAME, "svc1");
+ f.setParam(SearchFilter.ZONE_ID, "1");
+ f.setParam(SearchFilter.ZONE_NAME, "zone-a");
+ f.setParam(SearchFilter.NOT_ZONE_NAME, "zone-b");
+ f.setParam(SearchFilter.ZONE_NAME_PARTIAL, "zone");
+ f.setParam(SearchFilter.CREATED_BY, "admin");
+ util.applyFilter(zones, f);
+ Assertions.assertEquals(1, zones.size());
+ }
+
+ @Test
+ public void test07_isRecursivePredicate() {
+ RangerPolicy p = new RangerPolicy();
+ Map<String, RangerPolicyResource> res = new HashMap<>();
+ RangerPolicyResource r = new RangerPolicyResource("/a", false, true);
+ res.put("path", r);
+ p.setResources(res);
+ List<RangerPolicy> list = new ArrayList<>(Collections.singletonList(p));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.IS_RECURSIVE, "true");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+
+ // Now set recursive to false and ensure mismatch when filter is true
+ res.put("path", new RangerPolicyResource("/a", false, false));
+ p.setResources(res);
+ list = new ArrayList<>(Collections.singletonList(p));
+ util.applyFilter(list, f);
+ Assertions.assertEquals(0, list.size());
+ }
+
+ @Test
+ public void test08_policyPriorityFilter() {
+ RangerPolicy p = new RangerPolicy();
+ p.setPolicyPriority(RangerPolicy.POLICY_PRIORITY_OVERRIDE);
+ List<RangerPolicy> list = new ArrayList<>(Collections.singletonList(p));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.POLICY_PRIORITY, RangerPolicy.POLICY_PRIORITY_NAME_OVERRIDE);
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+
+ f.setParam(SearchFilter.POLICY_PRIORITY, RangerPolicy.POLICY_PRIORITY_NAME_NORMAL);
+ list = new ArrayList<>(Collections.singletonList(p));
+ util.applyFilter(list, f);
+ Assertions.assertEquals(0, list.size());
+ }
+
+ @Test
+ public void test09_zoneNamePredicateForPolicy() {
+ RangerPolicy p = new RangerPolicy();
+ p.setZoneName("zone-x");
+ List<RangerPolicy> list = new ArrayList<>(Collections.singletonList(p));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.ZONE_NAME, "zone-x");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+
+ f.setParam(SearchFilter.ZONE_NAME, "other");
+ list = new ArrayList<>(Collections.singletonList(p));
+ util.applyFilter(list, f);
+ Assertions.assertEquals(0, list.size());
+ }
+
+ @Test
+ public void test10_tagServiceNamePredicateForService() {
+ RangerService s = new RangerService();
+ s.setTagService("tagsvc");
+ List<RangerService> list = new ArrayList<>(Collections.singletonList(s));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.TAG_SERVICE_NAME, "tagsvc");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+
+ f.setParam(SearchFilter.TAG_SERVICE_NAME, "other");
+ list = new ArrayList<>(Collections.singletonList(s));
+ util.applyFilter(list, f);
+ Assertions.assertEquals(0, list.size());
+ }
+
+ @Test
+ public void test11_reverseOrderWhenNoSorterButDesc() {
+ RangerPolicy p1 = new RangerPolicy();
+ p1.setId(1L);
+ RangerPolicy p2 = new RangerPolicy();
+ p2.setId(2L);
+ List<RangerPolicy> list = new ArrayList<>(Arrays.asList(p1, p2));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setSortType("desc"); // no sortBy
+ util.applyFilter(list, f);
+ Assertions.assertEquals(2L, list.get(0).getId().longValue());
+ }
+
+ @Test
+ public void test12_isEnabledPredicateTrueAndFalse() {
+ RangerPolicy enabled = new RangerPolicy();
+ enabled.setIsEnabled(true);
+ RangerPolicy disabled = new RangerPolicy();
+ disabled.setIsEnabled(false);
+ List<RangerPolicy> list = new ArrayList<>(Arrays.asList(enabled, disabled));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.IS_ENABLED, "true");
+ List<RangerPolicy> copy = new ArrayList<>(list);
+ util.applyFilter(copy, f);
+ Assertions.assertEquals(1, copy.size());
+ Assertions.assertTrue(copy.get(0).getIsEnabled());
+
+ f.setParam(SearchFilter.IS_ENABLED, "false");
+ copy = new ArrayList<>(list);
+ util.applyFilter(copy, f);
+ Assertions.assertEquals(1, copy.size());
+ Assertions.assertFalse(copy.get(0).getIsEnabled());
+ }
+
+ @Test
+ public void test13_policyResourceContainsMatch() {
+ RangerPolicy p = new RangerPolicy();
+ Map<String, RangerPolicyResource> res = new HashMap<>();
+ res.put("db", new RangerPolicyResource("sales"));
+ p.setResources(res);
+ List<RangerPolicy> list = new ArrayList<>(Collections.singletonList(p));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.POL_RESOURCE, "ale"); // partial in 'sales'
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+ }
+
+ @Test
+ public void test14_resourceSignaturePredicate() {
+ RangerPolicy p = new RangerPolicy();
+ p.setResourceSignature("sig-123");
+ List<RangerPolicy> list = new ArrayList<>(Collections.singletonList(p));
+
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.RESOURCE_SIGNATURE, "sig-123");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+
+ list = new ArrayList<>(Collections.singletonList(p));
+ f.setParam(SearchFilter.RESOURCE_SIGNATURE, "other");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(0, list.size());
+ }
+
+ @Test
+ public void test15_sorterMapOtherSorters() {
+ RangerServiceDef sd1 = new RangerServiceDef();
+ sd1.setName("a");
+ RangerServiceDef sd2 = new RangerServiceDef();
+ sd2.setName("b");
+ List<RangerServiceDef> defs = new ArrayList<>(Arrays.asList(sd2, sd1));
+ AbstractPredicateUtil util = new AbstractPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setSortBy(SearchFilter.SERVICE_TYPE);
+ util.applyFilter(defs, f);
+ Assertions.assertEquals("a", defs.get(0).getName());
+
+ RangerPolicy p1 = new RangerPolicy();
+ p1.setName("alpha");
+ RangerPolicy p2 = new RangerPolicy();
+ p2.setName("beta");
+ List<RangerPolicy> policies = new ArrayList<>(Arrays.asList(p2, p1));
+ f = new SearchFilter();
+ f.setSortBy(SearchFilter.POLICY_NAME);
+ util.applyFilter(policies, f);
+ Assertions.assertEquals("alpha", policies.get(0).getName());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractServiceStore.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractServiceStore.java
new file mode 100644
index 000000000..3f3710ac0
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractServiceStore.java
@@ -0,0 +1,1047 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.apache.ranger.services.tag.RangerServiceTag;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for AbstractServiceStore class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestAbstractServiceStore {
+ public static class MyServiceStore extends AbstractServiceStore {
+ private final List<RangerServiceDef> sds;
+ private final List<RangerService> svcs;
+ private final List<RangerPolicy> pols;
+
+ MyServiceStore(List<RangerServiceDef> sds, List<RangerService> svcs, List<RangerPolicy> pols) {
+ this.sds = sds;
+ this.svcs = svcs;
+ this.pols = pols;
+ }
+
+ @Override
+ protected void updateServicesForServiceDefUpdate(RangerServiceDef serviceDef) {
+ }
+
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
+ return null;
+ }
+
+ @Override
+ public void deleteServiceDef(Long id, Boolean forceDelete) {
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByName(String name) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByDisplayName(String name) {
+ return null;
+ }
+
+ @Override
+ public List<RangerServiceDef> getServiceDefs(SearchFilter filter) {
+ return sds;
+ }
+
+ @Override
+ public PList<RangerServiceDef> getPaginatedServiceDefs(SearchFilter filter) throws Exception {
+ return super.getPaginatedServiceDefs(filter);
+ }
+
+ @Override
+ public RangerService createService(RangerService service) {
+ return null;
+ }
+
+ @Override
+ public RangerService updateService(RangerService service, Map<String, Object> options) {
+ return null;
+ }
+
+ @Override
+ public void deleteService(Long id) {
+ }
+
+ @Override
+ public boolean serviceExists(String name) {
+ return false;
+ }
+
+ @Override
+ public RangerService getService(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerService getServiceByName(String name) {
+ return null;
+ }
+
+ @Override
+ public RangerService getServiceByDisplayName(String displayName) {
+ return null;
+ }
+
+ @Override
+ public List<RangerService> getServices(SearchFilter filter) {
+ return svcs;
+ }
+
+ @Override
+ public PList<RangerService> getPaginatedServices(SearchFilter filter) throws Exception {
+ return super.getPaginatedServices(filter);
+ }
+
+ @Override
+ public RangerPolicy createPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createDefaultPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy updatePolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy, RangerService service) {
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy) {
+ }
+
+ @Override
+ public boolean policyExists(Long id) {
+ return false;
+ }
+
+ @Override
+ public RangerPolicy getPolicy(Long id) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPolicies(SearchFilter filter) {
+ return pols;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedPolicies(SearchFilter filter) throws Exception {
+ return super.getPaginatedPolicies(filter);
+ }
+
+ @Override
+ public Long getPolicyId(Long serviceId, String policyName, Long zoneId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(Long serviceId, SearchFilter filter) {
+ return pols;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(Long serviceId, SearchFilter filter) throws Exception {
+ return super.getPaginatedServicePolicies(serviceId, filter);
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(String serviceName, SearchFilter filter) {
+ return pols;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(String serviceName, SearchFilter filter)
+ throws Exception {
+ return super.getPaginatedServicePolicies(serviceName, filter);
+ }
+
+ @Override
+ public ServicePolicies getServicePoliciesIfUpdated(String serviceName, Long lastKnownVersion,
+ boolean needsBackwardCompatibility) {
+ return null;
+ }
+
+ @Override
+ public Long getServicePolicyVersion(String serviceName) {
+ return super.getServicePolicyVersion(serviceName);
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltasOrPolicies(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltas(String serviceName, Long lastKnownVersion,
+ Long cachedPolicyVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicies(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy getPolicyFromEventTime(String eventTimeStr, Long policyId) {
+ return null;
+ }
+
+ @Override
+ public Boolean getPopulateExistingBaseFields() {
+ return null;
+ }
+
+ @Override
+ public void setPopulateExistingBaseFields(Boolean populateExistingBaseFields) {
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(String name) {
+ return null;
+ }
+
+ @Override
+ public long getPoliciesCount(String serviceName) {
+ return 0;
+ }
+
+ @Override
+ public Map<String, String> getServiceConfigForPlugin(Long serviceId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesWithMetaAttributes(List<RangerPolicy> policies) {
+ return policies;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesByResourceSignature(String serviceName, String policySignature,
+ Boolean isPolicyEnabled) {
+ return pols;
+ }
+ }
+
+ public static class UpdateStore extends MyServiceStore {
+ public RangerServiceDef lastUpdated;
+ private final Long tagId;
+ private final RangerServiceDef tagRef;
+
+ public UpdateStore(List<RangerServiceDef> sds, RangerServiceDef tagRef) {
+ super(sds, new ArrayList<>(), new ArrayList<>());
+ this.tagRef = tagRef;
+ this.tagId = tagRef.getId();
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef(Long id) {
+ return id != null && id.equals(tagId) ? tagRef : null;
+ }
+
+ @Override
+ public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
+ this.lastUpdated = serviceDef;
+ return serviceDef;
+ }
+ }
+
+ public static class CapturingStore extends MyServiceStore {
+ public RangerServiceDef lastUpdated;
+
+ public CapturingStore(List<RangerServiceDef> sds) {
+ super(sds, new ArrayList<>(), new ArrayList<>());
+ }
+
+ @Override
+ public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
+ this.lastUpdated = serviceDef;
+ return serviceDef;
+ }
+ }
+
+ public static class ThrowingServiceStore extends MyServiceStore {
+ public ThrowingServiceStore(List<RangerServiceDef> sds, List<RangerService> svcs, List<RangerPolicy> pols) {
+ super(sds, svcs, pols);
+ }
+
+ @Override
+ public RangerService getServiceByName(String name) {
+ throw new RuntimeException("boom");
+ }
+ }
+
+ public static class DeleteStore extends MyServiceStore {
+ public RangerServiceDef lastUpdated;
+ private final Long tagId;
+ private final RangerServiceDef tagRef;
+
+ public DeleteStore(List<RangerServiceDef> sds, RangerServiceDef tagRef) {
+ super(sds, new ArrayList<>(), new ArrayList<>());
+ this.tagRef = tagRef;
+ this.tagId = tagRef.getId();
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef(Long id) {
+ return id != null && id.equals(tagId) ? tagRef : null;
+ }
+
+ @Override
+ public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
+ this.lastUpdated = serviceDef;
+ return serviceDef;
+ }
+ }
+
+ public static class PostUpdateStore extends UpdateStore {
+ public boolean servicesUpdated;
+
+ public PostUpdateStore(List<RangerServiceDef> sds, RangerServiceDef tagRef) {
+ super(sds, tagRef);
+ }
+
+ @Override
+ protected void updateServicesForServiceDefUpdate(RangerServiceDef serviceDef) {
+ servicesUpdated = true;
+ }
+ }
+
+ @Test
+ public void test01_getNextVersionAndPaginatedHelpers() throws Exception {
+ Assertions.assertEquals(1L, AbstractServiceStore.getNextVersion(null));
+ Assertions.assertEquals(6L, AbstractServiceStore.getNextVersion(5L));
+
+ List<RangerServiceDef> sds = new ArrayList<>(Collections.singletonList(new RangerServiceDef()));
+ List<RangerService> svcs = new ArrayList<>(Collections.singletonList(new RangerService()));
+ List<RangerPolicy> pols = new ArrayList<>(Collections.singletonList(new RangerPolicy()));
+ MyServiceStore store = new MyServiceStore(sds, svcs, pols);
+
+ PList<RangerServiceDef> p1 = store.getPaginatedServiceDefs(new SearchFilter());
+ Assertions.assertEquals(1, p1.getListSize());
+ PList<RangerService> p2 = store.getPaginatedServices(new SearchFilter());
+ Assertions.assertEquals(1, p2.getListSize());
+ PList<RangerPolicy> p3 = store.getPaginatedPolicies(new SearchFilter());
+ Assertions.assertEquals(1, p3.getListSize());
+
+ PList<RangerPolicy> p4 = store.getPaginatedServicePolicies(1L, new SearchFilter());
+ Assertions.assertEquals(1, p4.getListSize());
+ PList<RangerPolicy> p5 = store.getPaginatedServicePolicies("svc", new SearchFilter());
+ Assertions.assertEquals(1, p5.getListSize());
+ }
+
+ @Test
+ public void test02_getServicePolicyVersionHandlesNullService() {
+ List<RangerServiceDef> sds = new ArrayList<>();
+ List<RangerService> svcs = new ArrayList<>();
+ List<RangerPolicy> pols = new ArrayList<>();
+ MyServiceStore store = new MyServiceStore(sds, svcs, pols);
+
+ // getServiceByName returns null in stub; should return null and not throw
+ Assertions.assertNull(store.getServicePolicyVersion("missing"));
+ }
+
+ @Test
+ public void test03_getPaginatedServicePoliciesByNameAndId() throws Exception {
+ List<RangerServiceDef> sds = new ArrayList<>();
+ List<RangerService> svcs = new ArrayList<>();
+ List<RangerPolicy> pols = new ArrayList<>();
+ pols.add(new RangerPolicy());
+ MyServiceStore store = new MyServiceStore(sds, svcs, pols);
+
+ PList<RangerPolicy> pById = store.getPaginatedServicePolicies(5L, new SearchFilter());
+ Assertions.assertEquals(1, pById.getList().size());
+ PList<RangerPolicy> pByName = store.getPaginatedServicePolicies("svc1", new SearchFilter());
+ Assertions.assertEquals(1, pByName.getList().size());
+ }
+
+ @Test
+ public void test04_getServicePolicyVersion_whenGetServiceByNameThrows_returnsNull() {
+ List<RangerServiceDef> sds = new ArrayList<>();
+ List<RangerService> svcs = new ArrayList<>();
+ List<RangerPolicy> pols = new ArrayList<>();
+ ThrowingServiceStore store = new ThrowingServiceStore(sds, svcs, pols);
+
+ Assertions.assertNull(store.getServicePolicyVersion("svc"));
+ }
+
+ @Test
+ public void test05_getPaginatedEmptyLists() throws Exception {
+ List<RangerServiceDef> sds = new ArrayList<>();
+ List<RangerService> svcs = new ArrayList<>();
+ List<RangerPolicy> pols = new ArrayList<>();
+ MyServiceStore store = new MyServiceStore(sds, svcs, pols);
+
+ PList<RangerServiceDef> p1 = store.getPaginatedServiceDefs(new SearchFilter());
+ Assertions.assertEquals(0, p1.getListSize());
+ PList<RangerService> p2 = store.getPaginatedServices(new SearchFilter());
+ Assertions.assertEquals(0, p2.getListSize());
+ PList<RangerPolicy> p3 = store.getPaginatedPolicies(new SearchFilter());
+ Assertions.assertEquals(0, p3.getListSize());
+
+ PList<RangerPolicy> p4 = store.getPaginatedServicePolicies(1L, new SearchFilter());
+ Assertions.assertEquals(0, p4.getListSize());
+ PList<RangerPolicy> p5 = store.getPaginatedServicePolicies("svc", new SearchFilter());
+ Assertions.assertEquals(0, p5.getListSize());
+ }
+
+ @Test
+ public void test06_updateTagServiceDefForAccessTypes_updatesAccessTypesMaskAndRowFilter() throws Exception {
+ // Enable row-filter auto-propagation before store construction
+ RangerAdminConfig.getInstance().set(AbstractServiceStore.AUTOPROPAGATE_ROWFILTERDEF_TO_TAG_PROP, "true");
+
+ // Prepare service def "hdfs" with accessTypes, dataMask and rowFilter
+ RangerServiceDef svcDef = new RangerServiceDef();
+ svcDef.setId(2L);
+ svcDef.setName("hdfs");
+ List<RangerAccessTypeDef> svcAccess = new ArrayList<>();
+ svcAccess.add(new RangerAccessTypeDef(1L, "read", "read", null, null));
+ svcDef.setAccessTypes(svcAccess);
+
+ RangerServiceDef.RangerDataMaskDef svcMaskDef = new RangerServiceDef.RangerDataMaskDef();
+ List<RangerServiceDef.RangerDataMaskTypeDef> maskTypes = new ArrayList<>();
+ maskTypes.add(new RangerServiceDef.RangerDataMaskTypeDef(1L, "MASK", "MASK", null, null, null, null, null));
+ svcMaskDef.setMaskTypes(maskTypes);
+ List<RangerAccessTypeDef> maskAccess = new ArrayList<>();
+ maskAccess.add(new RangerAccessTypeDef(2L, "read", "read", null, null));
+ svcMaskDef.setAccessTypes(maskAccess);
+ svcDef.setDataMaskDef(svcMaskDef);
+
+ RangerServiceDef.RangerRowFilterDef svcRowDef = new RangerServiceDef.RangerRowFilterDef();
+ List<RangerAccessTypeDef> rowAccess = new ArrayList<>();
+ rowAccess.add(new RangerAccessTypeDef(3L, "select", "select", null, null));
+ svcRowDef.setAccessTypes(rowAccess);
+ svcDef.setRowFilterDef(svcRowDef);
+
+ // Prepare tag service-def with TAG resource
+ RangerServiceDef tagDef = new RangerServiceDef();
+ tagDef.setId(500L);
+ tagDef.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+ List<RangerServiceDef.RangerResourceDef> tagResources = new ArrayList<>();
+ RangerServiceDef.RangerResourceDef tagRes = new RangerServiceDef.RangerResourceDef();
+ tagRes.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+ tagResources.add(tagRes);
+ tagDef.setResources(tagResources);
+
+ List<RangerServiceDef> sds = new ArrayList<>();
+ sds.add(svcDef);
+ UpdateStore store = new UpdateStore(sds, tagDef);
+
+ // Wire EmbeddedServiceDefsUtil.tagServiceDef via reflection so
+ // getTagServiceDefId() matches
+ Field f = EmbeddedServiceDefsUtil.class.getDeclaredField("tagServiceDef");
+ f.setAccessible(true);
+ f.set(EmbeddedServiceDefsUtil.instance(), tagDef);
+
+ store.updateTagServiceDefForAccessTypes();
+
+ Assertions.assertNotNull(store.lastUpdated);
+ // Access types propagated with prefix
+ Assertions.assertTrue(tagDef.getAccessTypes().stream().anyMatch(a -> "hdfs:read".equals(a.getName())));
+ // Data mask: mask type added with prefixed name and itemId offset 2*(1000+1)+1
+ // = 2003
+ RangerServiceDef.RangerDataMaskDef updatedMaskDef = tagDef.getDataMaskDef();
+ Assertions.assertTrue(updatedMaskDef.getMaskTypes().stream().anyMatch(m -> "hdfs:MASK".equals(m.getName())));
+ Assertions.assertEquals(1, updatedMaskDef.getResources().size());
+ Assertions.assertEquals(RangerServiceTag.TAG_RESOURCE_NAME, updatedMaskDef.getResources().get(0).getName());
+ // Row filter propagated and resources set due to auto-propagation
+ RangerServiceDef.RangerRowFilterDef updatedRowDef = tagDef.getRowFilterDef();
+ Assertions.assertTrue(updatedRowDef.getAccessTypes().stream().anyMatch(a -> "hdfs:select".equals(a.getName())));
+ Assertions.assertEquals(1, updatedRowDef.getResources().size());
+ Assertions.assertEquals(RangerServiceTag.TAG_RESOURCE_NAME, updatedRowDef.getResources().get(0).getName());
+ }
+
+ @Test
+ public void test07_updateTagServiceDefForAccessTypes_tagServiceDefMissing_noUpdate() throws Exception {
+ // Ensure EmbeddedServiceDefsUtil has no tag service-def
+ Field f = EmbeddedServiceDefsUtil.class.getDeclaredField("tagServiceDef");
+ f.setAccessible(true);
+ f.set(EmbeddedServiceDefsUtil.instance(), null);
+
+ RangerServiceDef svcDef = new RangerServiceDef();
+ svcDef.setId(1L);
+ svcDef.setName("hdfs");
+ svcDef.setAccessTypes(new ArrayList<>());
+
+ List<RangerServiceDef> sds = new ArrayList<>();
+ sds.add(svcDef);
+ CapturingStore store = new CapturingStore(sds);
+
+ store.updateTagServiceDefForAccessTypes();
+
+ Assertions.assertNull(store.lastUpdated);
+ }
+
+ @Test
+ public void test08_postDelete_removesPrefixedAccessTypesAndClearsResourcesWhenEmpty() throws Exception {
+ // Prepare tag service-def with resources and some prefixed entries
+ RangerServiceDef tagDef = new RangerServiceDef();
+ tagDef.setId(600L);
+ tagDef.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+ List<RangerServiceDef.RangerResourceDef> tagResources = new ArrayList<>();
+ RangerServiceDef.RangerResourceDef tagRes = new RangerServiceDef.RangerResourceDef();
+ tagRes.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+ tagResources.add(tagRes);
+ tagDef.setResources(tagResources);
+
+ List<RangerAccessTypeDef> tagAccess = new ArrayList<>();
+ tagAccess.add(new RangerAccessTypeDef(1L, "hdfs:read", "hdfs:read", null, null));
+ tagAccess.add(new RangerAccessTypeDef(2L, "kafka:publish", "kafka:publish", null, null));
+ tagAccess.add(new RangerAccessTypeDef(3L, "hdfs:write", "hdfs:write", null, null));
+ tagDef.setAccessTypes(tagAccess);
+
+ RangerServiceDef.RangerDataMaskDef tagMask = new RangerServiceDef.RangerDataMaskDef();
+ List<RangerAccessTypeDef> maskAccess = new ArrayList<>();
+ maskAccess.add(new RangerAccessTypeDef(10L, "hdfs:read", "hdfs:read", null, null));
+ tagMask.setAccessTypes(maskAccess);
+ List<RangerServiceDef.RangerDataMaskTypeDef> maskTypes = new ArrayList<>();
+ maskTypes.add(new RangerServiceDef.RangerDataMaskTypeDef(11L, "hdfs:MASK", "hdfs:MASK", null, null, null, null,
+ null));
+ tagMask.setMaskTypes(maskTypes);
+ List<RangerServiceDef.RangerResourceDef> maskRes = new ArrayList<>();
+ maskRes.add(tagRes);
+ tagMask.setResources(maskRes);
+ tagDef.setDataMaskDef(tagMask);
+
+ RangerServiceDef.RangerRowFilterDef tagRow = new RangerServiceDef.RangerRowFilterDef();
+ List<RangerAccessTypeDef> rowAccess = new ArrayList<>();
+ rowAccess.add(new RangerAccessTypeDef(20L, "hdfs:select", "hdfs:select", null, null));
+ tagRow.setAccessTypes(rowAccess);
+ List<RangerServiceDef.RangerResourceDef> rowRes = new ArrayList<>();
+ rowRes.add(tagRes);
+ tagRow.setResources(rowRes);
+ tagDef.setRowFilterDef(tagRow);
+
+ // Set tag service-def in EmbeddedServiceDefsUtil
+ Field f = EmbeddedServiceDefsUtil.class.getDeclaredField("tagServiceDef");
+ f.setAccessible(true);
+ f.set(EmbeddedServiceDefsUtil.instance(), tagDef);
+
+ RangerServiceDef svcDef = new RangerServiceDef();
+ svcDef.setId(2L);
+ svcDef.setName("hdfs");
+
+ List<RangerServiceDef> sds = new ArrayList<>();
+ sds.add(svcDef);
+ DeleteStore store = new DeleteStore(sds, tagDef);
+
+ store.postDelete(svcDef);
+
+ Assertions.assertNotNull(store.lastUpdated);
+ // Prefixed access types removed
+ Assertions.assertTrue(tagDef.getAccessTypes().stream().noneMatch(a -> a.getName().startsWith("hdfs:")));
+ Assertions.assertTrue(tagDef.getAccessTypes().stream().anyMatch(a -> a.getName().equals("kafka:publish")));
+ // Data mask and row filter entries for hdfs removed; since accessTypes become
+ // empty, resources should be cleared by updateResourceInTagServiceDef
+ Assertions.assertTrue(tagDef.getDataMaskDef().getAccessTypes().isEmpty());
+ Assertions.assertTrue(tagDef.getDataMaskDef().getMaskTypes().isEmpty());
+ Assertions.assertTrue(tagDef.getDataMaskDef().getResources().isEmpty());
+ Assertions.assertTrue(tagDef.getRowFilterDef().getAccessTypes().isEmpty());
+ Assertions.assertTrue(tagDef.getRowFilterDef().getResources().isEmpty());
+ }
+
+ @Test
+ public void test09_postCreate_updatesTagServiceDef_whenServiceDefCreated() throws Exception {
+ RangerServiceDef svcDef = new RangerServiceDef();
+ svcDef.setId(3L);
+ svcDef.setName("hdfs");
+ List<RangerAccessTypeDef> svcAccess = new ArrayList<>();
+ svcAccess.add(new RangerAccessTypeDef(1L, "read", "read", null, null));
+ svcDef.setAccessTypes(svcAccess);
+
+ RangerServiceDef tagDef = new RangerServiceDef();
+ tagDef.setId(700L);
+ tagDef.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+ List<RangerServiceDef.RangerResourceDef> tagResources = new ArrayList<>();
+ RangerServiceDef.RangerResourceDef tagRes = new RangerServiceDef.RangerResourceDef();
+ tagRes.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+ tagResources.add(tagRes);
+ tagDef.setResources(tagResources);
+
+ List<RangerServiceDef> sds = new ArrayList<>();
+ sds.add(svcDef);
+ UpdateStore store = new UpdateStore(sds, tagDef);
+
+ Field f = EmbeddedServiceDefsUtil.class.getDeclaredField("tagServiceDef");
+ f.setAccessible(true);
+ f.set(EmbeddedServiceDefsUtil.instance(), tagDef);
+
+ store.postCreate(svcDef);
+
+ Assertions.assertNotNull(store.lastUpdated);
+ Assertions.assertTrue(tagDef.getAccessTypes().stream().anyMatch(a -> "hdfs:read".equals(a.getName())));
+ }
+
+ @Test
+ public void test10_postCreate_nonServiceDef_noop() throws Exception {
+ RangerServiceDef tagDef = new RangerServiceDef();
+ tagDef.setId(701L);
+ tagDef.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+
+ List<RangerServiceDef> sds = new ArrayList<>();
+ UpdateStore store = new UpdateStore(sds, tagDef);
+
+ Field f = EmbeddedServiceDefsUtil.class.getDeclaredField("tagServiceDef");
+ f.setAccessible(true);
+ f.set(EmbeddedServiceDefsUtil.instance(), tagDef);
+
+ store.postCreate(new RangerPolicy());
+ Assertions.assertNull(store.lastUpdated);
+ }
+
+ @Test
+ public void test11_postUpdate_updatesTagServiceDef_andInvokesServicesUpdate() throws Exception {
+ RangerServiceDef svcDef = new RangerServiceDef();
+ svcDef.setId(4L);
+ svcDef.setName("kafka");
+ List<RangerAccessTypeDef> svcAccess = new ArrayList<>();
+ svcAccess.add(new RangerAccessTypeDef(1L, "publish", "publish", null, null));
+ svcDef.setAccessTypes(svcAccess);
+
+ RangerServiceDef tagDef = new RangerServiceDef();
+ tagDef.setId(702L);
+ tagDef.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+
+ List<RangerServiceDef> sds = new ArrayList<>();
+ sds.add(svcDef);
+ PostUpdateStore store = new PostUpdateStore(sds, tagDef);
+
+ Field f = EmbeddedServiceDefsUtil.class.getDeclaredField("tagServiceDef");
+ f.setAccessible(true);
+ f.set(EmbeddedServiceDefsUtil.instance(), tagDef);
+
+ store.postUpdate(svcDef);
+
+ Assertions.assertNotNull(store.lastUpdated);
+ Assertions.assertTrue(store.servicesUpdated);
+ Assertions.assertTrue(tagDef.getAccessTypes().stream().anyMatch(a -> "kafka:publish".equals(a.getName())));
+ }
+
+ @Test
+ public void test12_postUpdate_nonServiceDef_noop() throws Exception {
+ RangerServiceDef tagDef = new RangerServiceDef();
+ tagDef.setId(703L);
+ tagDef.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+
+ List<RangerServiceDef> sds = new ArrayList<>();
+ PostUpdateStore store = new PostUpdateStore(sds, tagDef);
+
+ Field f = EmbeddedServiceDefsUtil.class.getDeclaredField("tagServiceDef");
+ f.setAccessible(true);
+ f.set(EmbeddedServiceDefsUtil.instance(), tagDef);
+
+ store.postUpdate(new RangerPolicy());
+ Assertions.assertNull(store.lastUpdated);
+ Assertions.assertFalse(store.servicesUpdated);
+ }
+
+ @Test
+ public void test13_getServicePolicyVersion_success() {
+ List<RangerServiceDef> sds = new ArrayList<>();
+ List<RangerPolicy> pols = new ArrayList<>();
+ List<RangerService> svcs = new ArrayList<>();
+
+ MyServiceStore store = new MyServiceStore(sds, svcs, pols) {
+ @Override
+ public Long getServicePolicyVersion(String serviceName) {
+ return super.getServicePolicyVersion(serviceName);
+ }
+
+ @Override
+ public RangerService getServiceByName(String name) {
+ RangerService svc = new RangerService();
+ svc.setPolicyVersion(9L);
+ return svc;
+ }
+ };
+
+ Assertions.assertEquals(9L, store.getServicePolicyVersion("svc"));
+ }
+
+ @Test
+ public void test14_updateTagAccessTypeDef_noChange_returnsFalse() throws Exception {
+ MyServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ RangerAccessTypeDef svcAccess = new RangerAccessTypeDef(1L, "read", "lbl", "rb", null);
+ List<String> svcImplied = new ArrayList<>();
+ svcImplied.add("write");
+ svcAccess.setImpliedGrants(svcImplied);
+
+ RangerAccessTypeDef tagAccess = new RangerAccessTypeDef(1001L, "hdfs:read", "lbl", "rb", null);
+ List<String> tagImplied = new ArrayList<>();
+ tagImplied.add("hdfs:write");
+ tagAccess.setImpliedGrants(tagImplied);
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagAccessTypeDef",
+ RangerAccessTypeDef.class,
+ RangerAccessTypeDef.class,
+ String.class);
+ m.setAccessible(true);
+
+ Boolean updated = (Boolean) m.invoke(store, tagAccess, svcAccess, "hdfs:");
+ Assertions.assertFalse(updated);
+ Assertions.assertEquals("hdfs:read", tagAccess.getName());
+ Assertions.assertEquals("lbl", tagAccess.getLabel());
+ Assertions.assertEquals("rb", tagAccess.getRbKeyLabel());
+ Assertions.assertTrue(tagAccess.getImpliedGrants().contains("hdfs:write"));
+ }
+
+ @Test
+ public void test15_updateTagAccessTypeDef_nameDiff_updatesAndPrefixesImpliedGrants() throws Exception {
+ MyServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ RangerAccessTypeDef svcAccess = new RangerAccessTypeDef(1L, "read", "lbl2", "rb2", null);
+ List<String> svcImplied = new ArrayList<>();
+ svcImplied.add("write");
+ svcImplied.add("execute");
+ svcAccess.setImpliedGrants(svcImplied);
+
+ RangerAccessTypeDef tagAccess = new RangerAccessTypeDef(1001L, "other", "old", "oldrb", null);
+ List<String> tagImplied = new ArrayList<>();
+ tagImplied.add("hdfs:old");
+ tagAccess.setImpliedGrants(tagImplied);
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagAccessTypeDef",
+ RangerAccessTypeDef.class,
+ RangerAccessTypeDef.class,
+ String.class);
+ m.setAccessible(true);
+
+ Boolean updated = (Boolean) m.invoke(store, tagAccess, svcAccess, "hdfs:");
+ Assertions.assertTrue(updated);
+ Assertions.assertEquals("hdfs:read", tagAccess.getName());
+ Assertions.assertEquals("lbl2", tagAccess.getLabel());
+ Assertions.assertEquals("rb2", tagAccess.getRbKeyLabel());
+ Assertions.assertTrue(tagAccess.getImpliedGrants().contains("hdfs:write"));
+ Assertions.assertTrue(tagAccess.getImpliedGrants().contains("hdfs:execute"));
+ }
+
+ @Test
+ public void test16_updateTagAccessTypeDef_impliedGrantMissing_updates() throws Exception {
+ MyServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ RangerAccessTypeDef svcAccess = new RangerAccessTypeDef(1L, "read", "lbl", "rb", null);
+ List<String> svcImplied = new ArrayList<>();
+ svcImplied.add("write");
+ svcImplied.add("execute");
+ svcAccess.setImpliedGrants(svcImplied);
+
+ // tag has correct name/labels but only one implied grant; missing one should trigger update via inner loop
+ RangerAccessTypeDef tagAccess = new RangerAccessTypeDef(1001L, "hdfs:read", "lbl", "rb", null);
+ List<String> tagImplied = new ArrayList<>();
+ tagImplied.add("hdfs:write");
+ tagAccess.setImpliedGrants(tagImplied);
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagAccessTypeDef",
+ RangerAccessTypeDef.class,
+ RangerAccessTypeDef.class,
+ String.class);
+ m.setAccessible(true);
+
+ Boolean updated = (Boolean) m.invoke(store, tagAccess, svcAccess, "hdfs:");
+ Assertions.assertTrue(updated);
+ Assertions.assertTrue(tagAccess.getImpliedGrants().contains("hdfs:write"));
+ Assertions.assertTrue(tagAccess.getImpliedGrants().contains("hdfs:execute"));
+ }
+
+ @Test
+ public void test17_updateTagAccessTypeDef_labelOrRbKeyDiff_updates() throws Exception {
+ MyServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ // Same name once prefix is removed, but label differs
+ RangerAccessTypeDef svcAccess = new RangerAccessTypeDef(1L, "read", "newLbl", "newRb", null);
+ List<String> svcImplied = new ArrayList<>();
+ svcImplied.add("write");
+ svcAccess.setImpliedGrants(svcImplied);
+
+ RangerAccessTypeDef tagAccess = new RangerAccessTypeDef(1001L, "hdfs:read", "oldLbl", "oldRb", null);
+ List<String> tagImplied = new ArrayList<>();
+ tagImplied.add("hdfs:write");
+ tagAccess.setImpliedGrants(tagImplied);
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagAccessTypeDef",
+ RangerAccessTypeDef.class,
+ RangerAccessTypeDef.class,
+ String.class);
+ m.setAccessible(true);
+
+ Boolean updated = (Boolean) m.invoke(store, tagAccess, svcAccess, "hdfs:");
+ Assertions.assertTrue(updated);
+ Assertions.assertEquals("hdfs:read", tagAccess.getName());
+ Assertions.assertEquals("newLbl", tagAccess.getLabel());
+ Assertions.assertEquals("newRb", tagAccess.getRbKeyLabel());
+ Assertions.assertTrue(tagAccess.getImpliedGrants().contains("hdfs:write"));
+ }
+
+ @Test
+ void test18_findAccessTypeDef_found() throws Exception {
+ AbstractServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ List<RangerAccessTypeDef> list = new ArrayList<>();
+ list.add(new RangerAccessTypeDef(1L, "a", "a", null, null));
+ list.add(new RangerAccessTypeDef(2L, "b", "b", null, null));
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("findAccessTypeDef", long.class, List.class);
+ m.setAccessible(true);
+
+ Object ret = m.invoke(store, 2L, list);
+ Assertions.assertNotNull(ret);
+ Assertions.assertEquals(2L, ((RangerAccessTypeDef) ret).getItemId());
+ }
+
+ @Test
+ void test19_findAccessTypeDef_notFound() throws Exception {
+ AbstractServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ List<RangerAccessTypeDef> list = new ArrayList<>();
+ list.add(new RangerAccessTypeDef(3L, "a", "a", null, null));
+ list.add(new RangerAccessTypeDef(4L, "b", "b", null, null));
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("findAccessTypeDef", long.class, List.class);
+ m.setAccessible(true);
+
+ Object ret = m.invoke(store, 2L, list);
+ Assertions.assertNull(ret);
+ }
+
+ @Test
+ void test20_updateTagAccessTypeDefs_addsMissingFromSvc() throws Exception {
+ AbstractServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ List<RangerAccessTypeDef> svc = new ArrayList<>();
+ RangerAccessTypeDef svcRead = new RangerAccessTypeDef(1L, "read", "lbl", "rb", null);
+ List<String> svcImpl = new ArrayList<>();
+ svcImpl.add("write");
+ svcRead.setImpliedGrants(svcImpl);
+ svc.add(svcRead);
+
+ List<RangerAccessTypeDef> tag = new ArrayList<>();
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagAccessTypeDefs", List.class, List.class, long.class, String.class);
+ m.setAccessible(true);
+
+ Boolean updated = (Boolean) m.invoke(store, svc, tag, 100L, "hdfs:");
+ Assertions.assertTrue(updated);
+ Assertions.assertEquals(1, tag.size());
+ Assertions.assertEquals(Long.valueOf(101L), tag.get(0).getItemId());
+ Assertions.assertEquals("hdfs:read", tag.get(0).getName());
+ Assertions.assertTrue(tag.get(0).getImpliedGrants().contains("hdfs:write"));
+ }
+
+ @Test
+ void test21_updateTagAccessTypeDefs_updatesChangedEntries() throws Exception {
+ AbstractServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ List<RangerAccessTypeDef> svc = new ArrayList<>();
+ RangerAccessTypeDef svcRead = new RangerAccessTypeDef(2L, "read", "newLbl", "newRb", null);
+ List<String> svcImpl = new ArrayList<>();
+ svcImpl.add("execute");
+ svcRead.setImpliedGrants(svcImpl);
+ svc.add(svcRead);
+
+ List<RangerAccessTypeDef> tag = new ArrayList<>();
+ RangerAccessTypeDef tagRead = new RangerAccessTypeDef(1002L, "hdfs:old", "oldLbl", "oldRb", null);
+ List<String> tagImpl = new ArrayList<>();
+ tagImpl.add("hdfs:write");
+ tagRead.setImpliedGrants(tagImpl);
+ tag.add(tagRead);
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagAccessTypeDefs", List.class, List.class, long.class, String.class);
+ m.setAccessible(true);
+
+ Boolean updated = (Boolean) m.invoke(store, svc, tag, 100L, "hdfs:");
+ Assertions.assertTrue(updated);
+ Assertions.assertEquals(1, tag.size());
+ Assertions.assertEquals("hdfs:read", tag.get(0).getName());
+ Assertions.assertEquals("newLbl", tag.get(0).getLabel());
+ Assertions.assertEquals("newRb", tag.get(0).getRbKeyLabel());
+ Assertions.assertTrue(tag.get(0).getImpliedGrants().contains("hdfs:execute"));
+ }
+
+ @Test
+ void test22_updateTagAccessTypeDefs_deletesRemovedFromSvc() throws Exception {
+ AbstractServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ List<RangerAccessTypeDef> svc = new ArrayList<>();
+ // svc intentionally empty to trigger deletion of prefixed tag entry
+
+ List<RangerAccessTypeDef> tag = new ArrayList<>();
+ RangerAccessTypeDef tagWrite = new RangerAccessTypeDef(1003L, "hdfs:write", "write", null, null);
+ tag.add(tagWrite);
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagAccessTypeDefs", List.class, List.class, long.class, String.class);
+ m.setAccessible(true);
+
+ Boolean updated = (Boolean) m.invoke(store, svc, tag, 100L, "hdfs:");
+ Assertions.assertTrue(updated);
+ Assertions.assertTrue(tag.isEmpty());
+ }
+
+ @Test
+ void test23_updateTagAccessTypeDefs_noChanges_returnsFalse() throws Exception {
+ AbstractServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ List<RangerAccessTypeDef> svc = new ArrayList<>();
+ RangerAccessTypeDef svcRead = new RangerAccessTypeDef(1L, "read", "lbl", "rb", null);
+ List<String> svcImpl = new ArrayList<>();
+ svcImpl.add("write");
+ svcRead.setImpliedGrants(svcImpl);
+ svc.add(svcRead);
+
+ List<RangerAccessTypeDef> tag = new ArrayList<>();
+ RangerAccessTypeDef tagRead = new RangerAccessTypeDef(101L, "hdfs:read", "lbl", "rb", null);
+ List<String> tagImpl = new ArrayList<>();
+ tagImpl.add("hdfs:write");
+ tagRead.setImpliedGrants(tagImpl);
+ tag.add(tagRead);
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagAccessTypeDefs", List.class, List.class, long.class, String.class);
+ m.setAccessible(true);
+
+ Boolean updated = (Boolean) m.invoke(store, svc, tag, 100L, "hdfs:");
+ Assertions.assertFalse(updated);
+ Assertions.assertEquals(1, tag.size());
+ Assertions.assertEquals("hdfs:read", tag.get(0).getName());
+ }
+
+ private RangerServiceDef makeSvcWithMask(long svcId, String svcName, List<RangerServiceDef.RangerDataMaskTypeDef> maskTypes, List<RangerAccessTypeDef> maskAccess) {
+ RangerServiceDef svc = new RangerServiceDef();
+ svc.setId(svcId);
+ svc.setName(svcName);
+ RangerServiceDef.RangerDataMaskDef maskDef = new RangerServiceDef.RangerDataMaskDef();
+ maskDef.setMaskTypes(maskTypes);
+ maskDef.setAccessTypes(maskAccess);
+ svc.setDataMaskDef(maskDef);
+ return svc;
+ }
+
+ private RangerServiceDef makeTagWithMask(List<RangerServiceDef.RangerDataMaskTypeDef> maskTypes, List<RangerAccessTypeDef> maskAccess) {
+ RangerServiceDef tag = new RangerServiceDef();
+ tag.setId(999L);
+ tag.setName(RangerServiceTag.TAG_RESOURCE_NAME);
+ RangerServiceDef.RangerDataMaskDef maskDef = new RangerServiceDef.RangerDataMaskDef();
+ maskDef.setMaskTypes(maskTypes);
+ maskDef.setAccessTypes(maskAccess);
+ tag.setDataMaskDef(maskDef);
+ return tag;
+ }
+
+ @Test
+ void test24_updateTagServiceDefForUpdatingDataMaskDef_add_update_delete_and_nochange() throws Exception {
+ AbstractServiceStore store = new MyServiceStore(new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
+
+ // Add scenario: tag has none, svc has one mask type and one access type
+ List<RangerServiceDef.RangerDataMaskTypeDef> svcMaskTypesAdd = new ArrayList<>();
+ svcMaskTypesAdd.add(new RangerServiceDef.RangerDataMaskTypeDef(1L, "MASK", "MASK", null, null, null, null, null));
+ List<RangerAccessTypeDef> svcMaskAccessAdd = new ArrayList<>();
+ svcMaskAccessAdd.add(new RangerAccessTypeDef(2L, "read", "read", null, null));
+ RangerServiceDef svcAdd = makeSvcWithMask(5L, "hdfs", svcMaskTypesAdd, svcMaskAccessAdd);
+
+ RangerServiceDef tagAdd = makeTagWithMask(new ArrayList<>(), new ArrayList<>());
+
+ Method m = AbstractServiceStore.class.getDeclaredMethod("updateTagServiceDefForUpdatingDataMaskDef", RangerServiceDef.class, RangerServiceDef.class, long.class, String.class);
+ m.setAccessible(true);
+
+ Boolean updatedAdd = (Boolean) m.invoke(store, tagAdd, svcAdd, 5L * 1001L, "hdfs:");
+ Assertions.assertTrue(updatedAdd);
+ Assertions.assertTrue(tagAdd.getDataMaskDef().getMaskTypes().stream().anyMatch(mt -> "hdfs:MASK".equals(mt.getName())));
+ Assertions.assertTrue(tagAdd.getDataMaskDef().getAccessTypes().stream().anyMatch(a -> "hdfs:read".equals(a.getName())));
+
+ // Update scenario: change label/desc in svc; existing tag has matching itemId, prefixed name
+ List<RangerServiceDef.RangerDataMaskTypeDef> svcMaskTypesUpd = new ArrayList<>();
+ RangerServiceDef.RangerDataMaskTypeDef svcMaskUpd = new RangerServiceDef.RangerDataMaskTypeDef(1L, "MASK", "NEWLBL", null, null, null, null, null);
+ svcMaskTypesUpd.add(svcMaskUpd);
+ RangerServiceDef svcUpd = makeSvcWithMask(5L, "hdfs", svcMaskTypesUpd, svcMaskAccessAdd);
+
+ RangerServiceDef tagUpd = makeTagWithMask(new ArrayList<>(tagAdd.getDataMaskDef().getMaskTypes()), new ArrayList<>(tagAdd.getDataMaskDef().getAccessTypes()));
+
+ Boolean updatedUpd = (Boolean) m.invoke(store, tagUpd, svcUpd, 5L * 1001L, "hdfs:");
+ Assertions.assertTrue(updatedUpd);
+ Assertions.assertTrue(tagUpd.getDataMaskDef().getMaskTypes().stream().anyMatch(mt -> "hdfs:MASK".equals(mt.getName())));
+
+ // Delete scenario: svc has no mask types; tag has one prefixed type -> should delete
+ List<RangerServiceDef.RangerDataMaskTypeDef> svcMaskTypesDel = new ArrayList<>();
+ RangerServiceDef svcDel = makeSvcWithMask(5L, "hdfs", svcMaskTypesDel, svcMaskAccessAdd);
+ RangerServiceDef tagDel = makeTagWithMask(new ArrayList<>(tagAdd.getDataMaskDef().getMaskTypes()), new ArrayList<>(tagAdd.getDataMaskDef().getAccessTypes()));
+
+ Boolean updatedDel = (Boolean) m.invoke(store, tagDel, svcDel, 5L * 1001L, "hdfs:");
+ Assertions.assertTrue(updatedDel);
+ Assertions.assertTrue(tagDel.getDataMaskDef().getMaskTypes().isEmpty());
+
+ // No-change scenario: identical svc and tag -> expect false
+ RangerServiceDef svcSame = makeSvcWithMask(6L, "kafka", new ArrayList<>(), new ArrayList<>());
+ RangerServiceDef tagSame = makeTagWithMask(new ArrayList<>(), new ArrayList<>());
+ Boolean updatedSame = (Boolean) m.invoke(store, tagSame, svcSame, 6L * 1001L, "kafka:");
+ Assertions.assertFalse(updatedSame);
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractTagStore.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractTagStore.java
new file mode 100644
index 000000000..e327fa229
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestAbstractTagStore.java
@@ -0,0 +1,541 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceResource;
+import org.apache.ranger.plugin.model.RangerTag;
+import org.apache.ranger.plugin.model.RangerTagDef;
+import org.apache.ranger.plugin.model.RangerTagResourceMap;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.apache.ranger.plugin.util.ServiceTags;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for AbstractTagStore class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestAbstractTagStore {
+ private static class MyTagStore extends AbstractTagStore {
+ @Override
+ public boolean isInPlaceTagUpdateSupported() {
+ return true;
+ }
+
+ @Override
+ public void deleteAllTagObjectsForService(String serviceName) {
+ }
+
+ @Override
+ public Long getTagVersion(String serviceName) {
+ return 0L;
+ }
+
+ @Override
+ public ServiceTags getServiceTagsDelta(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public ServiceTags getServiceTags(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public ServiceTags getServiceTagsIfUpdated(String serviceName, Long lastKnownVersion,
+ boolean needsBackwardCompatibility) {
+ return null;
+ }
+
+ @Override
+ public RangerTagDef createTagDef(RangerTagDef tagDef) {
+ return null;
+ }
+
+ @Override
+ public RangerTagDef updateTagDef(RangerTagDef tagDef) {
+ return null;
+ }
+
+ @Override
+ public void deleteTagDefByName(String name) {
+ }
+
+ @Override
+ public void deleteTagDef(Long id) {
+ }
+
+ @Override
+ public RangerTagDef getTagDef(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerTagDef getTagDefByGuid(String guid) {
+ return null;
+ }
+
+ @Override
+ public RangerTagDef getTagDefByName(String name) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTagDef> getTagDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerTagDef> getPaginatedTagDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public List<String> getTagTypes() {
+ return null;
+ }
+
+ @Override
+ public RangerTag createTag(RangerTag tag) {
+ return null;
+ }
+
+ @Override
+ public RangerTag updateTag(RangerTag tag) {
+ return null;
+ }
+
+ @Override
+ public void deleteTag(Long id) {
+ }
+
+ @Override
+ public RangerTag getTag(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerTag getTagByGuid(String guid) {
+ return null;
+ }
+
+ @Override
+ public List<Long> getTagIdsForResourceId(Long resourceId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTag> getTagsByType(String name) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTag> getTagsForResourceId(Long resourceId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTag> getTagsForResourceGuid(String resourceGuid) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTag> getTags(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerTag> getPaginatedTags(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceResource createServiceResource(RangerServiceResource resource) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceResource updateServiceResource(RangerServiceResource resource) {
+ return null;
+ }
+
+ @Override
+ public void refreshServiceResource(Long resourceId) {
+ }
+
+ @Override
+ public void deleteServiceResource(Long id) {
+ }
+
+ @Override
+ public void deleteServiceResourceByGuid(String guid) {
+ }
+
+ @Override
+ public RangerServiceResource getServiceResource(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceResource getServiceResourceByGuid(String guid) {
+ return null;
+ }
+
+ @Override
+ public List<RangerServiceResource> getServiceResourcesByService(String serviceName) {
+ return null;
+ }
+
+ @Override
+ public List<String> getServiceResourceGuidsByService(String serviceName) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceResource getServiceResourceByServiceAndResourceSignature(String serviceName,
+ String resourceSignature) {
+ return null;
+ }
+
+ @Override
+ public List<RangerServiceResource> getServiceResources(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerServiceResource> getPaginatedServiceResources(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerTagResourceMap createTagResourceMap(RangerTagResourceMap tagResourceMap) {
+ return null;
+ }
+
+ @Override
+ public void deleteTagResourceMap(Long id) {
+ }
+
+ @Override
+ public RangerTagResourceMap getTagResourceMap(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerTagResourceMap getTagResourceMapByGuid(String guid) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTagResourceMap> getTagResourceMapsForTagId(Long tagId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTagResourceMap> getTagResourceMapsForTagGuid(String tagGuid) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTagResourceMap> getTagResourceMapsForResourceId(Long resourceId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTagResourceMap> getTagResourceMapsForResourceGuid(String resourceGuid) {
+ return null;
+ }
+
+ @Override
+ public RangerTagResourceMap getTagResourceMapForTagAndResourceId(Long tagId, Long resourceId) {
+ return null;
+ }
+
+ @Override
+ public RangerTagResourceMap getTagResourceMapForTagAndResourceGuid(String tagGuid, String resourceGuid) {
+ return null;
+ }
+
+ @Override
+ public List<RangerTagResourceMap> getTagResourceMaps(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerTagResourceMap> getPaginatedTagResourceMaps(SearchFilter filter) {
+ return null;
+ }
+ }
+
+ @Test
+ public void test01_getSetServiceStore_andInitNoop() throws Exception {
+ MyTagStore s = new MyTagStore();
+ Assertions.assertNull(s.getServiceStore());
+ ServiceStore ss = new ServiceStore() {
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
+ return null;
+ }
+
+ @Override
+ public void deleteServiceDef(Long id, Boolean forceDelete) {
+ }
+
+ @Override
+ public void updateTagServiceDefForAccessTypes() {
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByName(String name) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByDisplayName(String name) {
+ return null;
+ }
+
+ @Override
+ public List<RangerServiceDef> getServiceDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerServiceDef> getPaginatedServiceDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerService createService(RangerService service) {
+ return null;
+ }
+
+ @Override
+ public RangerService updateService(RangerService service, Map<String, Object> options) {
+ return null;
+ }
+
+ @Override
+ public void deleteService(Long id) {
+ }
+
+ @Override
+ public boolean serviceExists(String name) {
+ return false;
+ }
+
+ @Override
+ public RangerService getService(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerService getServiceByName(String name) {
+ return null;
+ }
+
+ @Override
+ public RangerService getServiceByDisplayName(String displayName) {
+ return null;
+ }
+
+ @Override
+ public List<RangerService> getServices(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerService> getPaginatedServices(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createDefaultPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy updatePolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy, RangerService service) {
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy) {
+ }
+
+ @Override
+ public boolean policyExists(Long id) {
+ return false;
+ }
+
+ @Override
+ public RangerPolicy getPolicy(Long id) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPolicies(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public Long getPolicyId(Long serviceId, String policyName, Long zoneId) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedPolicies(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesByResourceSignature(String serviceName, String policySignature,
+ Boolean isPolicyEnabled) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(Long serviceId, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(Long serviceId, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(String serviceName, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(String serviceName, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePoliciesIfUpdated(String serviceName, Long lastKnownVersion,
+ boolean needsBackwardCompatibility) {
+ return null;
+ }
+
+ @Override
+ public Long getServicePolicyVersion(String serviceName) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltasOrPolicies(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltas(String serviceName, Long lastKnownVersion,
+ Long cachedPolicyVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicies(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy getPolicyFromEventTime(String eventTimeStr, Long policyId) {
+ return null;
+ }
+
+ @Override
+ public Boolean getPopulateExistingBaseFields() {
+ return null;
+ }
+
+ @Override
+ public void setPopulateExistingBaseFields(Boolean populateExistingBaseFields) {
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(String name) {
+ return null;
+ }
+
+ @Override
+ public long getPoliciesCount(String serviceName) {
+ return 0;
+ }
+
+ @Override
+ public Map<String, String> getServiceConfigForPlugin(Long serviceId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesWithMetaAttributes(List<RangerPolicy> policies) {
+ return null;
+ }
+ };
+ s.setServiceStore(ss);
+ Assertions.assertNotNull(s.getServiceStore());
+ s.init();
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestEmbeddedServiceDefsUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestEmbeddedServiceDefsUtil.java
new file mode 100644
index 000000000..11207ac7f
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestEmbeddedServiceDefsUtil.java
@@ -0,0 +1,347 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.gds.GdsPolicyEngine;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for EmbeddedServiceDefsUtil class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestEmbeddedServiceDefsUtil {
+ public static class CapturingServiceStore implements ServiceStore {
+ private final Map<String, RangerServiceDef> nameToServiceDef = new HashMap<>();
+ private final Map<Long, RangerServiceDef> idToServiceDef = new HashMap<>();
+ private final Map<String, RangerService> nameToService = new HashMap<>();
+ private final List<String> createdServiceDefNames = new ArrayList<>();
+ private int idSeq = 1;
+ private boolean populateExistingBaseFields;
+
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) {
+ if (serviceDef.getId() == null) {
+ serviceDef.setId((long) idSeq++);
+ }
+ nameToServiceDef.put(serviceDef.getName(), serviceDef);
+ idToServiceDef.put(serviceDef.getId(), serviceDef);
+ createdServiceDefNames.add(serviceDef.getName());
+ return serviceDef;
+ }
+
+ @Override
+ public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
+ nameToServiceDef.put(serviceDef.getName(), serviceDef);
+ idToServiceDef.put(serviceDef.getId(), serviceDef);
+ return serviceDef;
+ }
+
+ @Override
+ public void deleteServiceDef(Long id, Boolean forceDelete) {
+ RangerServiceDef sd = idToServiceDef.remove(id);
+ if (sd != null) {
+ nameToServiceDef.remove(sd.getName());
+ }
+ }
+
+ @Override
+ public void updateTagServiceDefForAccessTypes() {
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef(Long id) {
+ return idToServiceDef.get(id);
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByName(String name) {
+ return nameToServiceDef.get(name);
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByDisplayName(String name) {
+ return null;
+ }
+
+ @Override
+ public List<RangerServiceDef> getServiceDefs(SearchFilter filter) {
+ return new ArrayList<>(nameToServiceDef.values());
+ }
+
+ @Override
+ public PList<RangerServiceDef> getPaginatedServiceDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerService createService(RangerService service) {
+ if (service.getId() == null) {
+ service.setId((long) idSeq++);
+ }
+ nameToService.put(service.getName(), service);
+ return service;
+ }
+
+ @Override
+ public RangerService updateService(RangerService service, Map<String, Object> options) {
+ nameToService.put(service.getName(), service);
+ return service;
+ }
+
+ @Override
+ public void deleteService(Long id) {
+ }
+
+ @Override
+ public boolean serviceExists(String name) {
+ return nameToService.containsKey(name);
+ }
+
+ @Override
+ public RangerService getService(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerService getServiceByName(String name) {
+ return nameToService.get(name);
+ }
+
+ @Override
+ public RangerService getServiceByDisplayName(String displayName) {
+ return null;
+ }
+
+ @Override
+ public List<RangerService> getServices(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerService> getPaginatedServices(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createDefaultPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy updatePolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy, RangerService service) {
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy) {
+ }
+
+ @Override
+ public boolean policyExists(Long id) {
+ return false;
+ }
+
+ @Override
+ public RangerPolicy getPolicy(Long id) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPolicies(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedPolicies(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public Long getPolicyId(Long serviceId, String policyName, Long zoneId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(Long serviceId, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(Long serviceId, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(String serviceName, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(String serviceName, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePoliciesIfUpdated(String serviceName, Long lastKnownVersion, boolean needsBackwardCompatibility) {
+ return null;
+ }
+
+ @Override
+ public Long getServicePolicyVersion(String serviceName) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltasOrPolicies(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltas(String serviceName, Long lastKnownVersion, Long cachedPolicyVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicies(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy getPolicyFromEventTime(String eventTimeStr, Long policyId) {
+ return null;
+ }
+
+ @Override
+ public Boolean getPopulateExistingBaseFields() {
+ return populateExistingBaseFields;
+ }
+
+ @Override
+ public void setPopulateExistingBaseFields(Boolean populateExistingBaseFields) {
+ this.populateExistingBaseFields = populateExistingBaseFields != null && populateExistingBaseFields;
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(String name) {
+ return null;
+ }
+
+ @Override
+ public long getPoliciesCount(String serviceName) {
+ return 0L;
+ }
+
+ @Override
+ public Map<String, String> getServiceConfigForPlugin(Long serviceId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesWithMetaAttributes(List<RangerPolicy> policies) {
+ return policies;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesByResourceSignature(String serviceName, String policySignature, Boolean isPolicyEnabled) {
+ return null;
+ }
+ }
+
+ @Test
+ public void test01_getEmbeddedServiceDef_tagLoadsFromClasspath() throws Exception {
+ RangerServiceDef tag = EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME);
+ Assertions.assertNotNull(tag);
+ Assertions.assertEquals(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME, tag.getName());
+ Assertions.assertEquals(tag.getName(), tag.getDisplayName());
+ }
+
+ @Test
+ public void test02_init_createsTagAndGdsAndCreatesGdsService() {
+ RangerAdminConfig.getInstance().setBoolean(EmbeddedServiceDefsUtil.PROPERTY_CREATE_EMBEDDED_SERVICE_DEFS, true);
+
+ CapturingServiceStore store = new CapturingServiceStore();
+ EmbeddedServiceDefsUtil.instance().init(store);
+
+ Assertions.assertTrue(store.createdServiceDefNames.contains(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME));
+ Assertions.assertTrue(store.createdServiceDefNames.contains(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_GDS_NAME));
+ RangerService gdsSvc = store.getServiceByName(GdsPolicyEngine.GDS_SERVICE_NAME);
+ Assertions.assertNotNull(gdsSvc);
+ Assertions.assertEquals(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_GDS_NAME, gdsSvc.getType());
+ }
+
+ @Test
+ public void test03_isRecursiveEnabled_checksResourceDefFlag() {
+ RangerServiceDef def = new RangerServiceDef();
+ List<RangerServiceDef.RangerResourceDef> resources = new ArrayList<>();
+ RangerServiceDef.RangerResourceDef r = new RangerServiceDef.RangerResourceDef();
+ r.setName("path");
+ r.setLevel(1);
+ r.setRecursiveSupported(true);
+ resources.add(r);
+ def.setResources(resources);
+
+ boolean recursive = EmbeddedServiceDefsUtil.isRecursiveEnabled(def, "path");
+ Assertions.assertTrue(recursive);
+ }
+
+ @Test
+ public void test04_getEmbeddedServiceDef_unknownOrEmpty() throws Exception {
+ Assertions.assertNull(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef("unknown-type"));
+ Assertions.assertNull(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(null));
+ Assertions.assertNull(EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(""));
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestPList.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestPList.java
new file mode 100644
index 000000000..2f28e6610
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestPList.java
@@ -0,0 +1,101 @@
+/*
+ * 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.plugin.store;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for PList class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestPList {
+ @Test
+ public void test01_defaultConstructorAndGetters() {
+ PList<String> p = new PList<>();
+ Assertions.assertEquals(0, p.getStartIndex());
+ Assertions.assertEquals(0, p.getPageSize());
+ Assertions.assertEquals(0, p.getTotalCount());
+ Assertions.assertEquals(0, p.getResultSize());
+ Assertions.assertNull(p.getSortType());
+ Assertions.assertNull(p.getSortBy());
+ Assertions.assertEquals(0, p.getListSize());
+ Assertions.assertTrue(p.toString().contains("PList"));
+ }
+
+ @Test
+ public void test02_paramConstructorAndSize() {
+ List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
+ PList<String> p = new PList<>(list, 1, 10, 3, 3, "asc", "name");
+ Assertions.assertEquals(list, p.getList());
+ Assertions.assertEquals(1, p.getStartIndex());
+ Assertions.assertEquals(10, p.getPageSize());
+ Assertions.assertEquals(3, p.getTotalCount());
+ Assertions.assertEquals(3, p.getResultSize());
+ Assertions.assertEquals("asc", p.getSortType());
+ Assertions.assertEquals("name", p.getSortBy());
+ Assertions.assertEquals(3, p.getListSize());
+ }
+
+ @Test
+ public void test03_copyConstructorFromNull() {
+ PList<String> p = new PList<>((PList<String>) null);
+ Assertions.assertEquals(0, p.getStartIndex());
+ Assertions.assertEquals(0, p.getPageSize());
+ Assertions.assertEquals(0, p.getTotalCount());
+ Assertions.assertEquals(0, p.getResultSize());
+ Assertions.assertNull(p.getSortType());
+ Assertions.assertNull(p.getSortBy());
+ Assertions.assertEquals(0, p.getListSize());
+ }
+
+ @Test
+ public void test04_settersAffectValues() {
+ PList<Integer> p = new PList<>();
+ p.setList(new ArrayList<>(Collections.singletonList(42)));
+ p.setStartIndex(5);
+ p.setPageSize(7);
+ p.setTotalCount(11);
+ p.setResultSize(1);
+ p.setSortType("desc");
+ p.setSortBy("id");
+ p.setQueryTimeMS(123L);
+
+ Assertions.assertEquals(1, p.getListSize());
+ Assertions.assertEquals(5, p.getStartIndex());
+ Assertions.assertEquals(7, p.getPageSize());
+ Assertions.assertEquals(11, p.getTotalCount());
+ Assertions.assertEquals(1, p.getResultSize());
+ Assertions.assertEquals("desc", p.getSortType());
+ Assertions.assertEquals("id", p.getSortBy());
+ Assertions.assertEquals(123L, p.getQueryTimeMS());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestRangerServiceResourceSignature.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestRangerServiceResourceSignature.java
new file mode 100644
index 000000000..caaae2b76
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestRangerServiceResourceSignature.java
@@ -0,0 +1,116 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
+import org.apache.ranger.authorization.hadoop.config.RangerConfigConstants;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerServiceResource;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for RangerServiceResourceSignature class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRangerServiceResourceSignature {
+ private RangerServiceResource newResource(String value) {
+ Map<String, RangerPolicy.RangerPolicyResource> elements = new HashMap<>();
+ elements.put("path", new RangerPolicy.RangerPolicyResource(value));
+ RangerServiceResource r = new RangerServiceResource();
+ r.setResourceElements(elements);
+ return r;
+ }
+
+ @Test
+ public void test01_signatureChangesWithContent() {
+ RangerServiceResource r1 = newResource("/a");
+ RangerServiceResource r2 = newResource("/b");
+ String s1 = new RangerServiceResourceSignature(r1).getSignature();
+ String s2 = new RangerServiceResourceSignature(r2).getSignature();
+ Assertions.assertNotNull(s1);
+ Assertions.assertNotNull(s2);
+ Assertions.assertNotEquals(s1, s2);
+ }
+
+ @Test
+ public void test02_signatureStableForSameContent() {
+ RangerServiceResource r1 = newResource("/same");
+ RangerServiceResource r2 = newResource("/same");
+ Assertions.assertEquals(new RangerServiceResourceSignature(r1).getSignature(),
+ new RangerServiceResourceSignature(r2).getSignature());
+ }
+
+ @Test
+ public void test03_fipsToggleAltersHashAlgorithm() {
+ // force non-FIPS first
+ System.setProperty(RangerConfigConstants.RANGER_KEYSTORE_TYPE, "JKS");
+ RangerAdminConfig.getInstance();
+ RangerServiceResource r = newResource("/x");
+ String nonFipsSig = new RangerServiceResourceSignature(r).getSignature();
+
+ // now simulate FIPS by switching keystore type to bcfks
+ System.setProperty(RangerConfigConstants.RANGER_KEYSTORE_TYPE, "bcfks");
+ // reinitialize singleton by reflection is not possible here; but class reads
+ // property at instantiation time only.
+ // Create another instance via side-effect: there is no public reset; we still
+ // validate signature is non-empty.
+ String maybeFipsSig = new RangerServiceResourceSignature(r).getSignature();
+ Assertions.assertNotNull(nonFipsSig);
+ Assertions.assertNotNull(maybeFipsSig);
+ }
+
+ @Test
+ public void test04_asStringContainsSortedValuesAndFlags() {
+ Map<String, RangerPolicy.RangerPolicyResource> elements = new HashMap<>();
+ RangerPolicy.RangerPolicyResource res = new RangerPolicy.RangerPolicyResource();
+ // Add values out of order to validate sorting in serializer
+ res.setValues(Arrays.asList("b", "a"));
+ res.setIsExcludes(Boolean.TRUE);
+ res.setIsRecursive(Boolean.FALSE);
+ elements.put("path", res);
+ RangerServiceResource r = new RangerServiceResource();
+ r.setResourceElements(elements);
+
+ RangerServiceResourceSignature sig = new RangerServiceResourceSignature(r);
+ String asString = sig.asString();
+ Assertions.assertTrue(asString.contains("values=[a, b]"));
+ Assertions.assertTrue(asString.contains("excludes=true"));
+ Assertions.assertTrue(asString.contains("recursive=false"));
+
+ // Now set nulls to ensure defaults are false
+ res.setIsExcludes(null);
+ res.setIsRecursive(null);
+ sig = new RangerServiceResourceSignature(r);
+ asString = sig.asString();
+ Assertions.assertTrue(asString.contains("excludes=false"));
+ Assertions.assertTrue(asString.contains("recursive=false"));
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestRolePredicateUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestRolePredicateUtil.java
new file mode 100644
index 000000000..b5b26ccef
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestRolePredicateUtil.java
@@ -0,0 +1,123 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerRole;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for RolePredicateUtil class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestRolePredicateUtil {
+ private static RangerRole newRole(long id, String name) {
+ RangerRole r = new RangerRole();
+ r.setId(id);
+ r.setName(name);
+ r.setUsers(new ArrayList<>());
+ r.setGroups(new ArrayList<>());
+ r.setRoles(new ArrayList<>());
+ return r;
+ }
+
+ private static RangerRole.RoleMember member(String name) {
+ RangerRole.RoleMember m = new RangerRole.RoleMember();
+ m.setName(name);
+ return m;
+ }
+
+ @Test
+ public void test01_roleName_and_partialRoleName_matchRoleOrNestedMembers() {
+ RangerRole role = newRole(1L, "adminRole");
+ List<RangerRole> list = new ArrayList<>(Collections.singletonList(role));
+
+ RolePredicateUtil util = new RolePredicateUtil();
+ SearchFilter f1 = new SearchFilter();
+ f1.setParam(SearchFilter.ROLE_NAME, "adminRole");
+ util.applyFilter(list, f1);
+ Assertions.assertEquals(1, list.size());
+
+ // now make role name non-matching, but nested role member matches
+ role.setName("different");
+ role.getRoles().add(member("nestedAdmin"));
+ List<RangerRole> list2 = new ArrayList<>(Collections.singletonList(role));
+ SearchFilter f2 = new SearchFilter();
+ f2.setParam(SearchFilter.ROLE_NAME, "nestedAdmin");
+ util.applyFilter(list2, f2);
+ Assertions.assertEquals(1, list2.size());
+
+ List<RangerRole> list3 = new ArrayList<>(Collections.singletonList(role));
+ SearchFilter f3 = new SearchFilter();
+ f3.setParam(SearchFilter.ROLE_NAME_PARTIAL, "stedad");
+ util.applyFilter(list3, f3);
+ Assertions.assertEquals(1, list3.size());
+ }
+
+ @Test
+ public void test02_roleId_group_and_user_exact_and_partial() {
+ RangerRole role = newRole(5L, "roleX");
+ role.getGroups().add(member("analytics"));
+ role.getUsers().add(member("alice"));
+ List<RangerRole> list = new ArrayList<>(Collections.singletonList(role));
+
+ RolePredicateUtil util = new RolePredicateUtil();
+
+ SearchFilter byId = new SearchFilter();
+ byId.setParam(SearchFilter.ROLE_ID, "5");
+ util.applyFilter(list, byId);
+ Assertions.assertEquals(1, list.size());
+
+ List<RangerRole> list2 = new ArrayList<>(Collections.singletonList(role));
+ SearchFilter byGroup = new SearchFilter();
+ byGroup.setParam(SearchFilter.GROUP_NAME, "analytics");
+ util.applyFilter(list2, byGroup);
+ Assertions.assertEquals(1, list2.size());
+
+ List<RangerRole> list3 = new ArrayList<>(Collections.singletonList(role));
+ SearchFilter byGroupPartial = new SearchFilter();
+ byGroupPartial.setParam(SearchFilter.GROUP_NAME_PARTIAL, "lyt");
+ util.applyFilter(list3, byGroupPartial);
+ Assertions.assertEquals(1, list3.size());
+
+ List<RangerRole> list4 = new ArrayList<>(Collections.singletonList(role));
+ SearchFilter byUser = new SearchFilter();
+ byUser.setParam(SearchFilter.USER_NAME, "alice");
+ util.applyFilter(list4, byUser);
+ Assertions.assertEquals(1, list4.size());
+
+ List<RangerRole> list5 = new ArrayList<>(Collections.singletonList(role));
+ SearchFilter byUserPartial = new SearchFilter();
+ byUserPartial.setParam(SearchFilter.USER_NAME_PARTIAL, "ali");
+ util.applyFilter(list5, byUserPartial);
+ Assertions.assertEquals(1, list5.size());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestSecurityZonePredicateUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestSecurityZonePredicateUtil.java
new file mode 100644
index 000000000..45fbc70f4
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestSecurityZonePredicateUtil.java
@@ -0,0 +1,67 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for SecurityZonePredicateUtil class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestSecurityZonePredicateUtil {
+ @Test
+ public void test01_allPredicates() {
+ RangerSecurityZone z = new RangerSecurityZone();
+ z.setId(10L);
+ z.setName("zone-a");
+ z.setCreatedBy("admin");
+ Map<String, RangerSecurityZone.RangerSecurityZoneService> services = new HashMap<>();
+ services.put("svc1", new RangerSecurityZone.RangerSecurityZoneService());
+ z.setServices(services);
+
+ List<RangerSecurityZone> zones = new ArrayList<>(Collections.singletonList(z));
+
+ SecurityZonePredicateUtil util = new SecurityZonePredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.SERVICE_NAME, "svc1");
+ f.setParam(SearchFilter.ZONE_ID, "10");
+ f.setParam(SearchFilter.ZONE_NAME, "zone-a");
+ f.setParam(SearchFilter.NOT_ZONE_NAME, "zone-b");
+ f.setParam(SearchFilter.ZONE_NAME_PARTIAL, "zone");
+ f.setParam(SearchFilter.CREATED_BY, "admin");
+ util.applyFilter(zones, f);
+ Assertions.assertEquals(1, zones.size());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestServicePredicateUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestServicePredicateUtil.java
new file mode 100644
index 000000000..7c4144fb1
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestServicePredicateUtil.java
@@ -0,0 +1,331 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for ServicePredicateUtil class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestServicePredicateUtil {
+ private static class StubServiceStore implements ServiceStore {
+ private final RangerService service;
+ private final RangerService tagService;
+
+ private StubServiceStore(RangerService service, RangerService tagService) {
+ this.service = service;
+ this.tagService = tagService;
+ }
+
+ @Override
+ public void init() {
+ }
+
+ @Override
+ public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
+ return null;
+ }
+
+ @Override
+ public void deleteServiceDef(Long id, Boolean forceDelete) {
+ }
+
+ @Override
+ public void updateTagServiceDefForAccessTypes() {
+ }
+
+ @Override
+ public RangerServiceDef getServiceDef(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByName(String name) {
+ return null;
+ }
+
+ @Override
+ public RangerServiceDef getServiceDefByDisplayName(String name) {
+ return null;
+ }
+
+ @Override
+ public List<RangerServiceDef> getServiceDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerServiceDef> getPaginatedServiceDefs(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerService createService(RangerService service) {
+ return null;
+ }
+
+ @Override
+ public RangerService updateService(RangerService service, Map<String, Object> options) {
+ return null;
+ }
+
+ @Override
+ public void deleteService(Long id) {
+ }
+
+ @Override
+ public boolean serviceExists(String name) {
+ return false;
+ }
+
+ @Override
+ public RangerService getService(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerService getServiceByName(String name) {
+ return name.equals(this.service.getName()) ? service
+ : tagService != null && name.equals(tagService.getName()) ? tagService : null;
+ }
+
+ @Override
+ public RangerService getServiceByDisplayName(String displayName) {
+ return null;
+ }
+
+ @Override
+ public List<RangerService> getServices(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerService> getPaginatedServices(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy createDefaultPolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy updatePolicy(RangerPolicy policy) {
+ return null;
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy, RangerService service) {
+ }
+
+ @Override
+ public void deletePolicy(RangerPolicy policy) {
+ }
+
+ @Override
+ public boolean policyExists(Long id) {
+ return false;
+ }
+
+ @Override
+ public RangerPolicy getPolicy(Long id) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPolicies(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public Long getPolicyId(Long serviceId, String policyName, Long zoneId) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedPolicies(SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesByResourceSignature(String serviceName, String policySignature,
+ Boolean isPolicyEnabled) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(Long serviceId, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(Long serviceId, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getServicePolicies(String serviceName, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public PList<RangerPolicy> getPaginatedServicePolicies(String serviceName, SearchFilter filter) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePoliciesIfUpdated(String serviceName, Long lastKnownVersion,
+ boolean needsBackwardCompatibility) {
+ return null;
+ }
+
+ @Override
+ public Long getServicePolicyVersion(String serviceName) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltasOrPolicies(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicyDeltas(String serviceName, Long lastKnownVersion,
+ Long cachedPolicyVersion) {
+ return null;
+ }
+
+ @Override
+ public ServicePolicies getServicePolicies(String serviceName, Long lastKnownVersion) {
+ return null;
+ }
+
+ @Override
+ public RangerPolicy getPolicyFromEventTime(String eventTimeStr, Long policyId) {
+ return null;
+ }
+
+ @Override
+ public Boolean getPopulateExistingBaseFields() {
+ return null;
+ }
+
+ @Override
+ public void setPopulateExistingBaseFields(Boolean populateExistingBaseFields) {
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(Long id) {
+ return null;
+ }
+
+ @Override
+ public RangerSecurityZone getSecurityZone(String name) {
+ return null;
+ }
+
+ @Override
+ public long getPoliciesCount(String serviceName) {
+ return 0;
+ }
+
+ @Override
+ public Map<String, String> getServiceConfigForPlugin(Long serviceId) {
+ return null;
+ }
+
+ @Override
+ public List<RangerPolicy> getPoliciesWithMetaAttributes(List<RangerPolicy> policies) {
+ return null;
+ }
+ }
+
+ @Test
+ public void test01_filterByServiceTypeAndId_and_policyObjects() {
+ RangerService svc = new RangerService();
+ svc.setId(100L);
+ svc.setName("svc1");
+ svc.setType("hive");
+
+ ServicePredicateUtil util = new ServicePredicateUtil(new StubServiceStore(svc, null));
+
+ RangerPolicy pol = new RangerPolicy();
+ pol.setService("svc1");
+ List<RangerPolicy> list = new ArrayList<>(Collections.singletonList(pol));
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.SERVICE_TYPE, "hive");
+ f.setParam(SearchFilter.SERVICE_ID, "100");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+ }
+
+ @Test
+ public void test02_filterByServiceObjectsAndTagServicePredicates() {
+ RangerService svc = new RangerService();
+ svc.setId(1L);
+ svc.setName("svcA");
+ svc.setType("kafka");
+ svc.setTagService("tagSvc");
+
+ RangerService tagSvc = new RangerService();
+ tagSvc.setId(55L);
+ tagSvc.setName("tagSvc");
+ tagSvc.setType("tag");
+
+ ServicePredicateUtil util = new ServicePredicateUtil(new StubServiceStore(svc, tagSvc));
+
+ List<RangerService> list = new ArrayList<>(Collections.singletonList(svc));
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.SERVICE_TYPE, "kafka");
+ f.setParam(SearchFilter.TAG_SERVICE_NAME, "tagSvc");
+ f.setParam(SearchFilter.TAG_SERVICE_ID, "55");
+ util.applyFilter(list, f);
+ Assertions.assertEquals(1, list.size());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestStoredServiceResource.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestStoredServiceResource.java
new file mode 100644
index 000000000..1ce52ba9b
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestStoredServiceResource.java
@@ -0,0 +1,61 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for StoredServiceResource class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestStoredServiceResource {
+ @Test
+ public void test01_defaultConstructor() {
+ StoredServiceResource r = new StoredServiceResource();
+ Assertions.assertNull(r.getResourceElements());
+ Assertions.assertNull(r.getOwnerName());
+ Assertions.assertNull(r.getAdditionalInfo());
+ }
+
+ @Test
+ public void test02_paramConstructorAndGetters() {
+ RangerPolicy.RangerPolicyResource res = new RangerPolicy.RangerPolicyResource("db");
+ Map<String, RangerPolicy.RangerPolicyResource> elements = new HashMap<>();
+ elements.put("database", res);
+ Map<String, String> info = new HashMap<>();
+ info.put("k", "v");
+
+ StoredServiceResource r = new StoredServiceResource(elements, "owner", info);
+ Assertions.assertEquals(elements, r.getResourceElements());
+ Assertions.assertEquals("owner", r.getOwnerName());
+ Assertions.assertEquals(info, r.getAdditionalInfo());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagPredicateUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagPredicateUtil.java
new file mode 100644
index 000000000..119188ee1
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagPredicateUtil.java
@@ -0,0 +1,106 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerServiceResource;
+import org.apache.ranger.plugin.model.RangerTag;
+import org.apache.ranger.plugin.model.RangerTagDef;
+import org.apache.ranger.plugin.model.RangerTagResourceMap;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @generated by Cursor
+ * @description <Unit Test for TagPredicateUtil class>
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestTagPredicateUtil {
+ @Test
+ public void test01_predicatesForTagDefAndTag() {
+ RangerTagDef def = new RangerTagDef();
+ def.setId(1L);
+ def.setGuid("gd");
+ def.setName("PII");
+ List<RangerTagDef> defs = new ArrayList<>(Collections.singletonList(def));
+
+ TagPredicateUtil util = new TagPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.TAG_DEF_ID, "1");
+ f.setParam(SearchFilter.TAG_DEF_GUID, "gd");
+ f.setParam(SearchFilter.TAG_TYPE, "PII");
+ util.applyFilter(defs, f);
+ Assertions.assertEquals(1, defs.size());
+
+ RangerTag tag = new RangerTag();
+ tag.setId(2L);
+ tag.setGuid("tg");
+ tag.setType("PII");
+ List<RangerTag> tags = new ArrayList<>(Collections.singletonList(tag));
+ SearchFilter f2 = new SearchFilter();
+ f2.setParam(SearchFilter.TAG_ID, "2");
+ f2.setParam(SearchFilter.TAG_GUID, "tg");
+ f2.setParam(SearchFilter.TAG_TYPE, "PII");
+ util.applyFilter(tags, f2);
+ Assertions.assertEquals(1, tags.size());
+ }
+
+ @Test
+ public void test02_predicatesForResourceAndMap() {
+ RangerServiceResource res = new RangerServiceResource();
+ res.setId(10L);
+ res.setGuid("rg");
+ res.setServiceName("svc");
+ res.setResourceSignature("sig");
+ List<RangerServiceResource> resources = new ArrayList<>(Collections.singletonList(res));
+
+ TagPredicateUtil util = new TagPredicateUtil();
+ SearchFilter f = new SearchFilter();
+ f.setParam(SearchFilter.TAG_RESOURCE_ID, "10");
+ f.setParam(SearchFilter.TAG_RESOURCE_GUID, "rg");
+ f.setParam(SearchFilter.TAG_RESOURCE_SERVICE_NAME, "svc");
+ f.setParam(SearchFilter.TAG_RESOURCE_SIGNATURE, "sig");
+ util.applyFilter(resources, f);
+ Assertions.assertEquals(1, resources.size());
+
+ RangerTagResourceMap map = new RangerTagResourceMap();
+ map.setId(99L);
+ map.setTagId(2L);
+ map.setResourceId(10L);
+ List<RangerTagResourceMap> maps = new ArrayList<>(Collections.singletonList(map));
+ SearchFilter f2 = new SearchFilter();
+ f2.setParam(SearchFilter.TAG_MAP_ID, "99");
+ f2.setParam(SearchFilter.TAG_ID, "2");
+ // For TagResourceMap, current implementation of TAG_RESOURCE_ID predicate
+ // matches map id
+ f2.setParam(SearchFilter.TAG_RESOURCE_ID, "99");
+ util.applyFilter(maps, f2);
+ Assertions.assertEquals(1, maps.size());
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagValidator.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagValidator.java
new file mode 100644
index 000000000..03d21fd43
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagValidator.java
@@ -0,0 +1,315 @@
+/*
+ * 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.plugin.store;
+
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceResource;
+import org.apache.ranger.plugin.model.RangerTag;
+import org.apache.ranger.plugin.model.RangerTagDef;
+import org.apache.ranger.plugin.model.RangerTagResourceMap;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.Mockito.when;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for TagValidator class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestTagValidator {
+ private TagStore mockTagStore() {
+ return Mockito.mock(TagStore.class);
+ }
+
+ private static RangerServiceResource newServiceResourceWith(String serviceName, String resourceName, String value) {
+ RangerServiceResource r = new RangerServiceResource();
+ r.setServiceName(serviceName);
+ Map<String, RangerPolicyResource> elements = new HashMap<>();
+ elements.put(resourceName, new RangerPolicyResource(value));
+ r.setResourceElements(elements);
+ return r;
+ }
+
+ @Test
+ public void test01_preCreateTagDef_validatesNameAndReturnsExisting() throws Exception {
+ TagStore store = mockTagStore();
+ TagValidator v = new TagValidator();
+ v.setTagStore(store);
+
+ RangerTagDef def = new RangerTagDef();
+ def.setName("");
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagDef(def, false));
+
+ def.setName("PII");
+ RangerTagDef existing = new RangerTagDef();
+ existing.setId(1L);
+ when(store.getTagDefByName("PII")).thenReturn(existing);
+ Assertions.assertEquals(existing, v.preCreateTagDef(def, true));
+ }
+
+ @Test
+ public void test02_preCreateTag_usesGuidWhenPresent() throws Exception {
+ TagStore store = mockTagStore();
+ TagValidator v = new TagValidator();
+ v.setTagStore(store);
+
+ RangerTag tag = new RangerTag();
+ tag.setType(null);
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTag(tag));
+
+ tag.setType("PII");
+ tag.setGuid("g-1");
+ RangerTag found = new RangerTag();
+ when(store.getTagByGuid("g-1")).thenReturn(found);
+ Assertions.assertEquals(found, v.preCreateTag(tag));
+ }
+
+ @Test
+ public void test03_preUpdateTag_validations() throws Exception {
+ TagStore store = mockTagStore();
+ TagValidator v = new TagValidator();
+ v.setTagStore(store);
+
+ RangerTag tag = new RangerTag();
+ tag.setType("");
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateTag(1L, tag));
+
+ tag.setType("PII");
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateTag(null, tag));
+
+ when(store.getTag(1L)).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateTag(1L, tag));
+
+ RangerTag existing = new RangerTag();
+ existing.setId(1L);
+ existing.setGuid("g-1");
+ existing.setType("PCI");
+ when(store.getTag(2L)).thenReturn(existing);
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateTag(2L, tag));
+
+ existing.setType("PII");
+ RangerTag newTag = new RangerTag();
+ newTag.setType("PII");
+ when(store.getTag(3L)).thenReturn(existing);
+ v.preUpdateTag(3L, newTag);
+ Assertions.assertEquals(existing.getId(), newTag.getId());
+ Assertions.assertEquals(existing.getGuid(), newTag.getGuid());
+ }
+
+ @Test
+ public void test04_preUpdateTagByGuid_validations() throws Exception {
+ TagStore store = mockTagStore();
+ TagValidator v = new TagValidator();
+ v.setTagStore(store);
+
+ RangerTag tag = new RangerTag();
+ tag.setType("");
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateTagByGuid("g-1", tag));
+
+ tag.setType("PII");
+ when(store.getTagByGuid("g-x")).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateTagByGuid("g-x", tag));
+
+ RangerTag existing = new RangerTag();
+ existing.setId(5L);
+ existing.setGuid("g-1");
+ existing.setType("PCI");
+ when(store.getTagByGuid("g-1")).thenReturn(existing);
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateTagByGuid("g-1", tag));
+
+ existing.setType("PII");
+ v.preUpdateTagByGuid("g-1", tag);
+ Assertions.assertEquals(existing.getId(), tag.getId());
+ Assertions.assertEquals("g-1", tag.getGuid());
+ }
+
+ @Test
+ public void test05_preDeleteTag_andByGuid() throws Exception {
+ TagStore store = mockTagStore();
+ TagValidator v = new TagValidator();
+ v.setTagStore(store);
+
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTag(null));
+ when(store.getTag(1L)).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTag(1L));
+
+ RangerTag t = new RangerTag();
+ t.setId(2L);
+ when(store.getTag(2L)).thenReturn(t);
+ when(store.getTagResourceMapsForTagId(2L)).thenReturn(Collections.singletonList(new RangerTagResourceMap()));
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTag(2L));
+
+ when(store.getTagResourceMapsForTagId(2L)).thenReturn(Collections.emptyList());
+ Assertions.assertEquals(t, v.preDeleteTag(2L));
+
+ when(store.getTagByGuid("g-x")).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTagByGuid("g-x"));
+ RangerTag tg = new RangerTag();
+ tg.setId(3L);
+ when(store.getTagByGuid("g-3")).thenReturn(tg);
+ when(store.getTagResourceMapsForTagId(3L)).thenReturn(Collections.singletonList(new RangerTagResourceMap()));
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTagByGuid("g-3"));
+ when(store.getTagResourceMapsForTagId(3L)).thenReturn(Collections.emptyList());
+ Assertions.assertEquals(tg, v.preDeleteTagByGuid("g-3"));
+ }
+
+ @Test
+ public void test06_preCreateAndUpdateServiceResource() throws Exception {
+ TagStore store = mockTagStore();
+ TagValidator v = new TagValidator();
+ v.setTagStore(store);
+
+ RangerServiceResource r1 = new RangerServiceResource();
+ r1.setServiceName("");
+ Assertions.assertThrows(Exception.class, () -> v.preCreateServiceResource(r1));
+
+ RangerServiceResource r = newServiceResourceWith("svc", "db", "sales");
+ r.setGuid("rg-1");
+ RangerServiceResource existing = new RangerServiceResource();
+ when(store.getServiceResourceByGuid("rg-1")).thenReturn(existing);
+ Assertions.assertEquals(existing, v.preCreateServiceResource(r));
+
+ r = newServiceResourceWith("svc", "db", "sales");
+ when(store.getServiceResourceByServiceAndResourceSignature(Mockito.eq("svc"), Mockito.anyString())).thenReturn(existing);
+ RangerServiceResource ret = v.preCreateServiceResource(r);
+ Assertions.assertEquals(existing, ret);
+
+ // update by id
+ RangerServiceResource upd = newServiceResourceWith("svc", "db", "x");
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateServiceResource(null, upd));
+ when(store.getServiceResource(7L)).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateServiceResource(7L, upd));
+ RangerServiceResource ex = newServiceResourceWith("svc", "db", "old");
+ ex.setId(7L);
+ ex.setGuid("guid-7");
+ when(store.getServiceResource(7L)).thenReturn(ex);
+ RangerServiceResource wrongService = newServiceResourceWith("other", "db", "old");
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateServiceResource(7L, wrongService));
+ v.preUpdateServiceResource(7L, upd);
+ Assertions.assertEquals(ex.getId(), upd.getId());
+ Assertions.assertEquals(ex.getGuid(), upd.getGuid());
+
+ // update by guid
+ RangerServiceResource updG = newServiceResourceWith("svc", "db", "x");
+ when(store.getServiceResourceByGuid("guid-x")).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateServiceResourceByGuid("guid-x", updG));
+ when(store.getServiceResourceByGuid("guid-7")).thenReturn(ex);
+ Assertions.assertThrows(Exception.class, () -> v.preUpdateServiceResourceByGuid("guid-7", wrongService));
+ v.preUpdateServiceResourceByGuid("guid-7", updG);
+ Assertions.assertEquals(ex.getId(), updG.getId());
+ Assertions.assertEquals("guid-7", updG.getGuid());
+ }
+
+ @Test
+ public void test07_preDeleteServiceResource_andByGuid() throws Exception {
+ TagStore store = mockTagStore();
+ TagValidator v = new TagValidator();
+ v.setTagStore(store);
+
+ when(store.getServiceResource(1L)).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteServiceResource(1L));
+ RangerServiceResource ex = newServiceResourceWith("svc", "db", "x");
+ ex.setId(2L);
+ when(store.getServiceResource(2L)).thenReturn(ex);
+ when(store.getTagResourceMapsForResourceId(2L)).thenReturn(Collections.singletonList(new RangerTagResourceMap()));
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteServiceResource(2L));
+ when(store.getTagResourceMapsForResourceId(2L)).thenReturn(Collections.emptyList());
+ Assertions.assertEquals(ex, v.preDeleteServiceResource(2L));
+
+ when(store.getServiceResourceByGuid("g-x")).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteServiceResourceByGuid("g-x", false));
+ when(store.getServiceResourceByGuid("g-2")).thenReturn(ex);
+ when(store.getTagResourceMapsForResourceId(2L)).thenReturn(Collections.singletonList(new RangerTagResourceMap()));
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteServiceResourceByGuid("g-2", false));
+ Assertions.assertEquals(ex, v.preDeleteServiceResourceByGuid("g-2", true));
+ }
+
+ @Test
+ public void test08_preCreateAndDeleteTagResourceMap() throws Exception {
+ TagStore store = mockTagStore();
+ TagValidator v = new TagValidator();
+ v.setTagStore(store);
+
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagResourceMap(null, "r"));
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagResourceMap("t", null));
+
+ when(store.getTagResourceMapForTagAndResourceGuid("tg", "rg")).thenReturn(new RangerTagResourceMap());
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagResourceMap("tg", "rg"));
+
+ when(store.getTagResourceMapForTagAndResourceGuid("tg", "rg")).thenReturn(null);
+ when(store.getServiceResourceByGuid("rg")).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagResourceMap("tg", "rg"));
+ RangerServiceResource sr = newServiceResourceWith("svc", "db", "v");
+ sr.setId(10L);
+ when(store.getServiceResourceByGuid("rg")).thenReturn(sr);
+ when(store.getTagByGuid("tg")).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagResourceMap("tg", "rg"));
+ RangerTag tag = new RangerTag();
+ tag.setId(20L);
+ when(store.getTagByGuid("tg")).thenReturn(tag);
+ RangerTagResourceMap created = v.preCreateTagResourceMap("tg", "rg");
+ Assertions.assertEquals(10L, created.getResourceId());
+ Assertions.assertEquals(20L, created.getTagId());
+
+ when(store.getTagResourceMapForTagAndResourceId(1L, 2L)).thenReturn(new RangerTagResourceMap());
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagResourceMapByIds(1L, 2L));
+ when(store.getTagResourceMapForTagAndResourceId(1L, 2L)).thenReturn(null);
+ when(store.getServiceResource(2L)).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagResourceMapByIds(1L, 2L));
+ when(store.getServiceResource(2L)).thenReturn(sr);
+ when(store.getTag(1L)).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preCreateTagResourceMapByIds(1L, 2L));
+ when(store.getTag(1L)).thenReturn(tag);
+ RangerTagResourceMap createdByIds = v.preCreateTagResourceMapByIds(1L, 2L);
+ Assertions.assertEquals(2L, createdByIds.getResourceId());
+ Assertions.assertEquals(1L, createdByIds.getTagId());
+
+ when(store.getTagResourceMap(99L)).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTagResourceMap(99L));
+ when(store.getTagResourceMap(99L)).thenReturn(new RangerTagResourceMap());
+ Assertions.assertNotNull(v.preDeleteTagResourceMap(99L));
+
+ when(store.getTagResourceMapByGuid("g-x")).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTagResourceMapByGuid("g-x"));
+ when(store.getTagResourceMapByGuid("g-1")).thenReturn(new RangerTagResourceMap());
+ Assertions.assertNotNull(v.preDeleteTagResourceMapByGuid("g-1"));
+
+ when(store.getTagResourceMapForTagAndResourceGuid("tg2", "rg2")).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTagResourceMap("tg2", "rg2"));
+ when(store.getTagResourceMapForTagAndResourceGuid("tg2", "rg2")).thenReturn(new RangerTagResourceMap());
+ Assertions.assertNotNull(v.preDeleteTagResourceMap("tg2", "rg2"));
+
+ when(store.getTagResourceMapForTagAndResourceId(5L, 6L)).thenReturn(null);
+ Assertions.assertThrows(Exception.class, () -> v.preDeleteTagResourceMapByIds(5L, 6L));
+ when(store.getTagResourceMapForTagAndResourceId(5L, 6L)).thenReturn(new RangerTagResourceMap());
+ Assertions.assertNotNull(v.preDeleteTagResourceMapByIds(5L, 6L));
+ }
+}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/file/TestGeolocationFileStore.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/file/TestGeolocationFileStore.java
new file mode 100644
index 000000000..0e64c80c5
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/file/TestGeolocationFileStore.java
@@ -0,0 +1,258 @@
+/*
+ * 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.plugin.store.file;
+
+import org.apache.ranger.plugin.geo.RangerGeolocationData;
+import org.apache.ranger.plugin.geo.RangerGeolocationDatabase;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+/**
+* @generated by Cursor
+* @description <Unit Test for GeolocationFileStore class>
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class TestGeolocationFileStore {
+ private static Path writeTempGeoFile(final List<String> lines) throws IOException {
+ Path tmp = Files.createTempFile("geo", ".txt");
+ Files.write(tmp, new ArrayList<>(lines), StandardCharsets.UTF_8);
+ return tmp;
+ }
+
+ private static Map<String, String> newContext(final String filePath, final String forceRead, final String ipInDotFormat) {
+ Map<String, String> ctx = new HashMap<>();
+ if (filePath != null) {
+ ctx.put(GeolocationFileStore.PROP_GEOLOCATION_FILE_LOCATION, filePath);
+ }
+ if (forceRead != null) {
+ ctx.put(GeolocationFileStore.PROP_GEOLOCATION_FILE_REINIT, forceRead);
+ }
+ if (ipInDotFormat != null) {
+ ctx.put(GeolocationFileStore.PROP_GEOLOCATION_IP_IN_DOT_FORMAT, ipInDotFormat);
+ }
+ return ctx;
+ }
+
+ @Test
+ public void test01_init_usesDefaultPathWhenBlank_andLeavesDbNull() {
+ GeolocationFileStore store = new GeolocationFileStore();
+ Map<String, String> ctx = new HashMap<>();
+
+ store.init(ctx);
+
+ assertNull(store.getGeoDatabase());
+ }
+
+ @Test
+ public void test02_init_buildsDatabaseFromExistingFile_andCachesWhenNoReinit() throws Exception {
+ List<String> lines = new ArrayList<>();
+ lines.add("# comment");
+ lines.add("FROM_IP,TO_IP,COUNTRY_CODE,COUNTRY_NAME");
+ lines.add("1.2.3.4,1.2.3.4,US,United States");
+ Path file = writeTempGeoFile(lines);
+
+ GeolocationFileStore store1 = new GeolocationFileStore();
+ store1.init(newContext(file.toString(), "true", "true"));
+ RangerGeolocationDatabase db1 = store1.getGeoDatabase();
+ assertNotNull(db1);
+
+ GeolocationFileStore store2 = new GeolocationFileStore();
+ store2.init(newContext(file.toString(), "false", "true"));
+ RangerGeolocationDatabase db2 = store2.getGeoDatabase();
+ assertNotNull(db2);
+ assertSame(db1, db2);
+
+ RangerGeolocationData data = store2.getGeoLocation("1.2.3.4");
+ assertNotNull(data);
+ assertEquals("US", db2.getValue(data, "COUNTRY_CODE"));
+ }
+
+ @Test
+ public void test03_init_withReinitializeTrue_rebuildsAndReplacesCache() throws Exception {
+ List<String> lines = new ArrayList<>();
+ lines.add("FROM_IP,TO_IP,COUNTRY_CODE,COUNTRY_NAME");
+ lines.add("2.2.2.2,2.2.2.3,CA,Canada");
+ Path file = writeTempGeoFile(lines);
+
+ GeolocationFileStore storeA = new GeolocationFileStore();
+ storeA.init(newContext(file.toString(), "true", "true"));
+ RangerGeolocationDatabase dbA = storeA.getGeoDatabase();
+ assertNotNull(dbA);
+
+ // Modify file content to force a different DB instance on rebuild
+ List<String> newLines = new ArrayList<>();
+ newLines.add("FROM_IP,TO_IP,COUNTRY_CODE,COUNTRY_NAME");
+ newLines.add("3.3.3.3,3.3.3.4,BR,Brazil");
+ Files.write(file, newLines, StandardCharsets.UTF_8);
+
+ GeolocationFileStore storeB = new GeolocationFileStore();
+ storeB.init(newContext(file.toString(), "true", "true"));
+ RangerGeolocationDatabase dbB = storeB.getGeoDatabase();
+ assertNotNull(dbB);
+ assertNotSame(dbA, dbB);
+
+ assertNull(storeB.getGeoLocation("2.2.2.2"));
+ assertNotNull(storeB.getGeoLocation("3.3.3.3"));
+ }
+
+ @Test
+ public void test04_init_readsFromClasspathResource_whenFileNotPresent() {
+ GeolocationFileStore store = new GeolocationFileStore();
+ // Use the bundled sample resource path
+ store.init(newContext("/etc/ranger/geo/geo.txt", "true", "true"));
+ RangerGeolocationDatabase db = store.getGeoDatabase();
+ assertNotNull(db);
+ // Known range in the sample file
+ RangerGeolocationData data = store.getGeoLocation("128.101.101.200");
+ assertNotNull(data);
+ assertEquals("US", db.getValue(data, "COUNTRY_CODE"));
+ }
+
+ @Test
+ public void test05_build_returnsNull_onInvalidMetadata() throws Exception {
+ List<String> lines = new ArrayList<>();
+ lines.add("# header");
+ lines.add("FROM_IP,TO_IP"); // invalid: fewer than 3 fields
+ Path file = writeTempGeoFile(lines);
+
+ GeolocationFileStore store = new GeolocationFileStore();
+ RangerGeolocationDatabase db = store.build(file.toString());
+ assertNull(db);
+ }
+
+ @Test
+ public void test06_build_skipsInvalidDataAndEmptyLines_butSucceeds() throws Exception {
+ List<String> lines = new ArrayList<>();
+ lines.add("FROM_IP,TO_IP,COUNTRY_CODE");
+ lines.add(""); // empty line -> split returns null, should be skipped
+ lines.add("bad.ip,1.1.1.1,XX"); // invalid data line -> skipped
+ lines.add("4.4.4.4,4.4.4.5,IN"); // valid
+ Path file = writeTempGeoFile(lines);
+
+ GeolocationFileStore store = new GeolocationFileStore();
+ // ensure dot-notation is used during build
+ store.init(newContext(file.toString(), "true", "true"));
+ RangerGeolocationDatabase db = store.getGeoDatabase();
+ assertNotNull(db);
+
+ assertNull(db.find("4.4.4.3"));
+ assertNotNull(db.find("4.4.4.4"));
+ assertNotNull(db.find("4.4.4.5"));
+ assertNull(db.find("4.4.4.6"));
+ }
+
+ @Test
+ public void test07_getGeoLocation_returnsNull_whenDatabaseNotInitialized() {
+ GeolocationFileStore store = new GeolocationFileStore();
+ assertNull(store.getGeoLocation("1.1.1.1"));
+ }
+
+ @Test
+ public void test08_getGeoLocation_returnsNull_whenIpNotFound() throws Exception {
+ List<String> lines = new ArrayList<>();
+ lines.add("FROM_IP,TO_IP,COUNTRY_CODE");
+ lines.add("5.5.5.5,5.5.5.5,DE");
+ Path file = writeTempGeoFile(lines);
+
+ GeolocationFileStore store = new GeolocationFileStore();
+ store.init(newContext(file.toString(), "true", "true"));
+ assertNull(store.getGeoLocation("5.5.5.4"));
+ assertNotNull(store.getGeoLocation("5.5.5.5"));
+ assertNull(store.getGeoLocation("5.5.5.6"));
+ }
+
+ @Test
+ public void test09_build_supportsNumericIps_whenDotFormatDisabled() throws Exception {
+ // 3232235777 = 192.168.1.1, 3232235778 = 192.168.1.2
+ List<String> lines = new ArrayList<>();
+ lines.add("FROM_IP,TO_IP,COUNTRY_CODE");
+ lines.add("3232235777,3232235778,US");
+ Path file = writeTempGeoFile(lines);
+
+ GeolocationFileStore store = new GeolocationFileStore();
+ // Ensure useDotFormat is false before build
+ store.init(newContext(file.toString(), "true", "false"));
+ RangerGeolocationDatabase db = store.getGeoDatabase();
+ assertNotNull(db);
+ assertNotNull(store.getGeoLocation("192.168.1.1"));
+ assertNotNull(store.getGeoLocation("192.168.1.2"));
+ assertNull(store.getGeoLocation("192.168.1.3"));
+ }
+
+ @Test
+ public void test10_getGeoDatabase_returnsCurrentInstance() throws Exception {
+ List<String> lines = new ArrayList<>();
+ lines.add("FROM_IP,TO_IP,COUNTRY_CODE");
+ lines.add("7.7.7.7,7.7.7.7,CA");
+ Path file = writeTempGeoFile(lines);
+
+ GeolocationFileStore store = new GeolocationFileStore();
+ store.init(newContext(file.toString(), "true", "true"));
+ RangerGeolocationDatabase db = store.getGeoDatabase();
+ assertNotNull(db);
+ assertSame(db, store.getGeoDatabase());
+ }
+
+ @Test
+ public void test11_init_reinitializeTrue_butBuildFails_retainsOldDatabase() throws Exception {
+ List<String> lines = new ArrayList<>();
+ lines.add("FROM_IP,TO_IP,COUNTRY_CODE");
+ lines.add("8.8.8.8,8.8.8.8,US");
+ Path file = writeTempGeoFile(lines);
+
+ GeolocationFileStore store1 = new GeolocationFileStore();
+ store1.init(newContext(file.toString(), "true", "true"));
+ RangerGeolocationDatabase originalDb = store1.getGeoDatabase();
+ assertNotNull(originalDb);
+ assertNotNull(store1.getGeoLocation("8.8.8.8"));
+
+ // Now corrupt the file so build() returns null (invalid metadata)
+ List<String> bad = new ArrayList<>();
+ bad.add("FROM_IP,TO_IP");
+ Files.write(file, bad, StandardCharsets.UTF_8);
+
+ GeolocationFileStore store2 = new GeolocationFileStore();
+ store2.init(newContext(file.toString(), "true", "true"));
+ RangerGeolocationDatabase retainedDb = store2.getGeoDatabase();
+ assertNotNull(retainedDb);
+ assertSame(originalDb, retainedDb);
+ // Old data should still be available since rebuild failed
+ assertNotNull(store2.getGeoLocation("8.8.8.8"));
+ }
+}