use of org.opensearch.index.engine.DocumentMissingException in project asynchronous-search by opensearch-project.
the class AsynchronousSearchPersistenceService method updateExpirationTime.
/**
* Updates the expiration time field in index
*
* @param id asynchronous search id
* @param expirationTimeMillis the new expiration time
* @param user current user
* @param listener listener invoked with the response on completion of update request
*/
@SuppressWarnings("unchecked")
public void updateExpirationTime(String id, long expirationTimeMillis, User user, ActionListener<AsynchronousSearchPersistenceModel> listener) {
if (indexExists() == false) {
listener.onFailure(new ResourceNotFoundException(id));
return;
}
UpdateRequest updateRequest = new UpdateRequest(ASYNC_SEARCH_RESPONSE_INDEX, id);
updateRequest.retryOnConflict(5);
if (user == null) {
Map<String, Object> source = new HashMap<>();
source.put(EXPIRATION_TIME_MILLIS, expirationTimeMillis);
updateRequest.doc(source, XContentType.JSON);
} else {
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._source.expiration_time_millis = params.expiration_time_millis } else { ctx.op = 'none' }";
Map<String, Object> params = new HashMap<>();
params.put(BACKEND_ROLES, user.getBackendRoles());
params.put(EXPIRATION_TIME_MILLIS, expirationTimeMillis);
Script conditionalUpdateScript = new Script(ScriptType.INLINE, "painless", scriptCode, params);
updateRequest.script(conditionalUpdateScript);
}
updateRequest.fetchSource(FetchSourceContext.FETCH_SOURCE);
client.update(updateRequest, ActionListener.wrap(updateResponse -> {
switch(updateResponse.getResult()) {
case NOOP:
if (user != null) {
listener.onFailure(new OpenSearchSecurityException("User doesn't have necessary roles to access the asynchronous search with id " + id, RestStatus.FORBIDDEN));
} else {
Map<String, Object> updatedSource = updateResponse.getGetResult().getSource();
listener.onResponse(new AsynchronousSearchPersistenceModel((long) updatedSource.get(START_TIME_MILLIS), (long) updatedSource.get(EXPIRATION_TIME_MILLIS), (String) updatedSource.get(RESPONSE), (String) updatedSource.get(ERROR), parseUser((Map<String, Object>) updatedSource.get(USER))));
}
break;
case UPDATED:
Map<String, Object> updatedSource = updateResponse.getGetResult().getSource();
listener.onResponse(new AsynchronousSearchPersistenceModel((long) updatedSource.get(START_TIME_MILLIS), (long) updatedSource.get(EXPIRATION_TIME_MILLIS), (String) updatedSource.get(RESPONSE), (String) updatedSource.get(ERROR), parseUser((Map<String, Object>) updatedSource.get(USER))));
break;
case NOT_FOUND:
case DELETED:
logger.debug("Update Result [{}] for id [{}], expiration time requested, [{}]", updateResponse.getResult(), id, expirationTimeMillis);
listener.onFailure(new ResourceNotFoundException(id));
break;
}
}, exception -> {
final Throwable cause = ExceptionsHelper.unwrapCause(exception);
if (cause instanceof DocumentMissingException) {
listener.onFailure(new ResourceNotFoundException(id));
} else {
logger.error(() -> new ParameterizedMessage("Exception occurred updating expiration time for asynchronous search [{}]", id), exception);
listener.onFailure(cause instanceof Exception ? (Exception) cause : new NotSerializableExceptionWrapper(cause));
}
}));
}
use of org.opensearch.index.engine.DocumentMissingException 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.index.engine.DocumentMissingException in project OpenSearch by opensearch-project.
the class UpdateIT method testUpdate.
public void testUpdate() throws Exception {
assertAcked(prepareCreate("test").addAlias(new Alias("alias").writeIndex(true)));
assertAcked(prepareCreate("test2").addAlias(new Alias("alias")));
ensureGreen();
Script fieldIncScript = new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field"));
DocumentMissingException ex = expectThrows(DocumentMissingException.class, () -> client().prepareUpdate(indexOrAlias(), "1").setScript(fieldIncScript).execute().actionGet());
assertEquals("[1]: document missing", ex.getMessage());
client().prepareIndex("test").setId("1").setSource("field", 1).execute().actionGet();
UpdateResponse updateResponse = client().prepareUpdate(indexOrAlias(), "1").setScript(fieldIncScript).execute().actionGet();
assertThat(updateResponse.getVersion(), equalTo(2L));
assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
assertThat(updateResponse.getIndex(), equalTo("test"));
for (int i = 0; i < 5; i++) {
GetResponse getResponse = client().prepareGet("test", "1").execute().actionGet();
assertThat(getResponse.getSourceAsMap().get("field").toString(), equalTo("2"));
}
Map<String, Object> params = new HashMap<>();
params.put("inc", 3);
params.put("field", "field");
updateResponse = client().prepareUpdate(indexOrAlias(), "1").setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, params)).execute().actionGet();
assertThat(updateResponse.getVersion(), equalTo(3L));
assertEquals(DocWriteResponse.Result.UPDATED, updateResponse.getResult());
assertThat(updateResponse.getIndex(), equalTo("test"));
for (int i = 0; i < 5; i++) {
GetResponse getResponse = client().prepareGet("test", "1").execute().actionGet();
assertThat(getResponse.getSourceAsMap().get("field").toString(), equalTo("5"));
}
// check noop
updateResponse = client().prepareUpdate(indexOrAlias(), "1").setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT, Collections.singletonMap("_ctx", Collections.singletonMap("op", "none")))).execute().actionGet();
assertThat(updateResponse.getVersion(), equalTo(3L));
assertEquals(DocWriteResponse.Result.NOOP, updateResponse.getResult());
assertThat(updateResponse.getIndex(), equalTo("test"));
for (int i = 0; i < 5; i++) {
GetResponse getResponse = client().prepareGet("test", "1").execute().actionGet();
assertThat(getResponse.getSourceAsMap().get("field").toString(), equalTo("5"));
}
// check delete
updateResponse = client().prepareUpdate(indexOrAlias(), "1").setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, PUT_VALUES_SCRIPT, Collections.singletonMap("_ctx", Collections.singletonMap("op", "delete")))).execute().actionGet();
assertThat(updateResponse.getVersion(), equalTo(4L));
assertEquals(DocWriteResponse.Result.DELETED, updateResponse.getResult());
assertThat(updateResponse.getIndex(), equalTo("test"));
for (int i = 0; i < 5; i++) {
GetResponse getResponse = client().prepareGet("test", "1").execute().actionGet();
assertThat(getResponse.isExists(), equalTo(false));
}
// check _source parameter
client().prepareIndex("test").setId("1").setSource("field1", 1, "field2", 2).execute().actionGet();
updateResponse = client().prepareUpdate(indexOrAlias(), "1").setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field1"))).setFetchSource("field1", "field2").get();
assertThat(updateResponse.getIndex(), equalTo("test"));
assertThat(updateResponse.getGetResult(), notNullValue());
assertThat(updateResponse.getGetResult().getIndex(), equalTo("test"));
assertThat(updateResponse.getGetResult().sourceRef(), notNullValue());
assertThat(updateResponse.getGetResult().field("field1"), nullValue());
assertThat(updateResponse.getGetResult().sourceAsMap().size(), equalTo(1));
assertThat(updateResponse.getGetResult().sourceAsMap().get("field1"), equalTo(2));
// check updates without script
// add new field
client().prepareIndex("test").setId("1").setSource("field", 1).execute().actionGet();
client().prepareUpdate(indexOrAlias(), "1").setDoc(XContentFactory.jsonBuilder().startObject().field("field2", 2).endObject()).execute().actionGet();
for (int i = 0; i < 5; i++) {
GetResponse getResponse = client().prepareGet("test", "1").execute().actionGet();
assertThat(getResponse.getSourceAsMap().get("field").toString(), equalTo("1"));
assertThat(getResponse.getSourceAsMap().get("field2").toString(), equalTo("2"));
}
// change existing field
client().prepareUpdate(indexOrAlias(), "1").setDoc(XContentFactory.jsonBuilder().startObject().field("field", 3).endObject()).execute().actionGet();
for (int i = 0; i < 5; i++) {
GetResponse getResponse = client().prepareGet("test", "1").execute().actionGet();
assertThat(getResponse.getSourceAsMap().get("field").toString(), equalTo("3"));
assertThat(getResponse.getSourceAsMap().get("field2").toString(), equalTo("2"));
}
// recursive map
Map<String, Object> testMap = new HashMap<>();
Map<String, Object> testMap2 = new HashMap<>();
Map<String, Object> testMap3 = new HashMap<>();
testMap3.put("commonkey", testMap);
testMap3.put("map3", 5);
testMap2.put("map2", 6);
testMap.put("commonkey", testMap2);
testMap.put("map1", 8);
client().prepareIndex("test").setId("1").setSource("map", testMap).execute().actionGet();
client().prepareUpdate(indexOrAlias(), "1").setDoc(XContentFactory.jsonBuilder().startObject().field("map", testMap3).endObject()).execute().actionGet();
for (int i = 0; i < 5; i++) {
GetResponse getResponse = client().prepareGet("test", "1").execute().actionGet();
Map map1 = (Map) getResponse.getSourceAsMap().get("map");
assertThat(map1.size(), equalTo(3));
assertThat(map1.containsKey("map1"), equalTo(true));
assertThat(map1.containsKey("map3"), equalTo(true));
assertThat(map1.containsKey("commonkey"), equalTo(true));
Map map2 = (Map) map1.get("commonkey");
assertThat(map2.size(), equalTo(3));
assertThat(map2.containsKey("map1"), equalTo(true));
assertThat(map2.containsKey("map2"), equalTo(true));
assertThat(map2.containsKey("commonkey"), equalTo(true));
}
}
use of org.opensearch.index.engine.DocumentMissingException in project OpenSearch by opensearch-project.
the class UpdateHelper method prepareUpsert.
/**
* Prepare the request for upsert, executing the upsert script if present, and returning a {@code Result} containing a new
* {@code IndexRequest} to be executed on the primary and replicas.
*/
Result prepareUpsert(ShardId shardId, UpdateRequest request, final GetResult getResult, LongSupplier nowInMillis) {
if (request.upsertRequest() == null && !request.docAsUpsert()) {
throw new DocumentMissingException(shardId, request.id());
}
IndexRequest indexRequest = request.docAsUpsert() ? request.doc() : request.upsertRequest();
if (request.scriptedUpsert() && request.script() != null) {
// Run the script to perform the create logic
IndexRequest upsert = request.upsertRequest();
Tuple<UpdateOpType, Map<String, Object>> upsertResult = executeScriptedUpsert(upsert.sourceAsMap(), request.script, nowInMillis);
switch(upsertResult.v1()) {
case CREATE:
indexRequest = Requests.indexRequest(request.index()).source(upsertResult.v2());
break;
case NONE:
UpdateResponse update = new UpdateResponse(shardId, getResult.getId(), getResult.getSeqNo(), getResult.getPrimaryTerm(), getResult.getVersion(), DocWriteResponse.Result.NOOP);
update.setGetResult(getResult);
return new Result(update, DocWriteResponse.Result.NOOP, upsertResult.v2(), XContentType.JSON);
default:
// It's fine to throw an exception here, the leniency is handled/logged by `executeScriptedUpsert`
throw new IllegalArgumentException("unknown upsert operation, got: " + upsertResult.v1());
}
}
indexRequest.index(request.index()).id(request.id()).setRefreshPolicy(request.getRefreshPolicy()).routing(request.routing()).timeout(request.timeout()).waitForActiveShards(request.waitForActiveShards()).create(true);
if (request.versionType() != VersionType.INTERNAL) {
// in all but the internal versioning mode, we want to create the new document using the given version.
indexRequest.version(request.version()).versionType(request.versionType());
}
return new Result(indexRequest, DocWriteResponse.Result.CREATED, null, null);
}
use of org.opensearch.index.engine.DocumentMissingException in project job-scheduler by opensearch-project.
the class LockService method updateLock.
private void updateLock(final LockModel updateLock, ActionListener<LockModel> listener) {
try {
UpdateRequest updateRequest = new UpdateRequest().index(LOCK_INDEX_NAME).id(updateLock.getLockId()).setIfSeqNo(updateLock.getSeqNo()).setIfPrimaryTerm(updateLock.getPrimaryTerm()).doc(updateLock.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS)).fetchSource(true);
client.update(updateRequest, ActionListener.wrap(response -> listener.onResponse(new LockModel(updateLock, response.getSeqNo(), response.getPrimaryTerm())), exception -> {
if (exception instanceof VersionConflictEngineException) {
logger.debug("could not acquire lock {}", exception.getMessage());
}
if (exception instanceof DocumentMissingException) {
logger.debug("Document is deleted. This happens if the job is already removed and" + " this is the last run." + "{}", exception.getMessage());
}
if (exception instanceof IOException) {
logger.error("IOException occurred updating lock.", exception);
}
listener.onResponse(null);
}));
} catch (IOException e) {
logger.error("IOException occurred updating lock.", e);
listener.onResponse(null);
}
}
Aggregations