Browse Source

[Connector API] Bugfix: support list type in filtering advanced snippet value (#105633) (#105645)

Jedr Blaszyk 1 year ago
parent
commit
0527fcd701

+ 6 - 0
docs/changelog/105633.yaml

@@ -0,0 +1,6 @@
+pr: 105633
+summary: "[Connector API] Bugfix: support list type in filtering advenced snippet\
+  \ value"
+area: Application
+type: bug
+issues: []

+ 11 - 2
x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/332_connector_update_filtering.yml

@@ -23,7 +23,10 @@ setup:
                 advanced_snippet:
                   created_at: "2023-05-25T12:30:00.000Z"
                   updated_at: "2023-05-25T12:30:00.000Z"
-                  value: {}
+                  value:
+                    - tables:
+                        - some_table
+                      query: 'SELECT id, st_geohash(coordinates) FROM my_db.some_table;'
                 rules:
                   - created_at: "2023-05-25T12:30:00.000Z"
                     field: _
@@ -41,7 +44,13 @@ setup:
                 advanced_snippet:
                   created_at: "2023-05-25T12:30:00.000Z"
                   updated_at: "2023-05-25T12:30:00.000Z"
-                  value: {}
+                  value:
+                    - tables:
+                        - some_table
+                      query: 'SELECT id, st_geohash(coordinates) FROM my_db.some_table;'
+                    - tables:
+                        - another_table
+                      query: 'SELECT id, st_geohash(coordinates) FROM my_db.another_table;'
                 rules:
                   - created_at: "2023-05-25T12:30:00.000Z"
                     field: _

+ 16 - 13
x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/filtering/FilteringAdvancedSnippet.java

@@ -15,12 +15,12 @@ import org.elasticsearch.xcontent.ObjectParser;
 import org.elasticsearch.xcontent.ParseField;
 import org.elasticsearch.xcontent.ToXContentObject;
 import org.elasticsearch.xcontent.XContentBuilder;
+import org.elasticsearch.xcontent.XContentParseException;
 import org.elasticsearch.xcontent.XContentParser;
 import org.elasticsearch.xpack.application.connector.ConnectorUtils;
 
 import java.io.IOException;
 import java.time.Instant;
-import java.util.Map;
 import java.util.Objects;
 
 import static org.elasticsearch.xcontent.ConstructingObjectParser.constructorArg;
@@ -34,18 +34,14 @@ public class FilteringAdvancedSnippet implements Writeable, ToXContentObject {
 
     private final Instant advancedSnippetCreatedAt;
     private final Instant advancedSnippetUpdatedAt;
-    private final Map<String, Object> advancedSnippetValue;
+    private final Object advancedSnippetValue;
 
     /**
      * @param advancedSnippetCreatedAt The creation timestamp of the advanced snippet.
      * @param advancedSnippetUpdatedAt The update timestamp of the advanced snippet.
      * @param advancedSnippetValue     The value of the advanced snippet.
      */
-    private FilteringAdvancedSnippet(
-        Instant advancedSnippetCreatedAt,
-        Instant advancedSnippetUpdatedAt,
-        Map<String, Object> advancedSnippetValue
-    ) {
+    private FilteringAdvancedSnippet(Instant advancedSnippetCreatedAt, Instant advancedSnippetUpdatedAt, Object advancedSnippetValue) {
         this.advancedSnippetCreatedAt = advancedSnippetCreatedAt;
         this.advancedSnippetUpdatedAt = advancedSnippetUpdatedAt;
         this.advancedSnippetValue = advancedSnippetValue;
@@ -54,7 +50,7 @@ public class FilteringAdvancedSnippet implements Writeable, ToXContentObject {
     public FilteringAdvancedSnippet(StreamInput in) throws IOException {
         this.advancedSnippetCreatedAt = in.readInstant();
         this.advancedSnippetUpdatedAt = in.readInstant();
-        this.advancedSnippetValue = in.readMap(StreamInput::readString, StreamInput::readGenericValue);
+        this.advancedSnippetValue = in.readGenericValue();
     }
 
     private static final ParseField CREATED_AT_FIELD = new ParseField("created_at");
@@ -67,7 +63,7 @@ public class FilteringAdvancedSnippet implements Writeable, ToXContentObject {
         true,
         args -> new Builder().setAdvancedSnippetCreatedAt((Instant) args[0])
             .setAdvancedSnippetUpdatedAt((Instant) args[1])
-            .setAdvancedSnippetValue((Map<String, Object>) args[2])
+            .setAdvancedSnippetValue(args[2])
             .build()
     );
 
@@ -84,7 +80,14 @@ public class FilteringAdvancedSnippet implements Writeable, ToXContentObject {
             UPDATED_AT_FIELD,
             ObjectParser.ValueType.STRING
         );
-        PARSER.declareField(constructorArg(), (p, c) -> p.map(), VALUE_FIELD, ObjectParser.ValueType.OBJECT);
+        PARSER.declareField(constructorArg(), (p, c) -> {
+            if (p.currentToken() == XContentParser.Token.START_ARRAY) {
+                return p.list();
+            } else if (p.currentToken() == XContentParser.Token.START_OBJECT) {
+                return p.map();
+            }
+            throw new XContentParseException("Unsupported token [" + p.currentToken() + "]. Expected an array or an object.");
+        }, VALUE_FIELD, ObjectParser.ValueType.OBJECT_ARRAY);
     }
 
     @Override
@@ -107,7 +110,7 @@ public class FilteringAdvancedSnippet implements Writeable, ToXContentObject {
     public void writeTo(StreamOutput out) throws IOException {
         out.writeInstant(advancedSnippetCreatedAt);
         out.writeInstant(advancedSnippetUpdatedAt);
-        out.writeMap(advancedSnippetValue, StreamOutput::writeString, StreamOutput::writeGenericValue);
+        out.writeGenericValue(advancedSnippetValue);
     }
 
     @Override
@@ -129,7 +132,7 @@ public class FilteringAdvancedSnippet implements Writeable, ToXContentObject {
 
         private Instant advancedSnippetCreatedAt;
         private Instant advancedSnippetUpdatedAt;
-        private Map<String, Object> advancedSnippetValue;
+        private Object advancedSnippetValue;
 
         public Builder setAdvancedSnippetCreatedAt(Instant advancedSnippetCreatedAt) {
             this.advancedSnippetCreatedAt = advancedSnippetCreatedAt;
@@ -141,7 +144,7 @@ public class FilteringAdvancedSnippet implements Writeable, ToXContentObject {
             return this;
         }
 
-        public Builder setAdvancedSnippetValue(Map<String, Object> advancedSnippetValue) {
+        public Builder setAdvancedSnippetValue(Object advancedSnippetValue) {
             this.advancedSnippetValue = advancedSnippetValue;
             return this;
         }

+ 67 - 0
x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorFilteringTests.java

@@ -110,6 +110,73 @@ public class ConnectorFilteringTests extends ESTestCase {
 
     }
 
+    public void testToXContent_WithAdvancedSnippetPopulated() throws IOException {
+        String content = XContentHelper.stripWhitespace("""
+                {
+                    "active": {
+                        "advanced_snippet": {
+                            "created_at": "2023-11-09T15:13:08.231Z",
+                            "updated_at": "2023-11-09T15:13:08.231Z",
+                            "value": [
+                               {"service": "Incident", "query": "user_nameSTARTSWITHa"},
+                               {"service": "Incident", "query": "user_nameSTARTSWITHj"}
+                            ]
+                        },
+                        "rules": [
+                            {
+                                "created_at": "2023-11-09T15:13:08.231Z",
+                                "field": "_",
+                                "id": "DEFAULT",
+                                "order": 0,
+                                "policy": "include",
+                                "rule": "regex",
+                                "updated_at": "2023-11-09T15:13:08.231Z",
+                                "value": ".*"
+                            }
+                        ],
+                        "validation": {
+                            "errors": [],
+                            "state": "valid"
+                        }
+                    },
+                    "domain": "DEFAULT",
+                    "draft": {
+                        "advanced_snippet": {
+                            "created_at": "2023-11-09T15:13:08.231Z",
+                            "updated_at": "2023-11-09T15:13:08.231Z",
+                            "value": {}
+                        },
+                        "rules": [
+                            {
+                                "created_at": "2023-11-09T15:13:08.231Z",
+                                "field": "_",
+                                "id": "DEFAULT",
+                                "order": 0,
+                                "policy": "include",
+                                "rule": "regex",
+                                "updated_at": "2023-11-09T15:13:08.231Z",
+                                "value": ".*"
+                            }
+                        ],
+                        "validation": {
+                            "errors": [],
+                            "state": "valid"
+                        }
+                    }
+                }
+            """);
+
+        ConnectorFiltering filtering = ConnectorFiltering.fromXContentBytes(new BytesArray(content), XContentType.JSON);
+        boolean humanReadable = true;
+        BytesReference originalBytes = toShuffledXContent(filtering, XContentType.JSON, ToXContent.EMPTY_PARAMS, humanReadable);
+        ConnectorFiltering parsed;
+        try (XContentParser parser = createParser(XContentType.JSON.xContent(), originalBytes)) {
+            parsed = ConnectorFiltering.fromXContent(parser);
+        }
+        assertToXContentEquivalent(originalBytes, toXContent(parsed, XContentType.JSON, humanReadable), XContentType.JSON);
+
+    }
+
     private void assertTransportSerialization(ConnectorFiltering testInstance) throws IOException {
         ConnectorFiltering deserializedInstance = copyInstance(testInstance);
         assertNotSame(testInstance, deserializedInstance);

+ 16 - 2
x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTests.java

@@ -147,7 +147,14 @@ public class ConnectorTests extends ESTestCase {
                         "advanced_snippet":{
                            "created_at":"2023-11-09T15:13:08.231Z",
                            "updated_at":"2023-11-09T15:13:08.231Z",
-                           "value":{}
+                           "value":[
+                             {
+                                 "tables": [
+                                     "some_table"
+                                 ],
+                                 "query": "SELECT id, st_geohash(coordinates) FROM my_db.some_table;"
+                             }
+                           ]
                         },
                         "rules":[
                            {
@@ -171,7 +178,14 @@ public class ConnectorTests extends ESTestCase {
                         "advanced_snippet":{
                            "created_at":"2023-11-09T15:13:08.231Z",
                            "updated_at":"2023-11-09T15:13:08.231Z",
-                           "value":{}
+                           "value":[
+                             {
+                                 "tables": [
+                                     "some_table"
+                                 ],
+                                 "query": "SELECT id, st_geohash(coordinates) FROM my_db.some_table;"
+                             }
+                           ]
                         },
                         "rules":[
                            {