|
7 | 7 | package org.elasticsearch.xpack.core.async; |
8 | 8 |
|
9 | 9 | import org.elasticsearch.ResourceNotFoundException; |
| 10 | +import org.elasticsearch.TransportVersion; |
10 | 11 | import org.elasticsearch.action.ActionListener; |
11 | 12 | import org.elasticsearch.action.DocWriteResponse; |
12 | 13 | import org.elasticsearch.action.support.PlainActionFuture; |
13 | 14 | import org.elasticsearch.action.support.master.AcknowledgedResponse; |
14 | 15 | import org.elasticsearch.action.update.UpdateResponse; |
| 16 | +import org.elasticsearch.cluster.ClusterState; |
15 | 17 | import org.elasticsearch.cluster.service.ClusterService; |
16 | 18 | import org.elasticsearch.common.util.BigArrays; |
17 | 19 | import org.elasticsearch.core.TimeValue; |
| 20 | +import org.elasticsearch.rest.RestStatus; |
18 | 21 | import org.elasticsearch.tasks.CancellableTask; |
19 | 22 | import org.elasticsearch.tasks.Task; |
20 | 23 | import org.elasticsearch.tasks.TaskId; |
21 | 24 | import org.elasticsearch.tasks.TaskManager; |
22 | 25 | import org.elasticsearch.test.ESSingleNodeTestCase; |
| 26 | +import org.elasticsearch.test.TransportVersionUtils; |
23 | 27 | import org.elasticsearch.transport.AbstractTransportRequest; |
24 | 28 | import org.elasticsearch.transport.TransportService; |
25 | 29 | import org.elasticsearch.xpack.core.async.AsyncSearchIndexServiceTests.TestAsyncResponse; |
|
37 | 41 | import static org.hamcrest.Matchers.lessThanOrEqualTo; |
38 | 42 | import static org.hamcrest.Matchers.notNullValue; |
39 | 43 | import static org.hamcrest.Matchers.nullValue; |
| 44 | +import static org.mockito.Mockito.spy; |
| 45 | +import static org.mockito.Mockito.when; |
40 | 46 |
|
41 | 47 | public class AsyncResultsServiceTests extends ESSingleNodeTestCase { |
42 | 48 | private ClusterService clusterService; |
@@ -132,7 +138,7 @@ public Task createTask(long id, String type, String action, TaskId parentTaskId, |
132 | 138 |
|
133 | 139 | @Before |
134 | 140 | public void setup() { |
135 | | - clusterService = getInstanceFromNode(ClusterService.class); |
| 141 | + clusterService = spy(getInstanceFromNode(ClusterService.class)); |
136 | 142 | TransportService transportService = getInstanceFromNode(TransportService.class); |
137 | 143 | BigArrays bigArrays = getInstanceFromNode(BigArrays.class); |
138 | 144 | taskManager = transportService.getTaskManager(); |
@@ -326,4 +332,52 @@ public void testRetrieveFromDisk() throws Exception { |
326 | 332 | deleteService.deleteResponse(new DeleteAsyncResultRequest(task.getExecutionId().getEncoded()), deleteListener); |
327 | 333 | assertFutureThrows(deleteListener, ResourceNotFoundException.class); |
328 | 334 | } |
| 335 | + |
| 336 | + public void testFailWithIncompatibleResults() throws Exception { |
| 337 | + // force the search results to be serialized with an incompatible transport version |
| 338 | + when(clusterService.state()).thenAnswer(invocation -> { |
| 339 | + ClusterState state = (ClusterState) invocation.callRealMethod(); |
| 340 | + return ClusterState.builder(state) |
| 341 | + .putCompatibilityVersions( |
| 342 | + node().getNodeEnvironment().nodeId(), |
| 343 | + TransportVersionUtils.getPreviousVersion(TransportVersion.minimumCompatible()), |
| 344 | + Map.of() |
| 345 | + ) |
| 346 | + .build(); |
| 347 | + }); |
| 348 | + |
| 349 | + AsyncResultsService<TestTask, TestAsyncResponse> service = createResultsService(true); |
| 350 | + TestRequest request = new TestRequest("test request"); |
| 351 | + TestTask task = (TestTask) taskManager.register("test", "test", request); |
| 352 | + try { |
| 353 | + long startTime = System.currentTimeMillis(); |
| 354 | + task.setExpirationTime(startTime + TimeValue.timeValueMinutes(1).getMillis()); |
| 355 | + |
| 356 | + // we need to store initial result |
| 357 | + PlainActionFuture<DocWriteResponse> futureCreate = new PlainActionFuture<>(); |
| 358 | + indexService.createResponse( |
| 359 | + task.getExecutionId().getDocId(), |
| 360 | + task.getOriginHeaders(), |
| 361 | + new TestAsyncResponse(null, task.getExpirationTime()), |
| 362 | + futureCreate |
| 363 | + ); |
| 364 | + futureCreate.actionGet(TimeValue.timeValueSeconds(10)); |
| 365 | + |
| 366 | + PlainActionFuture<UpdateResponse> futureUpdate = new PlainActionFuture<>(); |
| 367 | + indexService.updateResponse( |
| 368 | + task.getExecutionId().getDocId(), |
| 369 | + emptyMap(), |
| 370 | + new TestAsyncResponse("final_response", task.getExpirationTime()), |
| 371 | + futureUpdate |
| 372 | + ); |
| 373 | + futureUpdate.actionGet(TimeValue.timeValueSeconds(10)); |
| 374 | + } finally { |
| 375 | + taskManager.unregister(task); |
| 376 | + } |
| 377 | + |
| 378 | + PlainActionFuture<TestAsyncResponse> listener = new PlainActionFuture<>(); |
| 379 | + // not waiting for completion, so should return immediately with timeout |
| 380 | + service.retrieveResult(new GetAsyncResultRequest(task.getExecutionId().getEncoded()), listener); |
| 381 | + assertFutureThrows(listener, IllegalArgumentException.class, RestStatus.BAD_REQUEST); |
| 382 | + } |
329 | 383 | } |
0 commit comments