github-advanced-security[bot] commented on code in PR #18844:
URL: https://github.com/apache/druid/pull/18844#discussion_r2620794691


##########
processing/src/main/java/org/apache/druid/timeline/CompactionState.java:
##########
@@ -50,6 +59,26 @@
  */
 public class CompactionState
 {
+
+  /**
+   * Lazy initialization holder for deterministic ObjectMapper.
+   * This inner static class is only loaded when first accessed, ensuring all 
Druid modules
+   * are properly initialized before the ObjectMapper is created.
+   * Based on DefaultObjectMapper (with all Druid modules) plus alphabetical 
sorting for consistency.
+   */
+  private static class DeterministicMapperHolder
+  {
+    static final ObjectMapper INSTANCE = createDeterministicMapper();
+
+    private static ObjectMapper createDeterministicMapper()
+    {
+      DefaultObjectMapper baseMapper = new DefaultObjectMapper();
+      baseMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, 
true);
+      baseMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);

Review Comment:
   ## Deprecated method or constructor invocation
   
   Invoking [ObjectMapper.configure](1) should be avoided because it has been 
deprecated.
   
   [Show more 
details](https://github.com/apache/druid/security/code-scanning/10593)



##########
processing/src/test/java/org/apache/druid/timeline/DataSegmentTest.java:
##########
@@ -513,6 +513,120 @@
 
   }
 
+  @Test
+  public void testSerializationWithCompactionStateFingerprint() throws 
Exception
+  {
+    final Interval interval = Intervals.of("2011-10-01/2011-10-02");
+    final ImmutableMap<String, Object> loadSpec = ImmutableMap.of("something", 
"or_other");
+    final String fingerprint = "abc123def456";
+
+    DataSegment segment = DataSegment.builder()

Review Comment:
   ## Deprecated method or constructor invocation
   
   Invoking [DataSegment.builder](1) should be avoided because it has been 
deprecated.
   
   [Show more 
details](https://github.com/apache/druid/security/code-scanning/10594)



##########
processing/src/test/java/org/apache/druid/timeline/DataSegmentTest.java:
##########
@@ -513,6 +513,120 @@
 
   }
 
+  @Test
+  public void testSerializationWithCompactionStateFingerprint() throws 
Exception
+  {
+    final Interval interval = Intervals.of("2011-10-01/2011-10-02");
+    final ImmutableMap<String, Object> loadSpec = ImmutableMap.of("something", 
"or_other");
+    final String fingerprint = "abc123def456";
+
+    DataSegment segment = DataSegment.builder()
+                                     .dataSource("something")
+                                     .interval(interval)
+                                     .version("1")
+                                     .loadSpec(loadSpec)
+                                     .dimensions(Arrays.asList("dim1", "dim2"))
+                                     .metrics(Arrays.asList("met1", "met2"))
+                                     .shardSpec(new NumberedShardSpec(3, 0))
+                                     .compactionStateFingerprint(fingerprint)
+                                     .binaryVersion(TEST_VERSION)
+                                     .size(1)
+                                     .build();
+
+    // Verify fingerprint is present in serialized JSON
+    final Map<String, Object> objectMap = MAPPER.readValue(
+        MAPPER.writeValueAsString(segment),
+        JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT
+    );
+    Assert.assertEquals(fingerprint, 
objectMap.get("compactionStateFingerprint"));
+
+    // Verify deserialization preserves fingerprint
+    DataSegment deserializedSegment = 
MAPPER.readValue(MAPPER.writeValueAsString(segment), DataSegment.class);
+    Assert.assertEquals(fingerprint, 
deserializedSegment.getCompactionStateFingerprint());
+    Assert.assertEquals(segment.hashCode(), deserializedSegment.hashCode());
+  }
+
+  @Test
+  public void testSerializationWithNullCompactionStateFingerprint() throws 
Exception
+  {
+    final Interval interval = Intervals.of("2011-10-01/2011-10-02");
+    final ImmutableMap<String, Object> loadSpec = ImmutableMap.of("something", 
"or_other");
+
+    DataSegment segment = DataSegment.builder()
+                                     .dataSource("something")
+                                     .interval(interval)
+                                     .version("1")
+                                     .loadSpec(loadSpec)
+                                     .dimensions(Arrays.asList("dim1", "dim2"))
+                                     .metrics(Arrays.asList("met1", "met2"))
+                                     .shardSpec(new NumberedShardSpec(3, 0))
+                                     .compactionStateFingerprint(null)
+                                     .binaryVersion(TEST_VERSION)
+                                     .size(1)
+                                     .build();
+
+    // Verify fingerprint is NOT present in serialized JSON (due to 
@JsonInclude(NON_NULL))
+    final Map<String, Object> objectMap = MAPPER.readValue(
+        MAPPER.writeValueAsString(segment),
+        JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT
+    );
+    Assert.assertFalse("compactionStateFingerprint should not be in JSON when 
null",
+                       objectMap.containsKey("compactionStateFingerprint"));
+
+    // Verify deserialization handles missing fingerprint
+    DataSegment deserializedSegment = 
MAPPER.readValue(MAPPER.writeValueAsString(segment), DataSegment.class);
+    Assert.assertNull(deserializedSegment.getCompactionStateFingerprint());
+    Assert.assertEquals(segment.hashCode(), deserializedSegment.hashCode());
+  }
+
+  @Test
+  public void 
testDeserializationBackwardCompatibility_missingCompactionStateFingerprint() 
throws Exception
+  {
+    // Simulate JSON from old Druid version without compactionStateFingerprint 
field
+    String jsonWithoutFingerprint = "{"
+                                    + "\"dataSource\": \"something\","
+                                    + "\"interval\": 
\"2011-10-01T00:00:00.000Z/2011-10-02T00:00:00.000Z\","
+                                    + "\"version\": \"1\","
+                                    + "\"loadSpec\": {\"something\": 
\"or_other\"},"
+                                    + "\"dimensions\": \"dim1,dim2\","
+                                    + "\"metrics\": \"met1,met2\","
+                                    + "\"shardSpec\": {\"type\": \"numbered\", 
\"partitionNum\": 3, \"partitions\": 0},"
+                                    + "\"binaryVersion\": 9,"
+                                    + "\"size\": 1"
+                                    + "}";
+
+    DataSegment deserializedSegment = MAPPER.readValue(jsonWithoutFingerprint, 
DataSegment.class);
+    Assert.assertNull("compactionStateFingerprint should be null for backward 
compatibility",
+                      deserializedSegment.getCompactionStateFingerprint());
+    Assert.assertEquals("something", deserializedSegment.getDataSource());
+    Assert.assertEquals(Intervals.of("2011-10-01/2011-10-02"), 
deserializedSegment.getInterval());
+  }
+
+  @Test
+  public void testWithCompactionStateFingerprint()
+  {
+    final String fingerprint = "test_fingerprint_12345";
+    final DataSegment segment1 = DataSegment.builder()
+                                            .dataSource("foo")
+                                            
.interval(Intervals.of("2012-01-01/2012-01-02"))
+                                            
.version(DateTimes.of("2012-01-01T11:22:33.444Z").toString())
+                                            .shardSpec(getShardSpec(7))
+                                            .size(0)
+                                            
.compactionStateFingerprint(fingerprint)
+                                            .build();
+    final DataSegment segment2 = DataSegment.builder()

Review Comment:
   ## Deprecated method or constructor invocation
   
   Invoking [DataSegment.builder](1) should be avoided because it has been 
deprecated.
   
   [Show more 
details](https://github.com/apache/druid/security/code-scanning/10597)



##########
processing/src/test/java/org/apache/druid/timeline/DataSegmentTest.java:
##########
@@ -513,6 +513,120 @@
 
   }
 
+  @Test
+  public void testSerializationWithCompactionStateFingerprint() throws 
Exception
+  {
+    final Interval interval = Intervals.of("2011-10-01/2011-10-02");
+    final ImmutableMap<String, Object> loadSpec = ImmutableMap.of("something", 
"or_other");
+    final String fingerprint = "abc123def456";
+
+    DataSegment segment = DataSegment.builder()
+                                     .dataSource("something")
+                                     .interval(interval)
+                                     .version("1")
+                                     .loadSpec(loadSpec)
+                                     .dimensions(Arrays.asList("dim1", "dim2"))
+                                     .metrics(Arrays.asList("met1", "met2"))
+                                     .shardSpec(new NumberedShardSpec(3, 0))
+                                     .compactionStateFingerprint(fingerprint)
+                                     .binaryVersion(TEST_VERSION)
+                                     .size(1)
+                                     .build();
+
+    // Verify fingerprint is present in serialized JSON
+    final Map<String, Object> objectMap = MAPPER.readValue(
+        MAPPER.writeValueAsString(segment),
+        JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT
+    );
+    Assert.assertEquals(fingerprint, 
objectMap.get("compactionStateFingerprint"));
+
+    // Verify deserialization preserves fingerprint
+    DataSegment deserializedSegment = 
MAPPER.readValue(MAPPER.writeValueAsString(segment), DataSegment.class);
+    Assert.assertEquals(fingerprint, 
deserializedSegment.getCompactionStateFingerprint());
+    Assert.assertEquals(segment.hashCode(), deserializedSegment.hashCode());
+  }
+
+  @Test
+  public void testSerializationWithNullCompactionStateFingerprint() throws 
Exception
+  {
+    final Interval interval = Intervals.of("2011-10-01/2011-10-02");
+    final ImmutableMap<String, Object> loadSpec = ImmutableMap.of("something", 
"or_other");
+
+    DataSegment segment = DataSegment.builder()

Review Comment:
   ## Deprecated method or constructor invocation
   
   Invoking [DataSegment.builder](1) should be avoided because it has been 
deprecated.
   
   [Show more 
details](https://github.com/apache/druid/security/code-scanning/10595)



##########
processing/src/test/java/org/apache/druid/timeline/DataSegmentTest.java:
##########
@@ -513,6 +513,120 @@
 
   }
 
+  @Test
+  public void testSerializationWithCompactionStateFingerprint() throws 
Exception
+  {
+    final Interval interval = Intervals.of("2011-10-01/2011-10-02");
+    final ImmutableMap<String, Object> loadSpec = ImmutableMap.of("something", 
"or_other");
+    final String fingerprint = "abc123def456";
+
+    DataSegment segment = DataSegment.builder()
+                                     .dataSource("something")
+                                     .interval(interval)
+                                     .version("1")
+                                     .loadSpec(loadSpec)
+                                     .dimensions(Arrays.asList("dim1", "dim2"))
+                                     .metrics(Arrays.asList("met1", "met2"))
+                                     .shardSpec(new NumberedShardSpec(3, 0))
+                                     .compactionStateFingerprint(fingerprint)
+                                     .binaryVersion(TEST_VERSION)
+                                     .size(1)
+                                     .build();
+
+    // Verify fingerprint is present in serialized JSON
+    final Map<String, Object> objectMap = MAPPER.readValue(
+        MAPPER.writeValueAsString(segment),
+        JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT
+    );
+    Assert.assertEquals(fingerprint, 
objectMap.get("compactionStateFingerprint"));
+
+    // Verify deserialization preserves fingerprint
+    DataSegment deserializedSegment = 
MAPPER.readValue(MAPPER.writeValueAsString(segment), DataSegment.class);
+    Assert.assertEquals(fingerprint, 
deserializedSegment.getCompactionStateFingerprint());
+    Assert.assertEquals(segment.hashCode(), deserializedSegment.hashCode());
+  }
+
+  @Test
+  public void testSerializationWithNullCompactionStateFingerprint() throws 
Exception
+  {
+    final Interval interval = Intervals.of("2011-10-01/2011-10-02");
+    final ImmutableMap<String, Object> loadSpec = ImmutableMap.of("something", 
"or_other");
+
+    DataSegment segment = DataSegment.builder()
+                                     .dataSource("something")
+                                     .interval(interval)
+                                     .version("1")
+                                     .loadSpec(loadSpec)
+                                     .dimensions(Arrays.asList("dim1", "dim2"))
+                                     .metrics(Arrays.asList("met1", "met2"))
+                                     .shardSpec(new NumberedShardSpec(3, 0))
+                                     .compactionStateFingerprint(null)
+                                     .binaryVersion(TEST_VERSION)
+                                     .size(1)
+                                     .build();
+
+    // Verify fingerprint is NOT present in serialized JSON (due to 
@JsonInclude(NON_NULL))
+    final Map<String, Object> objectMap = MAPPER.readValue(
+        MAPPER.writeValueAsString(segment),
+        JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT
+    );
+    Assert.assertFalse("compactionStateFingerprint should not be in JSON when 
null",
+                       objectMap.containsKey("compactionStateFingerprint"));
+
+    // Verify deserialization handles missing fingerprint
+    DataSegment deserializedSegment = 
MAPPER.readValue(MAPPER.writeValueAsString(segment), DataSegment.class);
+    Assert.assertNull(deserializedSegment.getCompactionStateFingerprint());
+    Assert.assertEquals(segment.hashCode(), deserializedSegment.hashCode());
+  }
+
+  @Test
+  public void 
testDeserializationBackwardCompatibility_missingCompactionStateFingerprint() 
throws Exception
+  {
+    // Simulate JSON from old Druid version without compactionStateFingerprint 
field
+    String jsonWithoutFingerprint = "{"
+                                    + "\"dataSource\": \"something\","
+                                    + "\"interval\": 
\"2011-10-01T00:00:00.000Z/2011-10-02T00:00:00.000Z\","
+                                    + "\"version\": \"1\","
+                                    + "\"loadSpec\": {\"something\": 
\"or_other\"},"
+                                    + "\"dimensions\": \"dim1,dim2\","
+                                    + "\"metrics\": \"met1,met2\","
+                                    + "\"shardSpec\": {\"type\": \"numbered\", 
\"partitionNum\": 3, \"partitions\": 0},"
+                                    + "\"binaryVersion\": 9,"
+                                    + "\"size\": 1"
+                                    + "}";
+
+    DataSegment deserializedSegment = MAPPER.readValue(jsonWithoutFingerprint, 
DataSegment.class);
+    Assert.assertNull("compactionStateFingerprint should be null for backward 
compatibility",
+                      deserializedSegment.getCompactionStateFingerprint());
+    Assert.assertEquals("something", deserializedSegment.getDataSource());
+    Assert.assertEquals(Intervals.of("2011-10-01/2011-10-02"), 
deserializedSegment.getInterval());
+  }
+
+  @Test
+  public void testWithCompactionStateFingerprint()
+  {
+    final String fingerprint = "test_fingerprint_12345";
+    final DataSegment segment1 = DataSegment.builder()

Review Comment:
   ## Deprecated method or constructor invocation
   
   Invoking [DataSegment.builder](1) should be avoided because it has been 
deprecated.
   
   [Show more 
details](https://github.com/apache/druid/security/code-scanning/10596)



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to