Browse Source

[Transform] fixes http status code when bad scripts are provided (#56117)

Transforms should propagate up the search execution exception if one is returned when it does the test query. 

this allows transforms to return a `4xx` when the aggs are malformed but parseable. 

closes https://github.com/elastic/elasticsearch/issues/55994
Benjamin Trent 5 years ago
parent
commit
7104cd3a02

+ 33 - 0
x-pack/plugin/src/test/resources/rest-api-spec/test/transform/transforms_crud.yml

@@ -637,3 +637,36 @@ setup:
             "description": "yaml test transform on airline-data"
           }
   - match: {acknowledged: true}
+---
+"Test put transform with bad query due to script compilation":
+  - do:
+      catch: bad_request
+      transform.put_transform:
+        transform_id: "airline-transform-with-bad-scripts"
+        body: >
+          {
+            "source": { "index": "airline-data" },
+            "dest": { "index": "airline-data-by-airline-with-bad-scripts" },
+            "pivot": {
+              "group_by": { "airline": {"terms": {"field": "airline"}}},
+              "aggs": {
+                "sumState": {
+                  "scripted_metric": {
+                    "combine_script": {
+                      "source": "foobar boom"
+                    },
+                    "init_script": {
+                      "source": "state.state = []"
+                    },
+                    "map_script": {
+                      "source": "state.state.add(1)"
+                    },
+                    "reduce_script": {
+                      "source": "long sum = 0; for (s in states) { sum += s } return sum"
+                    }
+                  }
+                }
+              }
+            },
+            "description": "yaml test transform on airline-data"
+          }

+ 11 - 1
x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/transforms/pivot/Pivot.java

@@ -9,6 +9,7 @@ package org.elasticsearch.xpack.transform.transforms.pivot;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.ElasticsearchStatusException;
 import org.elasticsearch.action.ActionListener;
 import org.elasticsearch.action.search.SearchAction;
@@ -28,6 +29,7 @@ import org.elasticsearch.search.aggregations.PipelineAggregationBuilder;
 import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregation;
 import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregationBuilder;
 import org.elasticsearch.search.builder.SearchSourceBuilder;
+import org.elasticsearch.xpack.core.ml.utils.ExceptionsHelper;
 import org.elasticsearch.xpack.core.transform.TransformMessages;
 import org.elasticsearch.xpack.core.transform.transforms.SourceConfig;
 import org.elasticsearch.xpack.core.transform.transforms.TransformIndexerStats;
@@ -99,7 +101,15 @@ public class Pivot {
                 return;
             }
             listener.onResponse(true);
-        }, e -> listener.onFailure(new ElasticsearchStatusException("Failed to test query", RestStatus.SERVICE_UNAVAILABLE, e))));
+        }, e -> {
+            Throwable unwrapped = ExceptionsHelper.unwrapCause(e);
+            RestStatus status = unwrapped instanceof ElasticsearchException ?
+                ((ElasticsearchException)unwrapped).status() :
+                RestStatus.SERVICE_UNAVAILABLE;
+            listener.onFailure(new ElasticsearchStatusException("Failed to test query",
+                status,
+                unwrapped));
+        }));
     }
 
     public void deduceMappings(Client client, SourceConfig sourceConfig, final ActionListener<Map<String, String>> listener) {