From adc17b34c919ff65f21815216ef7633859ec5e59 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Tue, 12 Mar 2019 10:27:38 +0000 Subject: [PATCH 1/7] Stop DataFrame --- .../elasticsearch/client/DataFrameClient.java | 41 +++++++++ .../client/DataFrameRequestConverters.java | 19 ++++ .../StopDataFrameTransformRequest.java | 91 +++++++++++++++++++ .../DataFrameRequestConvertersTests.java | 35 +++++++ .../client/DataFrameTransformIT.java | 25 +++++ .../StopDataFrameTransformRequestTests.java | 42 +++++++++ .../DataFrameTransformDocumentationIT.java | 8 ++ .../dataframe/stop_data_frame.asciidoc | 39 ++++++++ 8 files changed, 300 insertions(+) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequest.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequestTests.java create mode 100644 docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java index 59b89bc50b0f2..fc70d62751828 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java @@ -23,6 +23,7 @@ import org.elasticsearch.client.core.AcknowledgedResponse; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import java.io.IOException; import java.util.Collections; @@ -115,4 +116,44 @@ public void deleteDataFrameTransformAsync(DeleteDataFrameTransformRequest reques listener, Collections.emptySet()); } + + /** + * Stop a data frame transform + *

+ * For additional info + * see Stop Data Frame transform documentation + * + * @param request The stop data frame transform request + * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return An AcknowledgedResponse object indicating request success + * @throws IOException when there is a serialization issue sending the request or receiving the response + */ + public AcknowledgedResponse stopDataFrameTransform(StopDataFrameTransformRequest request, RequestOptions options) + throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, + DataFrameRequestConverters::stopDataFrameTransform, + options, + AcknowledgedResponse::fromXContent, + Collections.emptySet()); + } + + /** + * Stop a data frame transform asynchronously and notifies listener on completion + *

+ * For additional info + * see Stop Data Frame transform documentation + * + * @param request The stop data frame transform request + * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @param listener Listener to be notified upon request completion + */ + public void stopDataFrameTransformAsync(StopDataFrameTransformRequest request, RequestOptions options, + ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(request, + DataFrameRequestConverters::stopDataFrameTransform, + options, + AcknowledgedResponse::fromXContent, + listener, + Collections.emptySet()); + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameRequestConverters.java index e2aa24a4a1de2..a0ddecb46a81d 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameRequestConverters.java @@ -20,9 +20,11 @@ package org.elasticsearch.client; import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import java.io.IOException; @@ -50,4 +52,21 @@ static Request deleteDataFrameTransform(DeleteDataFrameTransformRequest request) .build(); return new Request(HttpDelete.METHOD_NAME, endpoint); } + + static Request stopDataFrameTransform(StopDataFrameTransformRequest stopRequest) { + String endpoint = new RequestConverters.EndpointBuilder() + .addPathPartAsIs("_data_frame", "transforms") + .addPathPart(stopRequest.getId()) + .addPathPartAsIs("_stop") + .build(); + Request request = new Request(HttpPost.METHOD_NAME, endpoint); + RequestConverters.Params params = new RequestConverters.Params(request); + if (stopRequest.getWaitForCompletion() != null) { + params.withWaitForCompletion(stopRequest.getWaitForCompletion()); + } + if (stopRequest.getTimeout() != null) { + params.withTimeout(stopRequest.getTimeout()); + } + return request; + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequest.java new file mode 100644 index 0000000000000..ffa6b70865db8 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequest.java @@ -0,0 +1,91 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.dataframe; + +import org.elasticsearch.client.Validatable; +import org.elasticsearch.client.ValidationException; +import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.unit.TimeValue; + +import java.util.Objects; +import java.util.Optional; + +public class StopDataFrameTransformRequest implements Validatable { + + private final String id; + private final Boolean waitForCompletion; + private final TimeValue timeout; + + public StopDataFrameTransformRequest(String id) { + this.id = id; + waitForCompletion = null; + timeout = null; + } + + public StopDataFrameTransformRequest(String id, @Nullable Boolean waitForCompletion, @Nullable TimeValue timeout) { + this.id = id; + this.waitForCompletion = waitForCompletion; + this.timeout = timeout; + } + + public String getId() { + return id; + } + + public Boolean getWaitForCompletion() { + return waitForCompletion; + } + + public TimeValue getTimeout() { + return timeout; + } + + @Override + public Optional validate() { + if (id == null) { + ValidationException validationException = new ValidationException(); + validationException.addValidationError("data frame transform id must not be null"); + return Optional.of(validationException); + } else { + return Optional.empty(); + } + } + + @Override + public int hashCode() { + return Objects.hash(id, waitForCompletion, timeout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + StopDataFrameTransformRequest other = (StopDataFrameTransformRequest) obj; + return Objects.equals(this.id, other.id) + && Objects.equals(this.waitForCompletion, other.waitForCompletion) + && Objects.equals(this.timeout, other.timeout); + } + +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameRequestConvertersTests.java index 1c7046694c706..256afb1f4eb6c 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameRequestConvertersTests.java @@ -20,12 +20,15 @@ package org.elasticsearch.client; import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfig; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfigTests; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; @@ -66,4 +69,36 @@ public void testDeleteDataFrameTransform() { assertEquals(HttpDelete.METHOD_NAME, request.getMethod()); assertThat(request.getEndpoint(), equalTo("/_data_frame/transforms/foo")); } + + public void testStopDataFrameTransform() { + String id = randomAlphaOfLength(10); + Boolean waitForCompletion = null; + if (randomBoolean()) { + waitForCompletion = randomBoolean(); + } + TimeValue timeValue = null; + if (randomBoolean()) { + timeValue = TimeValue.parseTimeValue(randomTimeValue(), "timeout"); + } + StopDataFrameTransformRequest stopRequest = new StopDataFrameTransformRequest(id, waitForCompletion, timeValue); + + + Request request = DataFrameRequestConverters.stopDataFrameTransform(stopRequest); + assertEquals(HttpPost.METHOD_NAME, request.getMethod()); + assertThat(request.getEndpoint(), equalTo("/_data_frame/transforms/" + stopRequest.getId() + "/_stop")); + + if (waitForCompletion != null) { + assertTrue(request.getParameters().containsKey("wait_for_completion")); + assertEquals(stopRequest.getWaitForCompletion(), Boolean.parseBoolean(request.getParameters().get("wait_for_completion"))); + } else { + assertFalse(request.getParameters().containsKey("wait_for_completion")); + } + + if (timeValue != null) { + assertTrue(request.getParameters().containsKey("timeout")); + assertEquals(stopRequest.getTimeout(), TimeValue.parseTimeValue(request.getParameters().get("timeout"), "timeout")); + } else { + assertFalse(request.getParameters().containsKey("timeout")); + } + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java index c3055ba819836..4e342e7cc3f48 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java @@ -23,6 +23,7 @@ import org.elasticsearch.client.core.AcknowledgedResponse; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfig; import org.elasticsearch.client.dataframe.transforms.QueryConfig; import org.elasticsearch.client.dataframe.transforms.pivot.AggregationConfig; @@ -96,5 +97,29 @@ public void testCreateDelete() throws IOException { client::deleteDataFrameTransformAsync)); assertThat(deleteError.getMessage(), containsString("Transform with id [test-crud] could not be found")); } + + public void testStop() throws IOException { + String sourceIndex = "transform-source"; + createIndex(sourceIndex); + + QueryConfig queryConfig = new QueryConfig(new MatchAllQueryBuilder()); + GroupConfig groupConfig = new GroupConfig(Collections.singletonMap("reviewer", new TermsGroupSource("user_id"))); + AggregatorFactories.Builder aggBuilder = new AggregatorFactories.Builder(); + aggBuilder.addAggregator(AggregationBuilders.avg("avg_rating").field("stars")); + AggregationConfig aggConfig = new AggregationConfig(aggBuilder); + PivotConfig pivotConfig = new PivotConfig(groupConfig, aggConfig); + + String id = "test-stop"; + DataFrameTransformConfig transform = new DataFrameTransformConfig(id, sourceIndex, "pivot-dest", queryConfig, pivotConfig); + + DataFrameClient client = highLevelClient().dataFrame(); + AcknowledgedResponse ack = execute(new PutDataFrameTransformRequest(transform), client::putDataFrameTransform, + client::putDataFrameTransformAsync); + assertTrue(ack.isAcknowledged()); + + StopDataFrameTransformRequest stopRequest = new StopDataFrameTransformRequest(id); + execute(stopRequest, client::stopDataFrameTransform, client::stopDataFrameTransformAsync); + assertTrue(ack.isAcknowledged()); + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequestTests.java new file mode 100644 index 0000000000000..56b22d57c07e9 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequestTests.java @@ -0,0 +1,42 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.dataframe; + +import org.elasticsearch.client.ValidationException; +import org.elasticsearch.test.ESTestCase; + +import java.util.Optional; + +import static org.hamcrest.Matchers.containsString; + +public class StopDataFrameTransformRequestTests extends ESTestCase { + public void testValidate_givenNullId() { + StopDataFrameTransformRequest request = new StopDataFrameTransformRequest(null); + Optional validate = request.validate(); + assertTrue(validate.isPresent()); + assertThat(validate.get().getMessage(), containsString("data frame transform id must not be null")); + } + + public void testValidate_givenValid() { + StopDataFrameTransformRequest request = new StopDataFrameTransformRequest("foo"); + Optional validate = request.validate(); + assertFalse(validate.isPresent()); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java index 270f9c9da9db6..c578f5acb6f85 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java @@ -27,6 +27,7 @@ import org.elasticsearch.client.core.AcknowledgedResponse; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfig; import org.elasticsearch.client.dataframe.transforms.QueryConfig; import org.elasticsearch.client.dataframe.transforms.pivot.AggregationConfig; @@ -150,6 +151,13 @@ public void onFailure(Exception e) { assertTrue(latch.await(30L, TimeUnit.SECONDS)); } + + // Stop the Data Frame + // tag::stop-data-frame-transform-request + StopDataFrameTransformRequest stopRequest = + new StopDataFrameTransformRequest("reviewer-avg-rating"); + // end::stop-data-frame-transform-request + } public void testDeleteDataFrameTransform() throws IOException, InterruptedException { diff --git a/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc b/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc new file mode 100644 index 0000000000000..03767a8fa24f5 --- /dev/null +++ b/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc @@ -0,0 +1,39 @@ +-- +:api: stop-data-frame-transform +:request: StopDataFrameTransformRequest +:response: AcknowledgedResponse +-- +[id="{upid}-{api}"] +=== Stop Data Frame Transform API + +Stop a started {dataframe-job}. +It accepts a +{request}+ object and responds with a +{response}+ object. + +[id="{upid}-{api}-request"] +==== Stop Data Frame Request + +A +{request}+ object requires a non-null `id`. + +["source","java",subs="attributes,callouts,macros"] +--------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request] +--------------------------------------------------- +<1> Constructing a new request referencing an existing {dataframe-job} + +==== Optional Arguments + +The following arguments are optional. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request-options] +-------------------------------------------------- +<1> If true wait for the data frame task to stop before responding +<2> Controls the amount of time to wait until the {dataframe-job} stops. +The default value is 30 seconds. + +include::../execution.asciidoc[] + +==== Response + +The returned +{response}+ object acknowledges the {dataframe-job} has stopped. \ No newline at end of file From 9eebb36cc7206eaff83265c5b7559523dd767b64 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Tue, 12 Mar 2019 16:05:39 +0000 Subject: [PATCH 2/7] Add base tasks response parsing --- .../core/AcknowledgedTasksResponse.java | 97 ++++++++++++ .../core/AcknowledgedTasksResponseTests.java | 145 ++++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/core/AcknowledgedTasksResponse.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/core/AcknowledgedTasksResponseTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/core/AcknowledgedTasksResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/AcknowledgedTasksResponse.java new file mode 100644 index 0000000000000..e69141fe50c06 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/AcknowledgedTasksResponse.java @@ -0,0 +1,97 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.core; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.TaskOperationFailure; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.TriFunction; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; + +public class AcknowledgedTasksResponse { + + protected static final ParseField TASK_FAILURES = new ParseField("task_failures"); + protected static final ParseField NODE_FAILURES = new ParseField("node_failures"); + + protected static ConstructingObjectParser generateParser( + String name, + TriFunction, List, T> ctor, + String ackFieldName) { + + ConstructingObjectParser parser = new ConstructingObjectParser<>(name, true, + args -> ctor.apply((boolean) args[0], (List) args[1], (List) args[2])); + parser.declareBoolean(constructorArg(), new ParseField(ackFieldName)); + parser.declareObjectArray(optionalConstructorArg(), (p, c) -> TaskOperationFailure.fromXContent(p), TASK_FAILURES); + parser.declareObjectArray(optionalConstructorArg(), (p, c) -> ElasticsearchException.fromXContent(p), NODE_FAILURES); + return parser; + } + + private boolean acknowledged; + private List taskFailures; + private List nodeFailures; + + AcknowledgedTasksResponse(boolean acknowledged, List taskFailures, + List nodeFailures) { + this.acknowledged = acknowledged; + this.taskFailures = taskFailures == null ? Collections.emptyList() : Collections.unmodifiableList(new ArrayList<>(taskFailures)); + this.nodeFailures = nodeFailures == null ? Collections.emptyList() : Collections.unmodifiableList(new ArrayList<>(nodeFailures)); + } + + boolean isAcknowledged() { + return acknowledged; + } + + public List getTaskFailures() { + return taskFailures; + } + + public List getNodeFailures() { + return nodeFailures; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + AcknowledgedTasksResponse other = (AcknowledgedTasksResponse) obj; + return acknowledged == other.acknowledged + && taskFailures.equals(other.taskFailures) + && nodeFailures.equals(other.nodeFailures); + } + + @Override + public int hashCode() { + return Objects.hash(acknowledged, taskFailures, nodeFailures); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/core/AcknowledgedTasksResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/core/AcknowledgedTasksResponseTests.java new file mode 100644 index 0000000000000..34a2ffa6830ee --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/core/AcknowledgedTasksResponseTests.java @@ -0,0 +1,145 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.core; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.TaskOperationFailure; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.BiPredicate; + +import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester; + +public class AcknowledgedTasksResponseTests extends ESTestCase { + + public void testFromXContent() throws IOException { + xContentTester(this::createParser, + this::createTestInstance, + AcknowledgedTasksResponseTests::toXContent, + AcknowledgedTasksResponseTests::fromXContent) + .assertEqualsConsumer(this::assertEqualInstances) + .assertToXContentEquivalence(false) + .supportsUnknownFields(false) + .test(); + } + + // Serialisation of TaskOperationFailure changes the error + // so use a custom compare method + private void assertEqualInstances(AcknowledgedTasksResponse expectedInstance, AcknowledgedTasksResponse actual) { + assertNotSame(expectedInstance, actual); + assertEquals(expectedInstance.isAcknowledged(), actual.isAcknowledged()); + + List expectedTaskFailures = expectedInstance.getTaskFailures(); + List actualTaskFailures = actual.getTaskFailures(); + + assertListEquals(expectedTaskFailures, actualTaskFailures, (a, b) -> + Objects.equals(a.getNodeId(), b.getNodeId()) + && Objects.equals(a.getTaskId(), b.getTaskId()) + && Objects.equals(a.getStatus(), b.getStatus()) + ); + + + List expectedExceptions = expectedInstance.getNodeFailures(); + List actualExceptions = actual.getNodeFailures(); + + assertListEquals(expectedExceptions, actualExceptions, (a, b) -> a != null && b != null); + } + + private void assertListEquals(List expected, List actual, BiPredicate comparator) { + if (expected == null) { + assertNull(actual); + return; + } else { + assertNotNull(actual); + } + + assertEquals(expected.size(), actual.size()); + for (int i=0; i taskFailures = null; + if (randomBoolean()) { + taskFailures = new ArrayList<>(); + int numTaskFailures = randomIntBetween(1, 4); + for (int i=0; i nodeFailures = null; + if (randomBoolean()) { + nodeFailures = new ArrayList<>(); + int numNodeFailures = randomIntBetween(1, 4); + for (int i=0; i taskFailures = response.getTaskFailures(); + if (taskFailures != null && taskFailures.isEmpty() == false) { + builder.startArray(AcknowledgedTasksResponse.TASK_FAILURES.getPreferredName()); + for (TaskOperationFailure failure : taskFailures) { + builder.startObject(); + failure.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + } + builder.endArray(); + } + + List nodeFailures = response.getNodeFailures(); + if (nodeFailures != null && nodeFailures.isEmpty() == false) { + builder.startArray(AcknowledgedTasksResponse.NODE_FAILURES.getPreferredName()); + for (ElasticsearchException failure : nodeFailures) { + builder.startObject(); + failure.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + } + builder.endArray(); + } + } + builder.endObject(); + } + +} + + From 1a63784791003403c21b5f8b3bab10dda2778214 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Thu, 14 Mar 2019 15:25:22 +0000 Subject: [PATCH 3/7] Add stop response --- .../elasticsearch/client/DataFrameClient.java | 9 ++-- .../core/AcknowledgedTasksResponse.java | 8 +-- .../StopDataFrameTransformResponse.java | 51 +++++++++++++++++++ .../client/DataFrameTransformIT.java | 8 ++- .../dataframe/stop_data_frame.asciidoc | 4 +- 5 files changed, 69 insertions(+), 11 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformResponse.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java index fc70d62751828..252c94e598d24 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java @@ -24,6 +24,7 @@ import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StopDataFrameTransformResponse; import java.io.IOException; import java.util.Collections; @@ -128,12 +129,12 @@ public void deleteDataFrameTransformAsync(DeleteDataFrameTransformRequest reques * @return An AcknowledgedResponse object indicating request success * @throws IOException when there is a serialization issue sending the request or receiving the response */ - public AcknowledgedResponse stopDataFrameTransform(StopDataFrameTransformRequest request, RequestOptions options) + public StopDataFrameTransformResponse stopDataFrameTransform(StopDataFrameTransformRequest request, RequestOptions options) throws IOException { return restHighLevelClient.performRequestAndParseEntity(request, DataFrameRequestConverters::stopDataFrameTransform, options, - AcknowledgedResponse::fromXContent, + StopDataFrameTransformResponse::fromXContent, Collections.emptySet()); } @@ -148,11 +149,11 @@ public AcknowledgedResponse stopDataFrameTransform(StopDataFrameTransformRequest * @param listener Listener to be notified upon request completion */ public void stopDataFrameTransformAsync(StopDataFrameTransformRequest request, RequestOptions options, - ActionListener listener) { + ActionListener listener) { restHighLevelClient.performRequestAsyncAndParseEntity(request, DataFrameRequestConverters::stopDataFrameTransform, options, - AcknowledgedResponse::fromXContent, + StopDataFrameTransformResponse::fromXContent, listener, Collections.emptySet()); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/core/AcknowledgedTasksResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/AcknowledgedTasksResponse.java index e69141fe50c06..b94c3454f8637 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/core/AcknowledgedTasksResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/core/AcknowledgedTasksResponse.java @@ -21,6 +21,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.TaskOperationFailure; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.TriFunction; import org.elasticsearch.common.xcontent.ConstructingObjectParser; @@ -38,6 +39,7 @@ public class AcknowledgedTasksResponse { protected static final ParseField TASK_FAILURES = new ParseField("task_failures"); protected static final ParseField NODE_FAILURES = new ParseField("node_failures"); + @SuppressWarnings("unchecked") protected static ConstructingObjectParser generateParser( String name, TriFunction, List, T> ctor, @@ -55,14 +57,14 @@ protected static ConstructingObjectParser< private List taskFailures; private List nodeFailures; - AcknowledgedTasksResponse(boolean acknowledged, List taskFailures, - List nodeFailures) { + public AcknowledgedTasksResponse(boolean acknowledged, @Nullable List taskFailures, + @Nullable List nodeFailures) { this.acknowledged = acknowledged; this.taskFailures = taskFailures == null ? Collections.emptyList() : Collections.unmodifiableList(new ArrayList<>(taskFailures)); this.nodeFailures = nodeFailures == null ? Collections.emptyList() : Collections.unmodifiableList(new ArrayList<>(nodeFailures)); } - boolean isAcknowledged() { + public boolean isAcknowledged() { return acknowledged; } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformResponse.java new file mode 100644 index 0000000000000..3d2ff03bd7912 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformResponse.java @@ -0,0 +1,51 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.dataframe; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.TaskOperationFailure; +import org.elasticsearch.client.core.AcknowledgedTasksResponse; +import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; + +public class StopDataFrameTransformResponse extends AcknowledgedTasksResponse { + + private static final String STOPPED = "stopped"; + + private static final ConstructingObjectParser PARSER = + AcknowledgedTasksResponse.generateParser("start_rollup_job_response", StopDataFrameTransformResponse::new, STOPPED); + + public static StopDataFrameTransformResponse fromXContent(final XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } + + public StopDataFrameTransformResponse(boolean stopped, @Nullable List taskFailures, + @Nullable List nodeFailures) { + super(stopped, taskFailures, nodeFailures); + } + + public boolean isStopped() { + return isAcknowledged(); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java index 4e342e7cc3f48..33faeccd0802b 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java @@ -24,6 +24,7 @@ import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StopDataFrameTransformResponse; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfig; import org.elasticsearch.client.dataframe.transforms.QueryConfig; import org.elasticsearch.client.dataframe.transforms.pivot.AggregationConfig; @@ -118,8 +119,11 @@ public void testStop() throws IOException { assertTrue(ack.isAcknowledged()); StopDataFrameTransformRequest stopRequest = new StopDataFrameTransformRequest(id); - execute(stopRequest, client::stopDataFrameTransform, client::stopDataFrameTransformAsync); - assertTrue(ack.isAcknowledged()); + StopDataFrameTransformResponse stopResponse = + execute(stopRequest, client::stopDataFrameTransform, client::stopDataFrameTransformAsync); + assertTrue(stopResponse.isStopped()); + assertNull(stopResponse.getNodeFailures()); + assertNull(stopResponse.getTaskFailures()); } } diff --git a/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc b/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc index 03767a8fa24f5..6a1e740ae198f 100644 --- a/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc +++ b/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc @@ -1,7 +1,7 @@ -- :api: stop-data-frame-transform :request: StopDataFrameTransformRequest -:response: AcknowledgedResponse +:response: StopDataFrameTransformResponse -- [id="{upid}-{api}"] === Stop Data Frame Transform API @@ -18,7 +18,7 @@ A +{request}+ object requires a non-null `id`. --------------------------------------------------- include-tagged::{doc-tests-file}[{api}-request] --------------------------------------------------- -<1> Constructing a new request referencing an existing {dataframe-job} +<1> Constructing a new stop request referencing an existing {dataframe-job} ==== Optional Arguments From 3fe1fe0b173b4daf2f8fe191c3a3118b30659209 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Thu, 14 Mar 2019 15:57:48 +0000 Subject: [PATCH 4/7] Start api --- .../elasticsearch/client/DataFrameClient.java | 43 +++++++ .../client/DataFrameRequestConverters.java | 15 +++ .../StartDataFrameTransformRequest.java | 84 +++++++++++++ .../StartDataFrameTransformResponse.java | 51 ++++++++ .../StopDataFrameTransformResponse.java | 2 +- .../DataFrameRequestConvertersTests.java | 21 ++++ .../client/DataFrameTransformIT.java | 20 +++- .../StartDataFrameTransformRequestTests.java | 42 +++++++ .../DataFrameTransformDocumentationIT.java | 113 +++++++++++++++++- 9 files changed, 381 insertions(+), 10 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformResponse.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequestTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java index 252c94e598d24..35a6403ef5eaa 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java @@ -23,6 +23,8 @@ import org.elasticsearch.client.core.AcknowledgedResponse; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StartDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StartDataFrameTransformResponse; import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import org.elasticsearch.client.dataframe.StopDataFrameTransformResponse; @@ -118,6 +120,47 @@ public void deleteDataFrameTransformAsync(DeleteDataFrameTransformRequest reques Collections.emptySet()); } + + /** + * Start a data frame transform + *

+ * For additional info + * see Start Data Frame transform documentation + * + * @param request The start data frame transform request + * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return A response object indicating request success + * @throws IOException when there is a serialization issue sending the request or receiving the response + */ + public StartDataFrameTransformResponse startDataFrameTransform(StartDataFrameTransformRequest request, RequestOptions options) + throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, + DataFrameRequestConverters::startDataFrameTransform, + options, + StartDataFrameTransformResponse::fromXContent, + Collections.emptySet()); + } + + /** + * Start a data frame transform asynchronously and notifies listener on completion + *

+ * For additional info + * see Start Data Frame transform documentation + * + * @param request The start data frame transform request + * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @param listener Listener to be notified upon request completion + */ + public void startDataFrameTransformAsync(StartDataFrameTransformRequest request, RequestOptions options, + ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(request, + DataFrameRequestConverters::startDataFrameTransform, + options, + StartDataFrameTransformResponse::fromXContent, + listener, + Collections.emptySet()); + } + /** * Stop a data frame transform *

diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameRequestConverters.java index a0ddecb46a81d..de7320b6adab8 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameRequestConverters.java @@ -24,6 +24,7 @@ import org.apache.http.client.methods.HttpPut; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StartDataFrameTransformRequest; import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import java.io.IOException; @@ -53,6 +54,20 @@ static Request deleteDataFrameTransform(DeleteDataFrameTransformRequest request) return new Request(HttpDelete.METHOD_NAME, endpoint); } + static Request startDataFrameTransform(StartDataFrameTransformRequest startRequest) { + String endpoint = new RequestConverters.EndpointBuilder() + .addPathPartAsIs("_data_frame", "transforms") + .addPathPart(startRequest.getId()) + .addPathPartAsIs("_start") + .build(); + Request request = new Request(HttpPost.METHOD_NAME, endpoint); + RequestConverters.Params params = new RequestConverters.Params(request); + if (startRequest.getTimeout() != null) { + params.withTimeout(startRequest.getTimeout()); + } + return request; + } + static Request stopDataFrameTransform(StopDataFrameTransformRequest stopRequest) { String endpoint = new RequestConverters.EndpointBuilder() .addPathPartAsIs("_data_frame", "transforms") diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java new file mode 100644 index 0000000000000..7482186e270ee --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java @@ -0,0 +1,84 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.dataframe; + +import org.elasticsearch.client.Validatable; +import org.elasticsearch.client.ValidationException; +import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.unit.TimeValue; + +import java.util.Objects; +import java.util.Optional; + +public class StartDataFrameTransformRequest implements Validatable { + + private final String id; + // TODO The REST endpoint does not accept the timeout parameter yet + private final TimeValue timeout; + + public StartDataFrameTransformRequest(String id) { + this.id = id; + this.timeout = null; + } + + public StartDataFrameTransformRequest(String id, @Nullable TimeValue timeout) { + this.id = id; + this.timeout = timeout; + } + + public String getId() { + return id; + } + + @Nullable + public TimeValue getTimeout() { + return timeout; + } + + @Override + public Optional validate() { + if (id == null) { + ValidationException validationException = new ValidationException(); + validationException.addValidationError("data frame transform id must not be null"); + return Optional.of(validationException); + } else { + return Optional.empty(); + } + } + + @Override + public int hashCode() { + return Objects.hash(id, timeout); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + StartDataFrameTransformRequest other = (StartDataFrameTransformRequest) obj; + return Objects.equals(this.id, other.id) + && Objects.equals(this.timeout, other.timeout); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformResponse.java new file mode 100644 index 0000000000000..43f99201b4567 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformResponse.java @@ -0,0 +1,51 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.dataframe; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.action.TaskOperationFailure; +import org.elasticsearch.client.core.AcknowledgedTasksResponse; +import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; + +public class StartDataFrameTransformResponse extends AcknowledgedTasksResponse { + + private static final String STARTED = "started"; + + private static final ConstructingObjectParser PARSER = + AcknowledgedTasksResponse.generateParser("stop_data_frame_transform_response", StartDataFrameTransformResponse::new, STARTED); + + public static StartDataFrameTransformResponse fromXContent(final XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } + + public StartDataFrameTransformResponse(boolean started, @Nullable List taskFailures, + @Nullable List nodeFailures) { + super(started, taskFailures, nodeFailures); + } + + public boolean isStarted() { + return isAcknowledged(); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformResponse.java index 3d2ff03bd7912..5020ba270d990 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformResponse.java @@ -34,7 +34,7 @@ public class StopDataFrameTransformResponse extends AcknowledgedTasksResponse { private static final String STOPPED = "stopped"; private static final ConstructingObjectParser PARSER = - AcknowledgedTasksResponse.generateParser("start_rollup_job_response", StopDataFrameTransformResponse::new, STOPPED); + AcknowledgedTasksResponse.generateParser("stop_data_frame_transform_response", StopDataFrameTransformResponse::new, STOPPED); public static StopDataFrameTransformResponse fromXContent(final XContentParser parser) throws IOException { return PARSER.parse(parser, null); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameRequestConvertersTests.java index 256afb1f4eb6c..d7249492bc6fc 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameRequestConvertersTests.java @@ -24,6 +24,7 @@ import org.apache.http.client.methods.HttpPut; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StartDataFrameTransformRequest; import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfig; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfigTests; @@ -70,6 +71,26 @@ public void testDeleteDataFrameTransform() { assertThat(request.getEndpoint(), equalTo("/_data_frame/transforms/foo")); } + public void testStartDataFrameTransform() { + String id = randomAlphaOfLength(10); + TimeValue timeValue = null; + if (randomBoolean()) { + timeValue = TimeValue.parseTimeValue(randomTimeValue(), "timeout"); + } + StartDataFrameTransformRequest startRequest = new StartDataFrameTransformRequest(id, timeValue); + + Request request = DataFrameRequestConverters.startDataFrameTransform(startRequest); + assertEquals(HttpPost.METHOD_NAME, request.getMethod()); + assertThat(request.getEndpoint(), equalTo("/_data_frame/transforms/" + startRequest.getId() + "/_start")); + + if (timeValue != null) { + assertTrue(request.getParameters().containsKey("timeout")); + assertEquals(startRequest.getTimeout(), TimeValue.parseTimeValue(request.getParameters().get("timeout"), "timeout")); + } else { + assertFalse(request.getParameters().containsKey("timeout")); + } + } + public void testStopDataFrameTransform() { String id = randomAlphaOfLength(10); Boolean waitForCompletion = null; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java index 33faeccd0802b..9c5bb7c175480 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/DataFrameTransformIT.java @@ -23,6 +23,8 @@ import org.elasticsearch.client.core.AcknowledgedResponse; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StartDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StartDataFrameTransformResponse; import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; import org.elasticsearch.client.dataframe.StopDataFrameTransformResponse; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfig; @@ -43,6 +45,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; public class DataFrameTransformIT extends ESRestHighLevelClientTestCase { @@ -99,7 +102,7 @@ public void testCreateDelete() throws IOException { assertThat(deleteError.getMessage(), containsString("Transform with id [test-crud] could not be found")); } - public void testStop() throws IOException { + public void testStartStop() throws IOException { String sourceIndex = "transform-source"; createIndex(sourceIndex); @@ -110,7 +113,7 @@ public void testStop() throws IOException { AggregationConfig aggConfig = new AggregationConfig(aggBuilder); PivotConfig pivotConfig = new PivotConfig(groupConfig, aggConfig); - String id = "test-stop"; + String id = "test-stop-start"; DataFrameTransformConfig transform = new DataFrameTransformConfig(id, sourceIndex, "pivot-dest", queryConfig, pivotConfig); DataFrameClient client = highLevelClient().dataFrame(); @@ -118,12 +121,21 @@ public void testStop() throws IOException { client::putDataFrameTransformAsync); assertTrue(ack.isAcknowledged()); + StartDataFrameTransformRequest startRequest = new StartDataFrameTransformRequest(id); + StartDataFrameTransformResponse startResponse = + execute(startRequest, client::startDataFrameTransform, client::startDataFrameTransformAsync); + assertTrue(startResponse.isStarted()); + assertThat(startResponse.getNodeFailures(), empty()); + assertThat(startResponse.getTaskFailures(), empty()); + + // TODO once get df stats is implemented assert the df has started + StopDataFrameTransformRequest stopRequest = new StopDataFrameTransformRequest(id); StopDataFrameTransformResponse stopResponse = execute(stopRequest, client::stopDataFrameTransform, client::stopDataFrameTransformAsync); assertTrue(stopResponse.isStopped()); - assertNull(stopResponse.getNodeFailures()); - assertNull(stopResponse.getTaskFailures()); + assertThat(stopResponse.getNodeFailures(), empty()); + assertThat(stopResponse.getTaskFailures(), empty()); } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequestTests.java new file mode 100644 index 0000000000000..6db4d1cd36f6e --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequestTests.java @@ -0,0 +1,42 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.dataframe; + +import org.elasticsearch.client.ValidationException; +import org.elasticsearch.test.ESTestCase; + +import java.util.Optional; + +import static org.hamcrest.Matchers.containsString; + +public class StartDataFrameTransformRequestTests extends ESTestCase { + public void testValidate_givenNullId() { + StartDataFrameTransformRequest request = new StartDataFrameTransformRequest(null, null); + Optional validate = request.validate(); + assertTrue(validate.isPresent()); + assertThat(validate.get().getMessage(), containsString("data frame transform id must not be null")); + } + + public void testValidate_givenValid() { + StartDataFrameTransformRequest request = new StartDataFrameTransformRequest("foo", null); + Optional validate = request.validate(); + assertFalse(validate.isPresent()); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java index c578f5acb6f85..2c5b74be9d807 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java @@ -27,7 +27,10 @@ import org.elasticsearch.client.core.AcknowledgedResponse; import org.elasticsearch.client.dataframe.DeleteDataFrameTransformRequest; import org.elasticsearch.client.dataframe.PutDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StartDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StartDataFrameTransformResponse; import org.elasticsearch.client.dataframe.StopDataFrameTransformRequest; +import org.elasticsearch.client.dataframe.StopDataFrameTransformResponse; import org.elasticsearch.client.dataframe.transforms.DataFrameTransformConfig; import org.elasticsearch.client.dataframe.transforms.QueryConfig; import org.elasticsearch.client.dataframe.transforms.pivot.AggregationConfig; @@ -151,13 +154,113 @@ public void onFailure(Exception e) { assertTrue(latch.await(30L, TimeUnit.SECONDS)); } + } + + public void testStartStop() throws IOException, InterruptedException { + createIndex("source-data"); + + RestHighLevelClient client = highLevelClient(); + + QueryConfig queryConfig = new QueryConfig(new MatchAllQueryBuilder()); + GroupConfig groupConfig = new GroupConfig(Collections.singletonMap("reviewer", new TermsGroupSource("user_id"))); + AggregatorFactories.Builder aggBuilder = new AggregatorFactories.Builder(); + aggBuilder.addAggregator(AggregationBuilders.avg("avg_rating").field("stars")); + AggregationConfig aggConfig = new AggregationConfig(aggBuilder); + PivotConfig pivotConfig = new PivotConfig(groupConfig, aggConfig); + + DataFrameTransformConfig transformConfig = new DataFrameTransformConfig("mega-transform", + "source-data", "pivot-dest", queryConfig, pivotConfig); + + client.dataFrame().putDataFrameTransform(new PutDataFrameTransformRequest(transformConfig), RequestOptions.DEFAULT); + + { + // tag::start-data-frame-transform-request + StartDataFrameTransformRequest request = + new StartDataFrameTransformRequest("mega-transform"); + // end::start-data-frame-transform-request + + // tag::start-data-frame-transform-execute + StartDataFrameTransformResponse response = + client.dataFrame().startDataFrameTransform( + request, RequestOptions.DEFAULT); + // end::start-data-frame-transform-execute + + assertTrue(response.isStarted()); + } + { + // tag::stop-data-frame-transform-request + StopDataFrameTransformRequest request = + new StopDataFrameTransformRequest("mega-transform"); + // end::stop-data-frame-transform-request + + // tag::stop-data-frame-transform-execute + StopDataFrameTransformResponse response = + client.dataFrame().stopDataFrameTransform( + request, RequestOptions.DEFAULT); + // end::stop-data-frame-transform-execute - // Stop the Data Frame - // tag::stop-data-frame-transform-request - StopDataFrameTransformRequest stopRequest = - new StopDataFrameTransformRequest("reviewer-avg-rating"); - // end::stop-data-frame-transform-request + assertTrue(response.isStopped()); + } + { + // tag::start-data-frame-transform-execute-listener + ActionListener listener = + new ActionListener() { + @Override + public void onResponse( + StartDataFrameTransformResponse response) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::start-data-frame-transform-execute-listener + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + ActionListener ackListener = listener; + listener = new LatchedActionListener<>(listener, latch); + + StartDataFrameTransformRequest request = new StartDataFrameTransformRequest("mega-transform"); + // tag::start-data-frame-transform-execute-async + client.dataFrame().startDataFrameTransformAsync( + request, RequestOptions.DEFAULT, listener); // <1> + // end::start-data-frame-transform-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + { + // tag::stop-data-frame-transform-execute-listener + ActionListener listener = + new ActionListener() { + @Override + public void onResponse( + StopDataFrameTransformResponse response) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::stop-data-frame-transform-execute-listener + + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + ActionListener ackListener = listener; + listener = new LatchedActionListener<>(listener, latch); + + StopDataFrameTransformRequest request = new StopDataFrameTransformRequest("mega-transform"); + // tag::stop-data-frame-transform-execute-async + client.dataFrame().stopDataFrameTransformAsync( + request, RequestOptions.DEFAULT, listener); // <1> + // end::stop-data-frame-transform-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } } public void testDeleteDataFrameTransform() throws IOException, InterruptedException { From 74053ec76466a677f4bb632156c99d177ebd4de0 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Mon, 18 Mar 2019 11:17:17 +0000 Subject: [PATCH 5/7] Small tidy-ups --- .../elasticsearch/client/DataFrameClient.java | 2 +- .../StartDataFrameTransformRequest.java | 11 +++--- .../StartDataFrameTransformResponse.java | 2 +- .../StopDataFrameTransformRequest.java | 15 ++++++-- .../core/AcknowledgedTasksResponseTests.java | 24 +++++++----- .../DataFrameTransformDocumentationIT.java | 21 ++++++++++- .../dataframe/start_data_frame.asciidoc | 37 +++++++++++++++++++ .../dataframe/stop_data_frame.asciidoc | 1 - .../high-level/supported-apis.asciidoc | 6 ++- 9 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 docs/java-rest/high-level/dataframe/start_data_frame.asciidoc diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java index 35a6403ef5eaa..2cd32f7e75c71 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/DataFrameClient.java @@ -169,7 +169,7 @@ public void startDataFrameTransformAsync(StartDataFrameTransformRequest request, * * @param request The stop data frame transform request * @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized - * @return An AcknowledgedResponse object indicating request success + * @return A response object indicating request success * @throws IOException when there is a serialization issue sending the request or receiving the response */ public StopDataFrameTransformResponse stopDataFrameTransform(StopDataFrameTransformRequest request, RequestOptions options) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java index 7482186e270ee..9dc9ab34288dc 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java @@ -21,7 +21,6 @@ import org.elasticsearch.client.Validatable; import org.elasticsearch.client.ValidationException; -import org.elasticsearch.common.Nullable; import org.elasticsearch.common.unit.TimeValue; import java.util.Objects; @@ -31,14 +30,13 @@ public class StartDataFrameTransformRequest implements Validatable { private final String id; // TODO The REST endpoint does not accept the timeout parameter yet - private final TimeValue timeout; + private TimeValue timeout; public StartDataFrameTransformRequest(String id) { this.id = id; - this.timeout = null; } - public StartDataFrameTransformRequest(String id, @Nullable TimeValue timeout) { + public StartDataFrameTransformRequest(String id, TimeValue timeout) { this.id = id; this.timeout = timeout; } @@ -47,11 +45,14 @@ public String getId() { return id; } - @Nullable public TimeValue getTimeout() { return timeout; } + public void setTimeout(TimeValue timeout) { + this.timeout = timeout; + } + @Override public Optional validate() { if (id == null) { diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformResponse.java index 43f99201b4567..3878824b91f4a 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformResponse.java @@ -34,7 +34,7 @@ public class StartDataFrameTransformResponse extends AcknowledgedTasksResponse { private static final String STARTED = "started"; private static final ConstructingObjectParser PARSER = - AcknowledgedTasksResponse.generateParser("stop_data_frame_transform_response", StartDataFrameTransformResponse::new, STARTED); + AcknowledgedTasksResponse.generateParser("start_data_frame_transform_response", StartDataFrameTransformResponse::new, STARTED); public static StartDataFrameTransformResponse fromXContent(final XContentParser parser) throws IOException { return PARSER.parse(parser, null); diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequest.java index ffa6b70865db8..0bc690ad79076 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StopDataFrameTransformRequest.java @@ -21,7 +21,6 @@ import org.elasticsearch.client.Validatable; import org.elasticsearch.client.ValidationException; -import org.elasticsearch.common.Nullable; import org.elasticsearch.common.unit.TimeValue; import java.util.Objects; @@ -30,8 +29,8 @@ public class StopDataFrameTransformRequest implements Validatable { private final String id; - private final Boolean waitForCompletion; - private final TimeValue timeout; + private Boolean waitForCompletion; + private TimeValue timeout; public StopDataFrameTransformRequest(String id) { this.id = id; @@ -39,7 +38,7 @@ public StopDataFrameTransformRequest(String id) { timeout = null; } - public StopDataFrameTransformRequest(String id, @Nullable Boolean waitForCompletion, @Nullable TimeValue timeout) { + public StopDataFrameTransformRequest(String id, Boolean waitForCompletion, TimeValue timeout) { this.id = id; this.waitForCompletion = waitForCompletion; this.timeout = timeout; @@ -49,10 +48,18 @@ public String getId() { return id; } + public void setWaitForCompletion(Boolean waitForCompletion) { + this.waitForCompletion = waitForCompletion; + } + public Boolean getWaitForCompletion() { return waitForCompletion; } + public void setTimeout(TimeValue timeout) { + this.timeout = timeout; + } + public TimeValue getTimeout() { return timeout; } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/core/AcknowledgedTasksResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/core/AcknowledgedTasksResponseTests.java index 34a2ffa6830ee..584c2f4f8772f 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/core/AcknowledgedTasksResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/core/AcknowledgedTasksResponseTests.java @@ -33,6 +33,7 @@ import java.util.function.BiPredicate; import static org.elasticsearch.test.AbstractXContentTestCase.xContentTester; +import static org.hamcrest.Matchers.containsString; public class AcknowledgedTasksResponseTests extends ESTestCase { @@ -47,13 +48,13 @@ public void testFromXContent() throws IOException { .test(); } - // Serialisation of TaskOperationFailure changes the error - // so use a custom compare method - private void assertEqualInstances(AcknowledgedTasksResponse expectedInstance, AcknowledgedTasksResponse actual) { - assertNotSame(expectedInstance, actual); - assertEquals(expectedInstance.isAcknowledged(), actual.isAcknowledged()); + // Serialisation of TaskOperationFailure and ElasticsearchException changes + // the object so use a custom compare method rather than Object.equals + private void assertEqualInstances(AcknowledgedTasksResponse expected, AcknowledgedTasksResponse actual) { + assertNotSame(expected, actual); + assertEquals(expected.isAcknowledged(), actual.isAcknowledged()); - List expectedTaskFailures = expectedInstance.getTaskFailures(); + List expectedTaskFailures = expected.getTaskFailures(); List actualTaskFailures = actual.getTaskFailures(); assertListEquals(expectedTaskFailures, actualTaskFailures, (a, b) -> @@ -62,11 +63,16 @@ private void assertEqualInstances(AcknowledgedTasksResponse expectedInstance, Ac && Objects.equals(a.getStatus(), b.getStatus()) ); - - List expectedExceptions = expectedInstance.getNodeFailures(); + List expectedExceptions = expected.getNodeFailures(); List actualExceptions = actual.getNodeFailures(); - assertListEquals(expectedExceptions, actualExceptions, (a, b) -> a != null && b != null); + // actualException is a wrapped copy of expectedException so the + // error messages won't be the same but actualException should contain + // the error message from expectedException + assertListEquals(expectedExceptions, actualExceptions, (expectedException, actualException) -> { + assertThat(actualException.getDetailedMessage(), containsString(expectedException.getMessage())); + return true; + }); } private void assertListEquals(List expected, List actual, BiPredicate comparator) { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java index 2c5b74be9d807..bae7e811d9b7c 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java @@ -39,6 +39,7 @@ import org.elasticsearch.client.dataframe.transforms.pivot.TermsGroupSource; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.CreateIndexResponse; +import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.search.aggregations.AggregationBuilders; @@ -176,9 +177,17 @@ public void testStartStop() throws IOException, InterruptedException { { // tag::start-data-frame-transform-request StartDataFrameTransformRequest request = - new StartDataFrameTransformRequest("mega-transform"); + new StartDataFrameTransformRequest("mega-transform"); // <1> // end::start-data-frame-transform-request + // tag::start-data-frame-transform-request-options + request.setTimeout(TimeValue.timeValueSeconds(20)); // <1> + // end::start-data-frame-transform-request-options + + + // TODO null the timeout value until it is supported in the REST api + request.setTimeout(null); + // tag::start-data-frame-transform-execute StartDataFrameTransformResponse response = client.dataFrame().startDataFrameTransform( @@ -190,9 +199,17 @@ public void testStartStop() throws IOException, InterruptedException { { // tag::stop-data-frame-transform-request StopDataFrameTransformRequest request = - new StopDataFrameTransformRequest("mega-transform"); + new StopDataFrameTransformRequest("mega-transform"); // <1> // end::stop-data-frame-transform-request + // tag::stop-data-frame-transform-request-options + request.setWaitForCompletion(Boolean.TRUE); // <1> + request.setTimeout(TimeValue.timeValueSeconds(30)); // <2> + // end::stop-data-frame-transform-request-options + + // TODO null the timeout value until it is supported in the REST api + request.setTimeout(null); + // tag::stop-data-frame-transform-execute StopDataFrameTransformResponse response = client.dataFrame().stopDataFrameTransform( diff --git a/docs/java-rest/high-level/dataframe/start_data_frame.asciidoc b/docs/java-rest/high-level/dataframe/start_data_frame.asciidoc new file mode 100644 index 0000000000000..6e18eb877289b --- /dev/null +++ b/docs/java-rest/high-level/dataframe/start_data_frame.asciidoc @@ -0,0 +1,37 @@ +-- +:api: start-data-frame-transform +:request: StartDataFrameTransformRequest +:response: StartDataFrameTransformResponse +-- +[id="{upid}-{api}"] +=== Start Data Frame Transform API + +Start a {dataframe-job}. +It accepts a +{request}+ object and responds with a +{response}+ object. + +[id="{upid}-{api}-request"] +==== Start Data Frame Request + +A +{request}+ object requires a non-null `id`. + +["source","java",subs="attributes,callouts,macros"] +--------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request] +--------------------------------------------------- +<1> Constructing a new start request referencing an existing {dataframe-job} + +==== Optional Arguments + +The following arguments are optional. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request-options] +-------------------------------------------------- +<1> Controls the amount of time to wait until the {dataframe-job} starts. + +include::../execution.asciidoc[] + +==== Response + +The returned +{response}+ object acknowledges the {dataframe-job} has started. \ No newline at end of file diff --git a/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc b/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc index 6a1e740ae198f..c91c228e0ea90 100644 --- a/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc +++ b/docs/java-rest/high-level/dataframe/stop_data_frame.asciidoc @@ -30,7 +30,6 @@ include-tagged::{doc-tests-file}[{api}-request-options] -------------------------------------------------- <1> If true wait for the data frame task to stop before responding <2> Controls the amount of time to wait until the {dataframe-job} stops. -The default value is 30 seconds. include::../execution.asciidoc[] diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index f1ad8ee5e5c7e..3d3e81f463662 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -556,6 +556,10 @@ The Java High Level REST Client supports the following Data Frame APIs: * <<{upid}-put-data-frame-transform>> * <<{upid}-delete-data-frame-transform>> +* <<{upid}-start-data-frame-transform>> +* <<{upid}-stop-data-frame-transform>> include::dataframe/put_data_frame.asciidoc[] -include::dataframe/delete_data_frame.asciidoc[] \ No newline at end of file +include::dataframe/delete_data_frame.asciidoc[] +include::dataframe/start_data_frame.asciidoc[] +include::dataframe/stop_data_frame.asciidoc[] \ No newline at end of file From f2430ac5ba55baee647a8b968bfdb060f2fd4c41 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Mon, 18 Mar 2019 14:10:44 +0000 Subject: [PATCH 6/7] Add teardown to docs test --- .../DataFrameTransformDocumentationIT.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java index bae7e811d9b7c..d987c9c07b7af 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java @@ -44,9 +44,12 @@ import org.elasticsearch.index.query.MatchAllQueryBuilder; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.AggregatorFactories; +import org.junit.After; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -54,6 +57,22 @@ public class DataFrameTransformDocumentationIT extends ESRestHighLevelClientTestCase { + private List transformsToClean = new ArrayList<>(); + + @After + public void cleanUpTransforms() throws IOException { + for (String transformId : transformsToClean) { + highLevelClient().dataFrame().stopDataFrameTransform(new StopDataFrameTransformRequest(transformId), RequestOptions.DEFAULT); + } + + for (String transformId : transformsToClean) { + highLevelClient().dataFrame().deleteDataFrameTransform( + new DeleteDataFrameTransformRequest(transformId), RequestOptions.DEFAULT); + } + + transformsToClean = new ArrayList<>(); + } + private void createIndex(String indexName) throws IOException { XContentBuilder builder = jsonBuilder(); @@ -173,6 +192,7 @@ public void testStartStop() throws IOException, InterruptedException { "source-data", "pivot-dest", queryConfig, pivotConfig); client.dataFrame().putDataFrameTransform(new PutDataFrameTransformRequest(transformConfig), RequestOptions.DEFAULT); + transformsToClean.add(transformConfig.getId()); { // tag::start-data-frame-transform-request @@ -207,9 +227,6 @@ public void testStartStop() throws IOException, InterruptedException { request.setTimeout(TimeValue.timeValueSeconds(30)); // <2> // end::stop-data-frame-transform-request-options - // TODO null the timeout value until it is supported in the REST api - request.setTimeout(null); - // tag::stop-data-frame-transform-execute StopDataFrameTransformResponse response = client.dataFrame().stopDataFrameTransform( From 679a44d9fe2e6913889f9f9dc8f6bbbc4b831c79 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Mon, 18 Mar 2019 15:11:06 +0000 Subject: [PATCH 7/7] Add timeout param parsing to start request --- .../client/dataframe/StartDataFrameTransformRequest.java | 1 - .../documentation/DataFrameTransformDocumentationIT.java | 4 ---- .../rest/action/RestStartDataFrameTransformAction.java | 8 +++++--- .../api/data_frame.start_data_frame_transform.json | 7 +++++++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java index 9dc9ab34288dc..380105eec5fd6 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/dataframe/StartDataFrameTransformRequest.java @@ -29,7 +29,6 @@ public class StartDataFrameTransformRequest implements Validatable { private final String id; - // TODO The REST endpoint does not accept the timeout parameter yet private TimeValue timeout; public StartDataFrameTransformRequest(String id) { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java index d987c9c07b7af..75fcf573f5a93 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/DataFrameTransformDocumentationIT.java @@ -204,10 +204,6 @@ public void testStartStop() throws IOException, InterruptedException { request.setTimeout(TimeValue.timeValueSeconds(20)); // <1> // end::start-data-frame-transform-request-options - - // TODO null the timeout value until it is supported in the REST api - request.setTimeout(null); - // tag::start-data-frame-transform-execute StartDataFrameTransformResponse response = client.dataFrame().startDataFrameTransform( diff --git a/x-pack/plugin/data-frame/src/main/java/org/elasticsearch/xpack/dataframe/rest/action/RestStartDataFrameTransformAction.java b/x-pack/plugin/data-frame/src/main/java/org/elasticsearch/xpack/dataframe/rest/action/RestStartDataFrameTransformAction.java index ac9f86388df35..a7cd58e8aed3a 100644 --- a/x-pack/plugin/data-frame/src/main/java/org/elasticsearch/xpack/dataframe/rest/action/RestStartDataFrameTransformAction.java +++ b/x-pack/plugin/data-frame/src/main/java/org/elasticsearch/xpack/dataframe/rest/action/RestStartDataFrameTransformAction.java @@ -6,6 +6,7 @@ package org.elasticsearch.xpack.dataframe.rest.action; +import org.elasticsearch.action.support.master.AcknowledgedRequest; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.rest.BaseRestHandler; @@ -13,7 +14,6 @@ import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.action.RestToXContentListener; import org.elasticsearch.xpack.core.dataframe.DataFrameField; -import org.elasticsearch.xpack.core.rollup.RollupField; import org.elasticsearch.xpack.core.dataframe.action.StartDataFrameTransformAction; import java.io.IOException; @@ -27,9 +27,11 @@ public RestStartDataFrameTransformAction(Settings settings, RestController contr @Override protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException { - String id = restRequest.param(RollupField.ID.getPreferredName()); + String id = restRequest.param(DataFrameField.ID.getPreferredName()); StartDataFrameTransformAction.Request request = new StartDataFrameTransformAction.Request(id); - + if (restRequest.hasParam(DataFrameField.TIMEOUT.getPreferredName())) { + request.timeout(restRequest.paramAsTime(DataFrameField.TIMEOUT.getPreferredName(), AcknowledgedRequest.DEFAULT_ACK_TIMEOUT)); + } return channel -> client.execute(StartDataFrameTransformAction.INSTANCE, request, new RestToXContentListener<>(channel)); } diff --git a/x-pack/plugin/src/test/resources/rest-api-spec/api/data_frame.start_data_frame_transform.json b/x-pack/plugin/src/test/resources/rest-api-spec/api/data_frame.start_data_frame_transform.json index 9bcd311ed5238..f1cb5b1e9d9b8 100644 --- a/x-pack/plugin/src/test/resources/rest-api-spec/api/data_frame.start_data_frame_transform.json +++ b/x-pack/plugin/src/test/resources/rest-api-spec/api/data_frame.start_data_frame_transform.json @@ -11,6 +11,13 @@ "required": true, "description": "The id of the transform to start" } + }, + "params": { + "timeout": { + "type": "time", + "required": false, + "description": "Controls the time to wait for the transform to start" + } } }, "body": null