This is an automated email from the ASF dual-hosted git repository.

chia7712 pushed a commit to branch 4.2
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/4.2 by this push:
     new ce5207afe8e KAFKA-20076 Fix wrong (uppercase) PluginType JSON 
serialization (#21318)
ce5207afe8e is described below

commit ce5207afe8eefbe34f683c2e3e79c5dbba16a679
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(

Reply via email to