This is an automated email from the ASF dual-hosted git repository.
chia7712 pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git
The following commit(s) were added to refs/heads/trunk by this push:
new 494a2b9e244 KAFKA-20076 Fix wrong (uppercase) PluginType JSON
serialization (#21318)
494a2b9e244 is described below
commit 494a2b9e244513c50b1997f24a9f97c961fe4da5
Author: Paolo Patierno <[email protected]>
AuthorDate: Sun Jan 18 17:19:31 2026 +0100
KAFKA-20076 Fix wrong (uppercase) PluginType JSON serialization (#21318)
As described in the corresponding JIRA
[KAFKA-20076](https://issues.apache.org/jira/browse/KAFKA-20076), by
changing the `PluginInfo` from being a class to be a record, the
corresponding JSON serialization of the `type` field from `PluginType`
enum is now wrong: uppercase and not lowercase anymore. This PR fixes
the issue by annotating the `PluginType.toString` with `@JsonValue` so
it's used for serializer/deserialize the `type` field as before.
Reviewers: Christo Lolov <[email protected]>, Chia-Ping Tsai
<[email protected]>
---
.../connect/runtime/isolation/PluginType.java | 3 ++
.../runtime/rest/entities/PluginInfoTest.java | 36 ++++++++++++++++++++++
.../resources/ConnectorPluginsResourceTest.java | 16 ++++++++++
3 files changed, 55 insertions(+)
diff --git
a/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/isolation/PluginType.java
b/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/isolation/PluginType.java
index 0f26e84a0bb..68e3cac36bd 100644
---
a/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/isolation/PluginType.java
+++
b/connect/runtime/src/main/java/org/apache/kafka/connect/runtime/isolation/PluginType.java
@@ -26,6 +26,8 @@ import org.apache.kafka.connect.storage.HeaderConverter;
import org.apache.kafka.connect.transforms.Transformation;
import org.apache.kafka.connect.transforms.predicates.Predicate;
+import com.fasterxml.jackson.annotation.JsonValue;
+
import java.util.Locale;
public enum PluginType {
@@ -54,6 +56,7 @@ public enum PluginType {
}
@Override
+ @JsonValue
public String toString() {
return super.toString().toLowerCase(Locale.ROOT);
}
diff --git
a/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/entities/PluginInfoTest.java
b/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/entities/PluginInfoTest.java
index c2966f9346b..7e41789b541 100644
---
a/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/entities/PluginInfoTest.java
+++
b/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/entities/PluginInfoTest.java
@@ -17,9 +17,15 @@
package org.apache.kafka.connect.runtime.rest.entities;
import org.apache.kafka.connect.runtime.isolation.PluginDesc;
+import org.apache.kafka.connect.runtime.isolation.PluginType;
+import org.apache.kafka.connect.tools.MockSinkConnector;
+import org.apache.kafka.connect.tools.MockSourceConnector;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -35,4 +41,34 @@ public class PluginInfoTest {
assertFalse(filter.equals(null));
assertTrue(filter.equals(PluginDesc.UNDEFINED_VERSION));
}
+
+ @Test
+ public void testPluginInfoJsonSerialization() throws Exception {
+ ClassLoader classLoader = PluginInfoTest.class.getClassLoader();
+ PluginInfo sinkInfo = new PluginInfo(
+ new PluginDesc<>(MockSinkConnector.class, "1.0.0",
PluginType.SINK, classLoader)
+ );
+ PluginInfo sourceInfo = new PluginInfo(
+ new PluginDesc<>(MockSourceConnector.class, "2.0.0",
PluginType.SOURCE, classLoader)
+ );
+
+ final ObjectMapper objectMapper = new ObjectMapper();
+
+ // Serialize to JSON
+ String serializedSink = objectMapper.writeValueAsString(sinkInfo);
+ String serializedSource = objectMapper.writeValueAsString(sourceInfo);
+
+ // Verify type field is lowercase in JSON
+ assertTrue(serializedSink.contains("\"type\":\"sink\""),
+ "Expected type to be lowercase 'sink' but got: " + serializedSink);
+ assertTrue(serializedSource.contains("\"type\":\"source\""),
+ "Expected type to be lowercase 'source' but got: " +
serializedSource);
+
+ // Deserialize back and verify
+ PluginInfo deserializedSink = objectMapper.readValue(serializedSink,
PluginInfo.class);
+ PluginInfo deserializedSource =
objectMapper.readValue(serializedSource, PluginInfo.class);
+
+ assertEquals(PluginType.SINK, deserializedSink.type());
+ assertEquals(PluginType.SOURCE, deserializedSource.type());
+ }
}
diff --git
a/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/resources/ConnectorPluginsResourceTest.java
b/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/resources/ConnectorPluginsResourceTest.java
index d510c3c475d..19c9c9e006f 100644
---
a/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/resources/ConnectorPluginsResourceTest.java
+++
b/connect/runtime/src/test/java/org/apache/kafka/connect/runtime/rest/resources/ConnectorPluginsResourceTest.java
@@ -400,6 +400,22 @@ public class ConnectorPluginsResourceTest {
);
}
+ @Test
+ public void testConnectorPluginsEndpointReturnsLowercaseTypeInJson()
throws Exception {
+ // Call the actual endpoint method
+ List<PluginInfo> plugins =
connectorPluginsResource.listConnectorPlugins(true);
+
+ // Serialize the response to JSON (simulating what the REST API does)
+ final ObjectMapper objectMapper = new ObjectMapper();
+ String json = objectMapper.writeValueAsString(plugins);
+
+ // Verify the JSON contains lowercase type fields
+ assertTrue(json.contains("\"type\":\"sink\""),
+ "Expected JSON to contain '\"type\":\"sink\"' but got: " + json);
+ assertTrue(json.contains("\"type\":\"source\""),
+ "Expected JSON to contain '\"type\":\"source\"' but got: " + json);
+ }
+
@Test
public void testListAllPlugins() {
List<PluginInfo> expectedConnectorPlugins = Stream.of(