This is an automated email from the ASF dual-hosted git repository. abhi pushed a commit to branch ranger-2.7 in repository https://gitbox.apache.org/repos/asf/ranger.git
commit 871ebc43b5c194089efb31ae877f407bba294a03 Author: Vyom Mani Tiwari <[email protected]> AuthorDate: Wed Jul 16 20:59:18 2025 +0530 RANGER-5251: dedupTags() doesn’t remove duplicate tag IDs within a single resource’s resourceToTagIds list (#608) (cherry picked from commit fb4f8d9ea395f72b3cfe2c7936aeb67ff4ee7c16) --- .../org/apache/ranger/plugin/util/ServiceTags.java | 8 ++++ .../apache/ranger/plugin/util/TestServiceTags.java | 51 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceTags.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceTags.java index 12f026e32..c77b96711 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceTags.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceTags.java @@ -21,12 +21,14 @@ import java.util.Date; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.HashMap; import java.util.ArrayList; +import java.util.Set; import org.apache.commons.lang3.tuple.MutablePair; import org.apache.ranger.authorization.utils.StringUtil; @@ -283,6 +285,7 @@ public int dedupTags() { final int finalTagsCount = tags.size(); for (Map.Entry<Long, List<Long>> resourceEntry : resourceToTagIds.entrySet()) { + Set<Long> uniqueTagIds = new HashSet<>(resourceEntry.getValue().size()); for (ListIterator<Long> listIter = resourceEntry.getValue().listIterator(); listIter.hasNext(); ) { final Long tagId = listIter.next(); Long mappedTagId = null; @@ -295,6 +298,11 @@ public int dedupTags() { continue; } + if (!uniqueTagIds.add(mappedTagId)) { + listIter.remove(); + continue; + } + listIter.set(mappedTagId); RangerTag tag = tags.get(mappedTagId); diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestServiceTags.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestServiceTags.java index d44309805..3866942bd 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestServiceTags.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestServiceTags.java @@ -23,9 +23,12 @@ import org.junit.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -205,6 +208,54 @@ public void testDedupTags_HigherIdTagAfterLowerIdRemoval() { assertFalse(svcTags1.getTags().containsKey(newTagId)); } + @Test + public void testDedupTags_DuplicateResourceToTagIds() { + RangerTag[] tags = { + new RangerTag("PII", Collections.singletonMap("type", "email")), + new RangerTag("PII", Collections.singletonMap("type", "email")), + new RangerTag("PCI", Collections.emptyMap()), + new RangerTag("PCI", Collections.emptyMap()), + new RangerTag("PII", Collections.singletonMap("type", "email")) + }; + ServiceTags svcTags = createServiceTags(tags, RESOURCES); + assertEquals(5, svcTags.getTags().size()); + + int dedupCount = svcTags.dedupTags(); + assertEquals(3, dedupCount); + assertEquals(2, svcTags.getTags().size()); + + ServiceTags svcTags1 = new ServiceTags(svcTags); + // Simulate resource1 deletion (like delete table_1) + svcTags1.getResourceToTagIds().remove(0L); + // Clear tags to simulate new sync + svcTags1.getTags().clear(); + + RangerTag tag1 = new RangerTag("PII", Collections.singletonMap("type", "email")); + RangerTag tag2 = new RangerTag("PII", Collections.singletonMap("type", "email")); + tag1.setId(200L); + tag2.setId(201L); + svcTags1.getTags().put(200L, tag1); + svcTags1.getTags().put(201L, tag2); + + // Set resource mappings with duplicate tag IDs + svcTags1.getResourceToTagIds().put(0L, new ArrayList<>(Arrays.asList(200L, 200L, 201L))); + svcTags1.getResourceToTagIds().put(1L, new ArrayList<>(Arrays.asList(200L, 200L, 201L, 201L))); + + dedupCount = svcTags1.dedupTags(); + assertEquals(1, dedupCount); + assertEquals(1, svcTags1.getTags().size()); + + // Verify resource1 has no duplicate tag IDs + List<Long> resource1Tags = svcTags1.getResourceToTagIds().get(0L); + Set<Long> uniqueTags = new HashSet<>(resource1Tags); + assertEquals("Duplicate tag IDs should be removed from resource1", uniqueTags.size(), resource1Tags.size()); + + // Verify resource2 has no duplicate tag IDs + List<Long> resource2Tags = svcTags1.getResourceToTagIds().get(1L); + uniqueTags = new HashSet<>(resource2Tags); + assertEquals("Duplicate tag IDs should be removed from resource2", uniqueTags.size(), resource2Tags.size()); + } + private ServiceTags createServiceTags(RangerTag[] tags, RangerServiceResource[] resources) { ServiceTags ret = new ServiceTags();
