use of org.opensearch.ResourceNotFoundException in project asynchronous-search by opensearch-project.
the class GetAsynchronousSearchSingleNodeIT method assertConcurrentGetOrUpdates.
private void assertConcurrentGetOrUpdates(AsynchronousSearchResponse submitResponse, QuadConsumer<AtomicInteger, AtomicInteger, AtomicInteger, AtomicInteger> assertionConsumer, boolean update, int concurrentRuns, boolean retainResponse) throws InterruptedException {
AtomicInteger numGetSuccess = new AtomicInteger();
AtomicInteger numGetFailures = new AtomicInteger();
AtomicInteger numVersionConflictFailures = new AtomicInteger();
AtomicInteger numResourceNotFoundFailures = new AtomicInteger();
AtomicInteger numTimeouts = new AtomicInteger();
TestThreadPool testThreadPool = null;
try {
testThreadPool = new TestThreadPool(GetAsynchronousSearchSingleNodeIT.class.getName());
int numThreads = concurrentRuns;
// 5 hours in millis
long lowerKeepAliveMillis = 5 * 1000 * 60 * 60;
// 10 hours in millis
long higherKeepAliveMillis = 10 * 1000 * 60 * 60;
List<Runnable> operationThreads = new ArrayList<>();
CountDownLatch countDownLatch = new CountDownLatch(numThreads);
for (int i = 0; i < numThreads; i++) {
long keepAlive = randomLongBetween(lowerKeepAliveMillis, higherKeepAliveMillis);
Runnable thread = () -> {
GetAsynchronousSearchRequest getAsynchronousSearchRequest = new GetAsynchronousSearchRequest(submitResponse.getId());
long requestedTime = System.currentTimeMillis() + keepAlive;
if (update) {
logger.info("Triggering asynchronous search gets with keep alive [{}] --->", requestedTime);
getAsynchronousSearchRequest.setKeepAlive(TimeValue.timeValueMillis(keepAlive));
}
getAsynchronousSearchRequest.setWaitForCompletionTimeout(TimeValue.timeValueMillis(randomLongBetween(1, 5000)));
executeGetAsynchronousSearch(client(), getAsynchronousSearchRequest, new LatchedActionListener<>(new ActionListener<AsynchronousSearchResponse>() {
@Override
public void onResponse(AsynchronousSearchResponse asResponse) {
if (update) {
// while updates we can run into version conflicts and hence the comparison is on the successful
// response. Since the final keep alive is calculated based on the current time of the server
// active contexts's expiration in memory are superseded by later writer so we are keeping a loose
// check
assertThat(asResponse.getExpirationTimeMillis(), greaterThanOrEqualTo(System.currentTimeMillis() + lowerKeepAliveMillis));
assertThat(asResponse.getExpirationTimeMillis(), lessThanOrEqualTo(System.currentTimeMillis() + higherKeepAliveMillis));
}
numGetSuccess.incrementAndGet();
}
@Override
public void onFailure(Exception e) {
if (e instanceof VersionConflictEngineException) {
numVersionConflictFailures.incrementAndGet();
} else if (e instanceof ResourceNotFoundException) {
numResourceNotFoundFailures.incrementAndGet();
} else if (e instanceof OpenSearchTimeoutException) {
numTimeouts.incrementAndGet();
} else {
numGetFailures.incrementAndGet();
}
}
}, countDownLatch));
};
operationThreads.add(thread);
}
TestThreadPool finalTestThreadPool = testThreadPool;
operationThreads.forEach(runnable -> finalTestThreadPool.executor("generic").execute(runnable));
countDownLatch.await();
if (retainResponse) {
DeleteAsynchronousSearchRequest deleteAsynchronousSearchRequest = new DeleteAsynchronousSearchRequest(submitResponse.getId());
executeDeleteAsynchronousSearch(client(), deleteAsynchronousSearchRequest).actionGet();
}
if (retainResponse && update) {
assertionConsumer.apply(numGetSuccess, numGetFailures, numVersionConflictFailures, numTimeouts);
} else {
assertionConsumer.apply(numGetSuccess, numGetFailures, numVersionConflictFailures, numResourceNotFoundFailures);
}
} finally {
ThreadPool.terminate(testThreadPool, 500, TimeUnit.MILLISECONDS);
}
}
use of org.opensearch.ResourceNotFoundException in project asynchronous-search by opensearch-project.
the class AsynchronousSearchPersistenceService method deleteResponse.
/**
* This method should be safe to call even if there isn't a prior document that exists. If the doc was actually deleted, the listener
* returns true
*
* @param id asynchronous search id
* @param user current user
* @param listener invoked once delete document request completes.
*/
public void deleteResponse(String id, User user, ActionListener<Boolean> listener) {
if (indexExists() == false) {
logger.debug("Async search index [{}] doesn't exists", ASYNC_SEARCH_RESPONSE_INDEX);
listener.onFailure(new ResourceNotFoundException(id));
return;
}
Consumer<Exception> onFailure = e -> {
final Throwable cause = ExceptionsHelper.unwrapCause(e);
if (cause instanceof DocumentMissingException) {
logger.debug(() -> new ParameterizedMessage("Async search response doc already deleted {}", id), e);
listener.onFailure(new ResourceNotFoundException(id));
} else {
logger.debug(() -> new ParameterizedMessage("Failed to delete asynchronous search for id {}", id), e);
listener.onFailure(cause instanceof Exception ? (Exception) cause : new NotSerializableExceptionWrapper(cause));
}
};
if (user == null) {
client.delete(new DeleteRequest(ASYNC_SEARCH_RESPONSE_INDEX, id), ActionListener.wrap(deleteResponse -> {
if (deleteResponse.getResult() == DocWriteResponse.Result.DELETED) {
logger.debug("Delete asynchronous search {} successful. Returned result {}", id, deleteResponse.getResult());
listener.onResponse(true);
} else {
logger.debug("Delete asynchronous search {} unsuccessful. Returned result {}", id, deleteResponse.getResult());
listener.onFailure(new ResourceNotFoundException(id));
}
}, onFailure));
} else {
UpdateRequest updateRequest = new UpdateRequest(ASYNC_SEARCH_RESPONSE_INDEX, id);
String scriptCode = "if (ctx._source.user == null || ctx._source.user.backend_roles == null || " + "( params.backend_roles!=null && params.backend_roles.containsAll(ctx._source.user.backend_roles))) " + "{ ctx.op = 'delete' } else { ctx.op = 'none' }";
Map<String, Object> params = new HashMap<>();
params.put("backend_roles", user.getBackendRoles());
Script deleteConditionallyScript = new Script(ScriptType.INLINE, "painless", scriptCode, params);
updateRequest.script(deleteConditionallyScript);
client.update(updateRequest, ActionListener.wrap(deleteResponse -> {
switch(deleteResponse.getResult()) {
case UPDATED:
listener.onFailure(new IllegalStateException("Document updated when requesting delete for asynchronous search id " + id));
break;
case NOOP:
listener.onFailure(new OpenSearchSecurityException("User doesn't have necessary roles to access the asynchronous search with id " + id, RestStatus.FORBIDDEN));
break;
case NOT_FOUND:
listener.onFailure(new ResourceNotFoundException(id));
break;
case DELETED:
listener.onResponse(true);
break;
}
}, onFailure));
}
}
use of org.opensearch.ResourceNotFoundException in project asynchronous-search by opensearch-project.
the class AsynchronousSearchServiceFreeContextTests method testFreeContextPermitAcquisitionFailure.
public void testFreeContextPermitAcquisitionFailure() throws InterruptedException {
DiscoveryNode discoveryNode = new DiscoveryNode("node", OpenSearchTestCase.buildNewFakeTransportAddress(), emptyMap(), DiscoveryNodeRole.BUILT_IN_ROLES, Version.CURRENT);
ThreadPool testThreadPool = null;
try {
testThreadPool = new TestThreadPool(OPEN_DISTRO_ASYNC_SEARCH_GENERIC_THREAD_POOL_NAME, executorBuilder);
ClusterService mockClusterService = getClusterService(discoveryNode, testThreadPool);
MockClient mockClient = new MockClient(testThreadPool);
AsynchronousSearchActiveStore mockStore = mock(AsynchronousSearchActiveStore.class);
AsynchronousSearchPersistenceService persistenceService = new AsynchronousSearchPersistenceService(mockClient, mockClusterService, testThreadPool);
AsynchronousSearchService asService = new AsynchronousSearchService(persistenceService, mockStore, mockClient, mockClusterService, testThreadPool, new InternalAsynchronousSearchStats(), new NamedWriteableRegistry(emptyList()));
TimeValue keepAlive = timeValueDays(9);
boolean keepOnCompletion = true;
User user1 = randomBoolean() ? randomUser() : null;
SearchRequest searchRequest = new SearchRequest();
SubmitAsynchronousSearchRequest submitAsynchronousSearchRequest = new SubmitAsynchronousSearchRequest(searchRequest);
submitAsynchronousSearchRequest.keepOnCompletion(keepOnCompletion);
submitAsynchronousSearchRequest.keepAlive(keepAlive);
AsynchronousSearchProgressListener asProgressListener = mockAsynchronousSearchProgressListener(testThreadPool);
AsynchronousSearchContextId asContextId = new AsynchronousSearchContextId(UUID.randomUUID().toString(), randomNonNegativeLong());
MockAsynchronousSearchActiveContext asActiveContext = new MockAsynchronousSearchActiveContext(asContextId, discoveryNode.getId(), keepAlive, true, testThreadPool, testThreadPool::absoluteTimeInMillis, asProgressListener, user1);
// bootstrap search
AsynchronousSearchTask task = new AsynchronousSearchTask(randomNonNegativeLong(), "transport", SearchAction.NAME, TaskId.EMPTY_TASK_ID, emptyMap(), asActiveContext, null, (c) -> {
});
asActiveContext.setTask(task);
simulateUncheckedException = true;
persisted = false;
when(mockStore.getContext(asContextId)).thenReturn(Optional.of(asActiveContext));
CountDownLatch latch = new CountDownLatch(1);
asService.freeContext(asActiveContext.getAsynchronousSearchId(), asActiveContext.getContextId(), null, new LatchedActionListener<>(wrap(r -> fail("Expected resource_not_found_exception. Got acknowledgement " + r), e -> {
assertTrue(e.getClass().getName(), e instanceof ResourceNotFoundException);
}), latch));
latch.await();
assertEquals(1, (int) mockClient.deleteCount);
mockClusterService.stop();
} finally {
ThreadPool.terminate(testThreadPool, 30, TimeUnit.SECONDS);
}
}
use of org.opensearch.ResourceNotFoundException in project asynchronous-search by opensearch-project.
the class AsynchronousSearchServiceFreeContextTests method testFreePersistedContextUserNotMatches.
public void testFreePersistedContextUserNotMatches() throws InterruptedException {
DiscoveryNode discoveryNode = new DiscoveryNode("node", OpenSearchTestCase.buildNewFakeTransportAddress(), emptyMap(), DiscoveryNodeRole.BUILT_IN_ROLES, Version.CURRENT);
ThreadPool testThreadPool = null;
try {
testThreadPool = new TestThreadPool(OPEN_DISTRO_ASYNC_SEARCH_GENERIC_THREAD_POOL_NAME, executorBuilder);
ClusterService mockClusterService = getClusterService(discoveryNode, testThreadPool);
MockClient mockClient = new MockClient(testThreadPool);
AsynchronousSearchActiveStore asActiveStore = new AsynchronousSearchActiveStore(mockClusterService);
AsynchronousSearchPersistenceService persistenceService = new AsynchronousSearchPersistenceService(mockClient, mockClusterService, testThreadPool);
AsynchronousSearchService asService = new AsynchronousSearchService(persistenceService, asActiveStore, mockClient, mockClusterService, testThreadPool, new InternalAsynchronousSearchStats(), new NamedWriteableRegistry(emptyList()));
AsynchronousSearchContextId asContextId = new AsynchronousSearchContextId(UUID.randomUUID().toString(), randomNonNegativeLong());
AsynchronousSearchId asId = new AsynchronousSearchId(discoveryNode.getId(), randomNonNegativeLong(), asContextId);
persisted = true;
userMatches = false;
CountDownLatch latch = new CountDownLatch(1);
asService.freeContext(AsynchronousSearchIdConverter.buildAsyncId(asId), asContextId, randomUser(), new LatchedActionListener<>(ActionListener.wrap(r -> {
fail("Expected resource_not_found_exception due to user mismatch security exception. received delete " + "acknowledgement : " + r);
}, e -> assertTrue("expected resource_not_found_exception got " + e.getClass().getName(), e instanceof ResourceNotFoundException)), latch));
latch.await();
mockClusterService.stop();
} finally {
ThreadPool.terminate(testThreadPool, 30, TimeUnit.SECONDS);
}
}
use of org.opensearch.ResourceNotFoundException in project asynchronous-search by opensearch-project.
the class AsynchronousSearchServiceTests method testFindContext.
public void testFindContext() throws InterruptedException {
DiscoveryNode discoveryNode = new DiscoveryNode("node", OpenSearchTestCase.buildNewFakeTransportAddress(), emptyMap(), DiscoveryNodeRole.BUILT_IN_ROLES, Version.CURRENT);
ThreadPool testThreadPool = null;
try {
testThreadPool = new TestThreadPool(AsynchronousSearchPlugin.OPEN_DISTRO_ASYNC_SEARCH_GENERIC_THREAD_POOL_NAME, executorBuilder);
ClusterService mockClusterService = TestUtils.createClusterService(settings, testThreadPool, discoveryNode, clusterSettings);
FakeClient fakeClient = new FakeClient(testThreadPool);
AsynchronousSearchActiveStore asActiveStore = new AsynchronousSearchActiveStore(mockClusterService);
AsynchronousSearchPersistenceService persistenceService = new AsynchronousSearchPersistenceService(fakeClient, mockClusterService, testThreadPool);
AsynchronousSearchService asService = new AsynchronousSearchService(persistenceService, asActiveStore, fakeClient, mockClusterService, testThreadPool, new InternalAsynchronousSearchStats(), new NamedWriteableRegistry(emptyList()));
TimeValue keepAlive = timeValueHours(9);
boolean keepOnCompletion = randomBoolean();
User user1 = TestClientUtils.randomUser();
User user2 = TestClientUtils.randomUser();
SearchRequest searchRequest = new SearchRequest();
SubmitAsynchronousSearchRequest submitAsynchronousSearchRequest = new SubmitAsynchronousSearchRequest(searchRequest);
submitAsynchronousSearchRequest.keepOnCompletion(keepOnCompletion);
submitAsynchronousSearchRequest.keepAlive(keepAlive);
AsynchronousSearchContext context = asService.createAndStoreContext(submitAsynchronousSearchRequest, System.currentTimeMillis(), () -> null, user1);
assertTrue(context instanceof AsynchronousSearchActiveContext);
AsynchronousSearchActiveContext asActiveContext = (AsynchronousSearchActiveContext) context;
assertNull(asActiveContext.getTask());
assertNull(asActiveContext.getAsynchronousSearchId());
assertEquals(asActiveContext.getAsynchronousSearchState(), AsynchronousSearchState.INIT);
assertEquals(asActiveContext.getUser(), user1);
// bootstrap search
AsynchronousSearchTask task = new AsynchronousSearchTask(randomNonNegativeLong(), "transport", SearchAction.NAME, TaskId.EMPTY_TASK_ID, emptyMap(), (AsynchronousSearchActiveContext) context, null, (c) -> {
});
asService.bootstrapSearch(task, context.getContextId());
assertEquals(asActiveContext.getTask(), task);
assertEquals(asActiveContext.getStartTimeMillis(), task.getStartTime());
assertEquals(asActiveContext.getExpirationTimeMillis(), task.getStartTime() + keepAlive.millis());
assertEquals(asActiveContext.getAsynchronousSearchState(), AsynchronousSearchState.RUNNING);
CountDownLatch findContextLatch = new CountDownLatch(3);
ActionListener<AsynchronousSearchContext> expectedSuccessfulActive = new LatchedActionListener<>(wrap(r -> {
assertTrue(r instanceof AsynchronousSearchActiveContext);
assertEquals(r, context);
}, e -> fail("Find context shouldn't have failed. " + e.getMessage())), findContextLatch);
ActionListener<AsynchronousSearchContext> expectedSecurityException = new LatchedActionListener<>(wrap(r -> fail("Expecting security exception"), e -> assertTrue(e instanceof ResourceNotFoundException)), findContextLatch);
asService.findContext(asActiveContext.getAsynchronousSearchId(), asActiveContext.getContextId(), user1, expectedSuccessfulActive);
asService.findContext(asActiveContext.getAsynchronousSearchId(), asActiveContext.getContextId(), user2, expectedSecurityException);
asService.findContext(asActiveContext.getAsynchronousSearchId(), asActiveContext.getContextId(), null, expectedSuccessfulActive);
findContextLatch.await();
AsynchronousSearchProgressListener asProgressListener = asActiveContext.getAsynchronousSearchProgressListener();
boolean success = randomBoolean();
if (success) {
// successful search response
asProgressListener.onResponse(getMockSearchResponse());
} else {
// exception occurred in search
asProgressListener.onFailure(new RuntimeException("test"));
}
waitUntil(() -> asService.getAllActiveContexts().isEmpty());
if (keepOnCompletion) {
// persist to disk
assertEquals(1, fakeClient.persistenceCount.intValue());
} else {
assertEquals(fakeClient.persistenceCount, Integer.valueOf(0));
CountDownLatch freeContextLatch = new CountDownLatch(1);
asService.findContext(context.getAsynchronousSearchId(), context.getContextId(), null, new LatchedActionListener<>(wrap(r -> fail("No context should have been found but found " + asService.getAllActiveContexts().size()), e -> assertTrue(e instanceof ResourceNotFoundException)), freeContextLatch));
freeContextLatch.await();
}
} finally {
ThreadPool.terminate(testThreadPool, 200, TimeUnit.MILLISECONDS);
}
}
Aggregations