From 2b5e99432bb7ebec92cfb19087a0b9e8fab6c562 Mon Sep 17 00:00:00 2001 From: Nagendra Mohan Date: Tue, 11 Aug 2026 10:33:51 +0530 Subject: [PATCH] fix: Prevent InvalidTypeIdException when Prometheus metric has 'type' label Add @JsonTypeInfo(use = JsonTypeInfo.Id.NONE) on PrometheusResult to override the parent DataSourceResult interface's polymorphic type handling. This prevents Jackson from interpreting a metric label named 'type' as the polymorphic type discriminator, which caused InvalidTypeIdException during deserialization. The type dispatch is already handled explicitly via switch statement in ExecuteDirectQueryActionResponse, so polymorphic type annotations are not needed on the concrete class. Resolves opensearch-project#5684 Signed-off-by: Nagendra Mohan --- .../model/datasource/PrometheusResult.java | 2 ++ .../ExecuteDirectQueryActionResponseTest.java | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/datasource/PrometheusResult.java b/direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/datasource/PrometheusResult.java index 09ff30598d8..ab8c67c6a32 100644 --- a/direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/datasource/PrometheusResult.java +++ b/direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/datasource/PrometheusResult.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import java.util.List; import java.util.Map; @@ -22,6 +23,7 @@ @Getter @Setter @JsonTypeName("prometheus") +@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) @JsonIgnoreProperties(ignoreUnknown = true) public class PrometheusResult implements DataSourceResult { diff --git a/direct-query/src/test/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponseTest.java b/direct-query/src/test/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponseTest.java index 9f4ab5fa9e1..e19bc1a143e 100644 --- a/direct-query/src/test/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponseTest.java +++ b/direct-query/src/test/java/org/opensearch/sql/directquery/transport/model/ExecuteDirectQueryActionResponseTest.java @@ -287,4 +287,30 @@ public void testConstructorWithPrometheusError() throws IOException { PrometheusResult result = (PrometheusResult) response.getResults().get(dataSourceName); assertNotNull(result); } + + @Test + public void testPrometheusResultWithTypeLabelInMetric() throws IOException { + // Regression test: metrics containing a label named "type" should not cause + // InvalidTypeIdException during deserialization (GitHub #5684) + String queryId = "query-type-label"; + String sessionId = "session-type-label"; + String rawResult = + "{\"resultType\":\"vector\",\"result\":[{\"metric\":" + + "{\"__name__\":\"cpu_usage\",\"type\":\"gauge\",\"instance\":\"localhost:9090\"}," + + "\"value\":[1625000000,\"0.5\"]}]}"; + String dataSourceName = "prom-with-type-label"; + String dataSourceType = "prometheus"; + + ExecuteDirectQueryActionResponse response = + new ExecuteDirectQueryActionResponse( + queryId, rawResult, sessionId, dataSourceName, dataSourceType); + + assertEquals(queryId, response.getQueryId()); + assertEquals(1, response.getResults().size()); + assertInstanceOf(PrometheusResult.class, response.getResults().get(dataSourceName)); + PrometheusResult result = (PrometheusResult) response.getResults().get(dataSourceName); + assertNotNull(result.getResult()); + assertEquals(1, result.getResult().size()); + assertEquals("gauge", result.getResult().get(0).getMetric().get("type")); + } } \ No newline at end of file