This is an automated email from the ASF dual-hosted git repository.
abhi 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 fb4f8d9ea RANGER-5251: dedupTags() doesn’t remove duplicate tag IDs
within a single resource’s resourceToTagIds list (#608)
fb4f8d9ea is described below
commit fb4f8d9ea395f72b3cfe2c7936aeb67ff4ee7c16
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)
---
.../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 74b2464a8..56ac3a0d3 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
@@ -33,10 +33,12 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.Set;
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@@ -280,6 +282,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;
@@ -292,6 +295,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 a2d52427f..7e1720518 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();