Copilot commented on code in PR #1220:
URL: https://github.com/apache/ranger/pull/1220#discussion_r3973038654
##########
agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json:
##########
@@ -198,7 +198,7 @@
],
"resources": [
{ "name": "database", "matcherOptions": { "wildCard": "false" },
"lookupSupported": true, "mandatory": true, "uiHint": "{ \"singleValue\":true
}" },
- { "name": "table", "matcherOptions": { "wildCard": "false" },
"lookupSupported": true, "mandatory": true, "uiHint": "{ \"singleValue\":true
}" }
+ { "name": "table", "matcherOptions": { "wildCard": "true" },
"lookupSupported": true, "mandatory": true, "uiHint": "" }
Review Comment:
This PR’s description focuses on enabling wildcard table names, but the
embedded Hive service-def also changes `uiHint` from `{ "singleValue":true }`
to an empty string. Clearing `uiHint` can affect UI behavior/validation
independently of wildcard matching. If the goal is strictly wildcard support,
consider keeping the prior `uiHint` (or documenting why it must be removed) and
adjusting the Java patch accordingly (it currently copies `uiHint` from the
embedded table resource into the DB service-def).
##########
security-admin/src/main/java/org/apache/ranger/patch/PatchForHiveServiceDefUpdate_J10068.java:
##########
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.patch;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.JSONUtil;
+import org.apache.ranger.common.RangerValidatorFactory;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerRowFilterDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
+import org.apache.ranger.plugin.model.validation.RangerValidator.Action;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.util.CLIUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class PatchForHiveServiceDefUpdate_J10068 extends BaseLoader {
+ private static final Logger logger =
LoggerFactory.getLogger(PatchForHiveServiceDefUpdate_J10068.class);
+
+ private static final String HIVE_SERVICE_DEF_NAME = "hive";
+ private static final String ROW_FILTER_TABLE_RESOURCE_NAME = "table";
+
+ @Autowired
+ RangerDaoManager daoMgr;
+
+ @Autowired
+ ServiceDBStore svcStore;
+
+ @Autowired
+ JSONUtil jsonUtil;
+
+ @Autowired
+ RangerValidatorFactory validatorFactory;
+
+ public static void main(String[] args) {
+ logger.info("main()");
+
+ try {
+ PatchForHiveServiceDefUpdate_J10068 loader =
(PatchForHiveServiceDefUpdate_J10068)
CLIUtil.getBean(PatchForHiveServiceDefUpdate_J10068.class);
+
+ loader.init();
+
+ while (loader.isMoreToProcess()) {
+ loader.load();
+ }
+
+ logger.info("Load complete. Exiting!!!");
+
+ System.exit(0);
+ } catch (Exception e) {
+ logger.error("Error loading", e);
+
+ System.exit(1);
+ }
+ }
+
+ @Override
+ public void init() throws Exception {
+ // Do Nothing
+ }
+
+ @Override
+ public void printStats() {
+ logger.info("PatchForHiveServiceDefUpdate_J10068");
+ }
+
+ @Override
+ public void execLoad() {
+ logger.info("==> PatchForHiveServiceDefUpdate_J10068.execLoad()");
+
+ try {
+ updateHiveServiceDef();
+ } catch (Exception e) {
+ logger.error("Failed to apply
PatchForHiveServiceDefUpdate_J10068.", e);
+
+ System.exit(1);
+ }
+
+ logger.info("<== PatchForHiveServiceDefUpdate_J10068.execLoad()");
+ }
+
+ private void updateHiveServiceDef() throws Exception {
+ RangerServiceDef embeddedHiveServiceDef =
EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(HIVE_SERVICE_DEF_NAME);
+
+ if (embeddedHiveServiceDef == null) {
+ throw new IllegalStateException("The embedded Hive
service-definition does not exist.");
+ }
+
+ RangerRowFilterDef embeddedRowFilterDef =
embeddedHiveServiceDef.getRowFilterDef();
+
+ if (embeddedRowFilterDef == null ||
CollectionUtils.isEmpty(embeddedRowFilterDef.getResources())) {
+ throw new IllegalStateException("Embedded " +
HIVE_SERVICE_DEF_NAME + " service-def has no rowFilterDef.");
+ }
+
+ XXServiceDef xXServiceDefObj =
daoMgr.getXXServiceDef().findByName(HIVE_SERVICE_DEF_NAME);
+
+ if (xXServiceDefObj == null) {
+ throw new IllegalStateException(HIVE_SERVICE_DEF_NAME + "
service-def not found in DB.");
+ }
+
+ Map<String, String> serviceDefOptionsPreUpdate =
jsonStringToMap(xXServiceDefObj.getDefOptions());
+ String valueBeforeUpdate =
serviceDefOptionsPreUpdate == null ? null
+ :
serviceDefOptionsPreUpdate.get(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES);
+
+ RangerServiceDef dbHiveServiceDef =
svcStore.getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
+ if (dbHiveServiceDef == null) {
+ throw new IllegalStateException(HIVE_SERVICE_DEF_NAME + "
service-def not found in DB.");
+ }
+
+ updateRowFilterTableResource(embeddedRowFilterDef,
dbHiveServiceDef.getRowFilterDef());
+
+ RangerServiceDefValidator validator =
validatorFactory.getServiceDefValidator(svcStore);
+
+ validator.validate(dbHiveServiceDef, Action.UPDATE);
+
+ RangerServiceDef ret = svcStore.updateServiceDef(dbHiveServiceDef);
+
+ if (ret == null) {
+ throw new IllegalStateException("Error while updating " +
HIVE_SERVICE_DEF_NAME + " service-def");
+ }
+
+ restoreDefOptionsIfNeeded(valueBeforeUpdate);
+
+ logger.info("Successfully updated rowFilterDef table resource for {}
service-def", HIVE_SERVICE_DEF_NAME);
+ }
+
+ private void updateRowFilterTableResource(RangerRowFilterDef
embeddedRowFilterDef, RangerRowFilterDef dbRowFilterDef) {
+ if (dbRowFilterDef == null ||
CollectionUtils.isEmpty(dbRowFilterDef.getResources())) {
+ throw new IllegalStateException("DB " + HIVE_SERVICE_DEF_NAME + "
service-def has no rowFilterDef.");
+ }
+
+ RangerResourceDef embeddedTableResource =
findRowFilterResource(embeddedRowFilterDef, ROW_FILTER_TABLE_RESOURCE_NAME);
+ RangerResourceDef dbTableResource =
findRowFilterResource(dbRowFilterDef, ROW_FILTER_TABLE_RESOURCE_NAME);
+
+ if (embeddedTableResource == null) {
+ throw new IllegalStateException("Embedded " +
HIVE_SERVICE_DEF_NAME + " rowFilterDef has no table resource.");
+ }
+
+ if (dbTableResource == null) {
+ throw new IllegalStateException("DB " + HIVE_SERVICE_DEF_NAME + "
rowFilterDef has no table resource.");
+ }
+
+ Map<String, String> matcherOptions =
embeddedTableResource.getMatcherOptions();
+
+ dbTableResource.setMatcherOptions(matcherOptions != null ? new
HashMap<>(matcherOptions) : null);
+ dbTableResource.setUiHint(embeddedTableResource.getUiHint());
+ }
+
+ private RangerResourceDef findRowFilterResource(RangerRowFilterDef
rowFilterDef, String resourceName) {
+ RangerResourceDef result = null;
+
+ if (rowFilterDef != null &&
CollectionUtils.isNotEmpty(rowFilterDef.getResources())) {
+ for (RangerResourceDef resourceDef : rowFilterDef.getResources()) {
+ if (resourceName.equals(resourceDef.getName())) {
+ result = resourceDef;
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void restoreDefOptionsIfNeeded(String valueBeforeUpdate) throws
Exception {
+ XXServiceDef xXServiceDefObj =
daoMgr.getXXServiceDef().findByName(HIVE_SERVICE_DEF_NAME);
+
+ if (xXServiceDefObj == null) {
+ return;
+ }
+
+ Map<String, String> serviceDefOptionsPostUpdate =
jsonStringToMap(xXServiceDefObj.getDefOptions());
+
+ if (serviceDefOptionsPostUpdate == null) {
+ return;
+ }
+
+ String valueAfterUpdate =
serviceDefOptionsPostUpdate.get(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES);
+
+ if (!StringUtils.equals(valueBeforeUpdate, valueAfterUpdate)) {
+ if (StringUtils.isEmpty(valueBeforeUpdate)) {
+
serviceDefOptionsPostUpdate.remove(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES);
+ } else {
+
serviceDefOptionsPostUpdate.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
valueBeforeUpdate);
+ }
+
+
xXServiceDefObj.setDefOptions(mapToJsonString(serviceDefOptionsPostUpdate));
+
+ daoMgr.getXXServiceDef().update(xXServiceDefObj);
+ }
+ }
+
+ protected Map<String, String> jsonStringToMap(String jsonStr) {
+ Map<String, String> ret = null;
+
+ if (!StringUtils.isEmpty(jsonStr)) {
+ try {
+ ret = jsonUtil.jsonToMap(jsonStr);
+ } catch (Exception excp) {
+ // fallback to earlier format: "name1=value1;name2=value2"
+ for (String optionString : jsonStr.split(";")) {
+ if (StringUtils.isEmpty(optionString)) {
+ continue;
+ }
+
+ String[] nvArr = optionString.split("=");
+ String name = (nvArr != null && nvArr.length > 0) ?
nvArr[0].trim() : null;
+ String value = (nvArr != null && nvArr.length > 1) ?
nvArr[1].trim() : null;
+
+ if (StringUtils.isEmpty(name)) {
+ continue;
+ }
+
+ if (ret == null) {
+ ret = new HashMap<>();
+ }
+
+ ret.put(name, value);
+ }
Review Comment:
`optionString.split("=")` will drop trailing empty values (e.g., `"c="`
becomes `["c"]`) and will also truncate values containing `=` (e.g., `"a=b=c"`
keeps only `"b"`). Prefer parsing by first `=` (e.g., `indexOf('=')`) or using
`split("=", 2)` plus logic that preserves empty values, so legacy defOptions
are round-tripped correctly.
##########
security-admin/src/test/java/org/apache/ranger/patch/TestPatchForHiveServiceDefUpdate_J10068.java:
##########
@@ -0,0 +1,433 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.patch;
+
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.JSONUtil;
+import org.apache.ranger.common.RangerValidatorFactory;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.db.XXServiceDefDao;
+import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerRowFilterDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
+import org.apache.ranger.plugin.model.validation.RangerValidator;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.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.ArgumentCaptor;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @description Unit Test for PatchForHiveServiceDefUpdate_J10068 class
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+class TestPatchForHiveServiceDefUpdate_J10068 {
+ private static final String HIVE_SERVICE_DEF_NAME = "hive";
+
+ @Test
+ void testExecLoadAndPrintStats() throws Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ mockSuccessfulDbUpdate(patch);
+
+ patch.execLoad();
+ patch.printStats();
+
+ Mockito.verify(patch.svcStore,
Mockito.atLeastOnce()).updateServiceDef(Mockito.any(RangerServiceDef.class));
+ }
+ }
+
+ @Test
+ void testExecLoad_EmbeddedMissing_FailsAndExits() throws Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(null)) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ assertExecLoadFailsAndExits(patch);
+
+ Mockito.verify(patch.svcStore,
Mockito.never()).updateServiceDef(Mockito.any(RangerServiceDef.class));
+ }
+ }
+
+ @Test
+ void testExecLoad_UpdateReturnsNull_FailsAndExits() throws Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(null).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ assertExecLoadFailsAndExits(patch);
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_rowFilterDefMissing_throwsException() throws
Exception {
+ RangerServiceDef embedded = new RangerServiceDef();
+ embedded.setName(HIVE_SERVICE_DEF_NAME);
+
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(embedded)) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ IllegalStateException ex =
Assertions.assertThrows(IllegalStateException.class,
+ () -> invokeUpdateHiveServiceDef(patch));
+ Assertions.assertTrue(ex.getMessage().contains("rowFilterDef"));
+ Mockito.verify(patch.svcStore,
Mockito.never()).updateServiceDef(Mockito.any(RangerServiceDef.class));
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_copiesOnlyTableResourceFields() throws
Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+ RangerServiceDefValidator validator =
patch.validatorFactory.getServiceDefValidator(patch.svcStore);
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+
+ ArgumentCaptor<RangerServiceDef> captor =
ArgumentCaptor.forClass(RangerServiceDef.class);
+
+ Mockito.verify(validator,
Mockito.atLeastOnce()).validate(Mockito.any(RangerServiceDef.class),
+ Mockito.eq(RangerValidator.Action.UPDATE));
+ Mockito.verify(patch.svcStore).updateServiceDef(captor.capture());
+
+ RangerResourceDef tableResource =
findRowFilterResource(captor.getValue(), "table");
+ RangerResourceDef databaseResource =
findRowFilterResource(captor.getValue(), "database");
+
+ Assertions.assertNotNull(tableResource);
+ Assertions.assertNotNull(tableResource.getMatcherOptions());
+ Assertions.assertEquals("true",
tableResource.getMatcherOptions().get("wildCard"));
+ Assertions.assertEquals("", tableResource.getUiHint());
+
+ Assertions.assertNotNull(databaseResource);
+ Assertions.assertNotNull(databaseResource.getMatcherOptions());
+ Assertions.assertEquals("false",
databaseResource.getMatcherOptions().get("wildCard"));
+ Assertions.assertEquals("{ \"singleValue\":true }",
databaseResource.getUiHint());
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_copiesMatcherOptionsDefensively() throws
Exception {
+ RangerServiceDef embedded = createEmbeddedHiveServiceDef();
+ Map<String, String> embeddedMatcherOptions =
findRowFilterResource(embedded, "table").getMatcherOptions();
+
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(embedded)) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+
+ ArgumentCaptor<RangerServiceDef> captor =
ArgumentCaptor.forClass(RangerServiceDef.class);
+ Mockito.verify(patch.svcStore).updateServiceDef(captor.capture());
+
+ RangerResourceDef tableResource =
findRowFilterResource(captor.getValue(), "table");
+
+ Assertions.assertNotNull(tableResource.getMatcherOptions());
+ Assertions.assertNotSame(embeddedMatcherOptions,
tableResource.getMatcherOptions());
+ Assertions.assertEquals(embeddedMatcherOptions,
tableResource.getMatcherOptions());
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_idempotentWhenAlreadyPatched() throws
Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ RangerServiceDef dbServiceDef = createEmbeddedHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+ invokeUpdateHiveServiceDef(patch);
+
+ Mockito.verify(patch.svcStore,
Mockito.times(2)).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ RangerResourceDef tableResource =
findRowFilterResource(dbServiceDef, "table");
+ Assertions.assertEquals("true",
tableResource.getMatcherOptions().get("wildCard"));
+ Assertions.assertEquals("", tableResource.getUiHint());
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_restoresDefOptionsWhenInjected() throws
Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ XXServiceDefDao xxServiceDefDao = patch.daoMgr.getXXServiceDef();
+ XXServiceDef xdefPre = Mockito.mock(XXServiceDef.class);
+ XXServiceDef xdefPost = Mockito.mock(XXServiceDef.class);
+
+
Mockito.when(xxServiceDefDao.findByName(HIVE_SERVICE_DEF_NAME)).thenReturn(xdefPre,
xdefPost);
+ Mockito.when(xdefPre.getDefOptions()).thenReturn("{}");
+
+ Map<String, String> postMap = new HashMap<>();
+
postMap.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
"true");
+ Mockito.when(xdefPost.getDefOptions()).thenReturn(new
JSONUtil().readMapToString(postMap));
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+
+ Mockito.verify(xxServiceDefDao,
Mockito.times(1)).update(Mockito.eq(xdefPost));
+ }
+ }
+
+ @Test
+ void testJsonStringToMap_withJson() {
+ PatchForHiveServiceDefUpdate_J10068 patch = new
PatchForHiveServiceDefUpdate_J10068();
+ patch.jsonUtil = new JSONUtil();
+
+ Map<String, String> result =
patch.jsonStringToMap("{\"a\":\"1\",\"b\":\"2\"}");
+
+ Assertions.assertEquals("1", result.get("a"));
+ Assertions.assertEquals("2", result.get("b"));
+ }
+
+ @Test
+ void testJsonStringToMap_withLegacyFormat() {
+ PatchForHiveServiceDefUpdate_J10068 patch = new
PatchForHiveServiceDefUpdate_J10068();
+ patch.jsonUtil = new JSONUtil();
+
+ Map<String, String> result = patch.jsonStringToMap("a=1;b=2;c=\n");
+
+ Assertions.assertEquals("1", result.get("a"));
+ Assertions.assertEquals("2", result.get("b"));
+ Assertions.assertTrue(result.containsKey("c"));
+ }
+
+ @Test
+ void testJsonStringToMap_nullOrEmpty() {
+ PatchForHiveServiceDefUpdate_J10068 patch = new
PatchForHiveServiceDefUpdate_J10068();
+ patch.jsonUtil = new JSONUtil();
+
+ Assertions.assertNull(patch.jsonStringToMap(null));
+ Assertions.assertNull(patch.jsonStringToMap(""));
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_preservesExistingDefOptions() throws
Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ XXServiceDefDao xxServiceDefDao = patch.daoMgr.getXXServiceDef();
+ XXServiceDef xdefPre = Mockito.mock(XXServiceDef.class);
+ XXServiceDef xdefPost = Mockito.mock(XXServiceDef.class);
+
+
Mockito.when(xxServiceDefDao.findByName(HIVE_SERVICE_DEF_NAME)).thenReturn(xdefPre,
xdefPost);
+
+ Map<String, String> preMap = new HashMap<>();
+
preMap.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
"abc");
+ Mockito.when(xdefPre.getDefOptions()).thenReturn(new
JSONUtil().readMapToString(preMap));
+
+ Map<String, String> postMap = new HashMap<>();
+
postMap.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
"xyz");
+ Mockito.when(xdefPost.getDefOptions()).thenReturn(new
JSONUtil().readMapToString(postMap));
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+
+ ArgumentCaptor<String> defOptionsCaptor =
ArgumentCaptor.forClass(String.class);
+ Mockito.verify(xdefPost).setDefOptions(defOptionsCaptor.capture());
+ Mockito.verify(xxServiceDefDao,
Mockito.times(1)).update(Mockito.eq(xdefPost));
+ Assertions.assertTrue(defOptionsCaptor.getValue()
+ .contains("\"" +
RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES + "\":\"abc\""));
+ }
+ }
+
+ private void
assertExecLoadFailsAndExits(PatchForHiveServiceDefUpdate_J10068 patch) {
+ SecurityManager original = System.getSecurityManager();
+
+ try {
+ System.setSecurityManager(new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm) {
+ }
+
+ @Override
+ public void checkExit(int status) {
+ throw new SecurityException("Intercepted System.exit");
+ }
+ });
+ patch.execLoad();
+ Assertions.fail("Expected SecurityException");
+ } catch (SecurityException ignored) {
+ } finally {
+ System.setSecurityManager(original);
+ }
+ }
Review Comment:
These tests rely on installing a custom `SecurityManager` to intercept
`System.exit()`. `SecurityManager` is deprecated for removal and may be
disabled in some build/runtime configurations, which can make the test suite
fail or behave inconsistently. A more robust approach is to test the underlying
behavior by invoking `updateHiveServiceDef()` (or a non-exiting helper) and
asserting on thrown exceptions, rather than asserting on `System.exit()`.
##########
security-admin/src/test/java/org/apache/ranger/patch/TestPatchForHiveServiceDefUpdate_J10068.java:
##########
@@ -0,0 +1,433 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.patch;
+
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.JSONUtil;
+import org.apache.ranger.common.RangerValidatorFactory;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.db.XXServiceDefDao;
+import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerRowFilterDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
+import org.apache.ranger.plugin.model.validation.RangerValidator;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.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.ArgumentCaptor;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @description Unit Test for PatchForHiveServiceDefUpdate_J10068 class
+ */
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+class TestPatchForHiveServiceDefUpdate_J10068 {
+ private static final String HIVE_SERVICE_DEF_NAME = "hive";
+
+ @Test
+ void testExecLoadAndPrintStats() throws Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ mockSuccessfulDbUpdate(patch);
+
+ patch.execLoad();
+ patch.printStats();
+
+ Mockito.verify(patch.svcStore,
Mockito.atLeastOnce()).updateServiceDef(Mockito.any(RangerServiceDef.class));
+ }
+ }
+
+ @Test
+ void testExecLoad_EmbeddedMissing_FailsAndExits() throws Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(null)) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ assertExecLoadFailsAndExits(patch);
+
+ Mockito.verify(patch.svcStore,
Mockito.never()).updateServiceDef(Mockito.any(RangerServiceDef.class));
+ }
+ }
+
+ @Test
+ void testExecLoad_UpdateReturnsNull_FailsAndExits() throws Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(null).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ assertExecLoadFailsAndExits(patch);
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_rowFilterDefMissing_throwsException() throws
Exception {
+ RangerServiceDef embedded = new RangerServiceDef();
+ embedded.setName(HIVE_SERVICE_DEF_NAME);
+
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(embedded)) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ IllegalStateException ex =
Assertions.assertThrows(IllegalStateException.class,
+ () -> invokeUpdateHiveServiceDef(patch));
+ Assertions.assertTrue(ex.getMessage().contains("rowFilterDef"));
+ Mockito.verify(patch.svcStore,
Mockito.never()).updateServiceDef(Mockito.any(RangerServiceDef.class));
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_copiesOnlyTableResourceFields() throws
Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+ RangerServiceDefValidator validator =
patch.validatorFactory.getServiceDefValidator(patch.svcStore);
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+
+ ArgumentCaptor<RangerServiceDef> captor =
ArgumentCaptor.forClass(RangerServiceDef.class);
+
+ Mockito.verify(validator,
Mockito.atLeastOnce()).validate(Mockito.any(RangerServiceDef.class),
+ Mockito.eq(RangerValidator.Action.UPDATE));
+ Mockito.verify(patch.svcStore).updateServiceDef(captor.capture());
+
+ RangerResourceDef tableResource =
findRowFilterResource(captor.getValue(), "table");
+ RangerResourceDef databaseResource =
findRowFilterResource(captor.getValue(), "database");
+
+ Assertions.assertNotNull(tableResource);
+ Assertions.assertNotNull(tableResource.getMatcherOptions());
+ Assertions.assertEquals("true",
tableResource.getMatcherOptions().get("wildCard"));
+ Assertions.assertEquals("", tableResource.getUiHint());
+
+ Assertions.assertNotNull(databaseResource);
+ Assertions.assertNotNull(databaseResource.getMatcherOptions());
+ Assertions.assertEquals("false",
databaseResource.getMatcherOptions().get("wildCard"));
+ Assertions.assertEquals("{ \"singleValue\":true }",
databaseResource.getUiHint());
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_copiesMatcherOptionsDefensively() throws
Exception {
+ RangerServiceDef embedded = createEmbeddedHiveServiceDef();
+ Map<String, String> embeddedMatcherOptions =
findRowFilterResource(embedded, "table").getMatcherOptions();
+
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(embedded)) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+
+ ArgumentCaptor<RangerServiceDef> captor =
ArgumentCaptor.forClass(RangerServiceDef.class);
+ Mockito.verify(patch.svcStore).updateServiceDef(captor.capture());
+
+ RangerResourceDef tableResource =
findRowFilterResource(captor.getValue(), "table");
+
+ Assertions.assertNotNull(tableResource.getMatcherOptions());
+ Assertions.assertNotSame(embeddedMatcherOptions,
tableResource.getMatcherOptions());
+ Assertions.assertEquals(embeddedMatcherOptions,
tableResource.getMatcherOptions());
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_idempotentWhenAlreadyPatched() throws
Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ RangerServiceDef dbServiceDef = createEmbeddedHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+ invokeUpdateHiveServiceDef(patch);
+
+ Mockito.verify(patch.svcStore,
Mockito.times(2)).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ RangerResourceDef tableResource =
findRowFilterResource(dbServiceDef, "table");
+ Assertions.assertEquals("true",
tableResource.getMatcherOptions().get("wildCard"));
+ Assertions.assertEquals("", tableResource.getUiHint());
+ }
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_restoresDefOptionsWhenInjected() throws
Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ XXServiceDefDao xxServiceDefDao = patch.daoMgr.getXXServiceDef();
+ XXServiceDef xdefPre = Mockito.mock(XXServiceDef.class);
+ XXServiceDef xdefPost = Mockito.mock(XXServiceDef.class);
+
+
Mockito.when(xxServiceDefDao.findByName(HIVE_SERVICE_DEF_NAME)).thenReturn(xdefPre,
xdefPost);
+ Mockito.when(xdefPre.getDefOptions()).thenReturn("{}");
+
+ Map<String, String> postMap = new HashMap<>();
+
postMap.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
"true");
+ Mockito.when(xdefPost.getDefOptions()).thenReturn(new
JSONUtil().readMapToString(postMap));
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+
+ Mockito.verify(xxServiceDefDao,
Mockito.times(1)).update(Mockito.eq(xdefPost));
+ }
+ }
+
+ @Test
+ void testJsonStringToMap_withJson() {
+ PatchForHiveServiceDefUpdate_J10068 patch = new
PatchForHiveServiceDefUpdate_J10068();
+ patch.jsonUtil = new JSONUtil();
+
+ Map<String, String> result =
patch.jsonStringToMap("{\"a\":\"1\",\"b\":\"2\"}");
+
+ Assertions.assertEquals("1", result.get("a"));
+ Assertions.assertEquals("2", result.get("b"));
+ }
+
+ @Test
+ void testJsonStringToMap_withLegacyFormat() {
+ PatchForHiveServiceDefUpdate_J10068 patch = new
PatchForHiveServiceDefUpdate_J10068();
+ patch.jsonUtil = new JSONUtil();
+
+ Map<String, String> result = patch.jsonStringToMap("a=1;b=2;c=\n");
+
+ Assertions.assertEquals("1", result.get("a"));
+ Assertions.assertEquals("2", result.get("b"));
+ Assertions.assertTrue(result.containsKey("c"));
+ }
+
+ @Test
+ void testJsonStringToMap_nullOrEmpty() {
+ PatchForHiveServiceDefUpdate_J10068 patch = new
PatchForHiveServiceDefUpdate_J10068();
+ patch.jsonUtil = new JSONUtil();
+
+ Assertions.assertNull(patch.jsonStringToMap(null));
+ Assertions.assertNull(patch.jsonStringToMap(""));
+ }
+
+ @Test
+ void testUpdateHiveServiceDef_preservesExistingDefOptions() throws
Exception {
+ try (MockedStatic<EmbeddedServiceDefsUtil> utilMock =
mockEmbeddedServiceDef(createEmbeddedHiveServiceDef())) {
+ PatchForHiveServiceDefUpdate_J10068 patch = createPatchWithMocks();
+
+ XXServiceDefDao xxServiceDefDao = patch.daoMgr.getXXServiceDef();
+ XXServiceDef xdefPre = Mockito.mock(XXServiceDef.class);
+ XXServiceDef xdefPost = Mockito.mock(XXServiceDef.class);
+
+
Mockito.when(xxServiceDefDao.findByName(HIVE_SERVICE_DEF_NAME)).thenReturn(xdefPre,
xdefPost);
+
+ Map<String, String> preMap = new HashMap<>();
+
preMap.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
"abc");
+ Mockito.when(xdefPre.getDefOptions()).thenReturn(new
JSONUtil().readMapToString(preMap));
+
+ Map<String, String> postMap = new HashMap<>();
+
postMap.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
"xyz");
+ Mockito.when(xdefPost.getDefOptions()).thenReturn(new
JSONUtil().readMapToString(postMap));
+
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+
+ invokeUpdateHiveServiceDef(patch);
+
+ ArgumentCaptor<String> defOptionsCaptor =
ArgumentCaptor.forClass(String.class);
+ Mockito.verify(xdefPost).setDefOptions(defOptionsCaptor.capture());
+ Mockito.verify(xxServiceDefDao,
Mockito.times(1)).update(Mockito.eq(xdefPost));
+ Assertions.assertTrue(defOptionsCaptor.getValue()
+ .contains("\"" +
RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES + "\":\"abc\""));
+ }
+ }
+
+ private void
assertExecLoadFailsAndExits(PatchForHiveServiceDefUpdate_J10068 patch) {
+ SecurityManager original = System.getSecurityManager();
+
+ try {
+ System.setSecurityManager(new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm) {
+ }
+
+ @Override
+ public void checkExit(int status) {
+ throw new SecurityException("Intercepted System.exit");
+ }
+ });
+ patch.execLoad();
+ Assertions.fail("Expected SecurityException");
+ } catch (SecurityException ignored) {
+ } finally {
+ System.setSecurityManager(original);
+ }
+ }
+
+ private PatchForHiveServiceDefUpdate_J10068 createPatchWithMocks() {
+ PatchForHiveServiceDefUpdate_J10068 patch = new
PatchForHiveServiceDefUpdate_J10068();
+
+ ServiceDBStore svcStore = Mockito.mock(ServiceDBStore.class);
+ RangerValidatorFactory validatorFactory =
Mockito.mock(RangerValidatorFactory.class);
+ RangerServiceDefValidator validator =
Mockito.mock(RangerServiceDefValidator.class);
+ RangerDaoManager daoMgr = Mockito.mock(RangerDaoManager.class);
+ XXServiceDefDao xxServiceDefDao = Mockito.mock(XXServiceDefDao.class);
+
+
Mockito.lenient().when(validatorFactory.getServiceDefValidator(svcStore)).thenReturn(validator);
+
Mockito.lenient().when(daoMgr.getXXServiceDef()).thenReturn(xxServiceDefDao);
+
+ XXServiceDef xXServiceDef = Mockito.mock(XXServiceDef.class);
+
Mockito.lenient().when(xxServiceDefDao.findByName(HIVE_SERVICE_DEF_NAME)).thenReturn(xXServiceDef);
+ Mockito.lenient().when(xXServiceDef.getDefOptions()).thenReturn("{}");
+
+ patch.svcStore = svcStore;
+ patch.validatorFactory = validatorFactory;
+ patch.daoMgr = daoMgr;
+ patch.jsonUtil = new JSONUtil();
+
+ return patch;
+ }
+
+ private void mockSuccessfulDbUpdate(PatchForHiveServiceDefUpdate_J10068
patch) throws Exception {
+ RangerServiceDef dbServiceDef = createDbHiveServiceDef();
+
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).getServiceDefByName(HIVE_SERVICE_DEF_NAME);
+
Mockito.doReturn(dbServiceDef).when(patch.svcStore).updateServiceDef(Mockito.any(RangerServiceDef.class));
+ }
+
+ private MockedStatic<EmbeddedServiceDefsUtil>
mockEmbeddedServiceDef(RangerServiceDef embedded) throws Exception {
+ MockedStatic<EmbeddedServiceDefsUtil> utilMock =
Mockito.mockStatic(EmbeddedServiceDefsUtil.class);
+ EmbeddedServiceDefsUtil util =
Mockito.mock(EmbeddedServiceDefsUtil.class);
+
+ utilMock.when(EmbeddedServiceDefsUtil::instance).thenReturn(util);
+
Mockito.doReturn(embedded).when(util).getEmbeddedServiceDef(HIVE_SERVICE_DEF_NAME);
+
+ return utilMock;
+ }
+
+ private RangerServiceDef createEmbeddedHiveServiceDef() {
+ RangerServiceDef embedded = new RangerServiceDef();
+ embedded.setName(HIVE_SERVICE_DEF_NAME);
+ embedded.setRowFilterDef(createEmbeddedRowFilterDef());
+ return embedded;
+ }
+
+ private RangerServiceDef createDbHiveServiceDef() {
+ RangerServiceDef dbServiceDef = new RangerServiceDef();
+ dbServiceDef.setName(HIVE_SERVICE_DEF_NAME);
+ dbServiceDef.setRowFilterDef(createDbRowFilterDef());
+ return dbServiceDef;
+ }
+
+ private RangerRowFilterDef createEmbeddedRowFilterDef() {
+ Map<String, String> tableMatcherOptions = new HashMap<>();
+ tableMatcherOptions.put("wildCard", "true");
+
+ RangerResourceDef databaseResource = new RangerResourceDef();
+ databaseResource.setName("database");
+
+ RangerResourceDef tableResource = new RangerResourceDef();
+ tableResource.setName("table");
+ tableResource.setMatcherOptions(tableMatcherOptions);
+ tableResource.setUiHint("");
+
+ RangerRowFilterDef rowFilterDef = new RangerRowFilterDef();
+ rowFilterDef.setResources(Arrays.asList(databaseResource,
tableResource));
+
+ return rowFilterDef;
+ }
+
+ private RangerRowFilterDef createDbRowFilterDef() {
+ Map<String, String> databaseMatcherOptions = new HashMap<>();
+ databaseMatcherOptions.put("wildCard", "false");
+
+ Map<String, String> tableMatcherOptions = new HashMap<>();
+ tableMatcherOptions.put("wildCard", "false");
+
+ RangerResourceDef databaseResource = new RangerResourceDef();
+ databaseResource.setName("database");
+ databaseResource.setMatcherOptions(databaseMatcherOptions);
+ databaseResource.setUiHint("{ \"singleValue\":true }");
+
+ RangerResourceDef tableResource = new RangerResourceDef();
+ tableResource.setName("table");
+ tableResource.setMatcherOptions(tableMatcherOptions);
+ tableResource.setUiHint("{ \"singleValue\":true }");
+
+ RangerRowFilterDef rowFilterDef = new RangerRowFilterDef();
+ rowFilterDef.setResources(Arrays.asList(databaseResource,
tableResource));
+
+ return rowFilterDef;
+ }
+
+ private RangerResourceDef findRowFilterResource(RangerServiceDef
serviceDef, String resourceName) {
+ RangerResourceDef result = null;
+
+ if (serviceDef != null && serviceDef.getRowFilterDef() != null &&
serviceDef.getRowFilterDef().getResources() != null) {
+ for (RangerResourceDef resourceDef :
serviceDef.getRowFilterDef().getResources()) {
+ if (resourceName.equals(resourceDef.getName())) {
+ result = resourceDef;
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void
invokeUpdateHiveServiceDef(PatchForHiveServiceDefUpdate_J10068 patch) throws
Exception {
+ Method method =
PatchForHiveServiceDefUpdate_J10068.class.getDeclaredMethod("updateHiveServiceDef");
+ method.setAccessible(true);
+
+ try {
+ method.invoke(patch);
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+
+ if (cause instanceof Exception) {
+ throw (Exception) cause;
+ }
+
+ if (cause instanceof Error) {
+ throw (Error) cause;
+ }
+
+ throw e;
+ }
+ }
Review Comment:
The tests use reflection to call `updateHiveServiceDef()`, which adds
verbosity and makes failures harder to debug (access checks, wrapped
exceptions, etc.). Since the test is in the same package
(`org.apache.ranger.patch`), consider making `updateHiveServiceDef()`
package-private (or `protected` with a clear “visible for testing” intent) so
tests can call it directly and avoid reflection.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]