From 3dd5f34a7b76ca8c78a54d78ebd1b114683a56e9 Mon Sep 17 00:00:00 2001 From: Hiroshi Fukada Date: Fri, 21 Nov 2025 12:38:07 -0500 Subject: [PATCH 1/2] fix(protobuf-core): re-introduce the load-by-file-path/url protobuf descriptors --- .../FileBasedProtobufBytesDecoder.java | 24 +++++++++++++++++-- .../FileBasedProtobufBytesDecoderTest.java | 13 +++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoder.java b/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoder.java index 39ce2520f420..bbd394acfa09 100644 --- a/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoder.java +++ b/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoder.java @@ -27,6 +27,8 @@ import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Objects; public class FileBasedProtobufBytesDecoder extends DescriptorBasedProtobufBytesDecoder @@ -56,9 +58,27 @@ public String getDescriptorFilePath() @Override protected DescriptorProtos.FileDescriptorSet loadFileDescriptorSet() { - try (InputStream fin = this.getClass().getClassLoader().getResourceAsStream(descriptorFilePath)) { + InputStream fin; + try { + fin = this.getClass().getClassLoader().getResourceAsStream(descriptorFilePath); if (fin == null) { - throw new ParseException(descriptorFilePath, "Descriptor not found in class path [%s]", descriptorFilePath); + URL url; + try { + url = new URL(descriptorFilePath); + } + catch (MalformedURLException e) { + throw new ParseException( + descriptorFilePath, + e, + "Descriptor not found in class path or malformed URL: [%s]", descriptorFilePath + ); + } + try { + fin = url.openConnection().getInputStream(); + } + catch (IOException e) { + throw new ParseException(url.toString(), e, "Cannot read descriptor file: [%s]", url); + } } final var descriptorSet = DescriptorProtos.FileDescriptorSet.parseFrom(fin); diff --git a/extensions-core/protobuf-extensions/src/test/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoderTest.java b/extensions-core/protobuf-extensions/src/test/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoderTest.java index d6eb00ccf500..15f32394f150 100644 --- a/extensions-core/protobuf-extensions/src/test/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoderTest.java +++ b/extensions-core/protobuf-extensions/src/test/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoderTest.java @@ -25,6 +25,7 @@ import org.apache.druid.java.util.common.parsers.ParseException; import org.junit.jupiter.api.Test; +import java.io.File; import java.nio.ByteBuffer; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @@ -68,6 +69,16 @@ public void testMoreComplexProtoFile() assertEquals("prototest.ProtoNestedEvent", decoder.getDescriptor().getFullName()); } + @Test + public void tesDescriptorUrl() + { + File descFile = new File("src/test/resources/proto_test_event.desc"); + String path = descFile.getAbsoluteFile().toString(); + + final var decoder = new FileBasedProtobufBytesDecoder("file://" + path, "ProtoTestEvent"); + assertEquals("prototest.ProtoTestEvent", decoder.getDescriptor().getFullName()); + } + @Test public void testParsingWithMoreComplexProtoFile() throws Exception { @@ -123,7 +134,7 @@ public void testMalformedDescriptorUrl() ); assertEquals( - "Descriptor not found in class path [file:/nonexist.desc]", + "Cannot read descriptor file: [file:/nonexist.desc]", ex.getMessage() ); } From 94c99e00cd20cd2e0e6bfdb09df93193dc1f6d2c Mon Sep 17 00:00:00 2001 From: Hiroshi Fukada Date: Fri, 21 Nov 2025 13:56:04 -0500 Subject: [PATCH 2/2] fix: typo and refactor with context --- .../FileBasedProtobufBytesDecoder.java | 19 ++++++++++++------- .../FileBasedProtobufBytesDecoderTest.java | 4 ++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoder.java b/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoder.java index bbd394acfa09..1f5b19ab0b6c 100644 --- a/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoder.java +++ b/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoder.java @@ -59,6 +59,7 @@ public String getDescriptorFilePath() protected DescriptorProtos.FileDescriptorSet loadFileDescriptorSet() { InputStream fin; + DescriptorProtos.FileDescriptorSet descriptorSet; try { fin = this.getClass().getClassLoader().getResourceAsStream(descriptorFilePath); if (fin == null) { @@ -73,15 +74,19 @@ protected DescriptorProtos.FileDescriptorSet loadFileDescriptorSet() "Descriptor not found in class path or malformed URL: [%s]", descriptorFilePath ); } - try { - fin = url.openConnection().getInputStream(); - } - catch (IOException e) { - throw new ParseException(url.toString(), e, "Cannot read descriptor file: [%s]", url); + try (InputStream urlIn = url.openConnection().getInputStream()) { + if (urlIn == null) { + throw new ParseException( + descriptorFilePath, + "Descriptor not found at URL: [%s]", descriptorFilePath + ); + } + descriptorSet = DescriptorProtos.FileDescriptorSet.parseFrom(urlIn); } + } else { + descriptorSet = DescriptorProtos.FileDescriptorSet.parseFrom(fin); } - final var descriptorSet = DescriptorProtos.FileDescriptorSet.parseFrom(fin); if (descriptorSet.getFileCount() == 0) { throw new ParseException(null, "No file descriptors found in the descriptor set"); } @@ -89,7 +94,7 @@ protected DescriptorProtos.FileDescriptorSet loadFileDescriptorSet() return descriptorSet; } catch (IOException e) { - throw new ParseException(descriptorFilePath, e, "Failed to initialize descriptor"); + throw new ParseException(descriptorFilePath, e, "Failed to initialize descriptor at [%s]", descriptorFilePath); } } diff --git a/extensions-core/protobuf-extensions/src/test/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoderTest.java b/extensions-core/protobuf-extensions/src/test/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoderTest.java index 15f32394f150..1e9b3fb9c88a 100644 --- a/extensions-core/protobuf-extensions/src/test/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoderTest.java +++ b/extensions-core/protobuf-extensions/src/test/java/org/apache/druid/data/input/protobuf/FileBasedProtobufBytesDecoderTest.java @@ -70,7 +70,7 @@ public void testMoreComplexProtoFile() } @Test - public void tesDescriptorUrl() + public void testDescriptorUrl() { File descFile = new File("src/test/resources/proto_test_event.desc"); String path = descFile.getAbsoluteFile().toString(); @@ -134,7 +134,7 @@ public void testMalformedDescriptorUrl() ); assertEquals( - "Cannot read descriptor file: [file:/nonexist.desc]", + "Failed to initialize descriptor at [file:/nonexist.desc]", ex.getMessage() ); }