@Override public List<ActionRequest> doCall(Index index) { List<ActionRequest> inserts = new ArrayList<ActionRequest>(); List<UpdateRequest> updates = index.getNormalizer().normalize(dto); for (UpdateRequest update : updates) { if (update.doc() != null) { inserts.add( update .upsertRequest() .index(index.getIndexName()) .type(index.getIndexType()) .id(update.id()) .routing(update.routing())); } else { inserts.add(update.index(index.getIndexName()).type(index.getIndexType())); } } return inserts; }
@Override public void handleRequest(final RestRequest request, final RestChannel channel) { UpdateRequest updateRequest = new UpdateRequest(request.param("index"), request.param("type"), request.param("id")); updateRequest.listenerThreaded(false); updateRequest.routing(request.param("routing")); updateRequest.parent( request.param( "parent")); // order is important, set it after routing, so it will set the routing updateRequest.timeout(request.paramAsTime("timeout", updateRequest.timeout())); updateRequest.refresh(request.paramAsBoolean("refresh", updateRequest.refresh())); String replicationType = request.param("replication"); if (replicationType != null) { updateRequest.replicationType(ReplicationType.fromString(replicationType)); } String consistencyLevel = request.param("consistency"); if (consistencyLevel != null) { updateRequest.consistencyLevel(WriteConsistencyLevel.fromString(consistencyLevel)); } updateRequest.percolate(request.param("percolate", null)); updateRequest.script(request.param("script")); updateRequest.scriptLang(request.param("lang")); for (Map.Entry<String, String> entry : request.params().entrySet()) { if (entry.getKey().startsWith("sp_")) { updateRequest.addScriptParam(entry.getKey().substring(3), entry.getValue()); } } String sField = request.param("fields"); if (sField != null) { String[] sFields = Strings.splitStringByCommaToArray(sField); if (sFields != null) { updateRequest.fields(sFields); } } updateRequest.retryOnConflict( request.paramAsInt("retry_on_conflict", updateRequest.retryOnConflict())); // see if we have it in the body if (request.hasContent()) { try { updateRequest.source( request.contentByteArray(), request.contentByteArrayOffset(), request.contentLength()); IndexRequest upsertRequest = updateRequest.upsertRequest(); if (upsertRequest != null) { upsertRequest.routing(request.param("routing")); upsertRequest.parent( request.param( "parent")); // order is important, set it after routing, so it will set the // routing upsertRequest.timestamp(request.param("timestamp")); if (request.hasParam("ttl")) { upsertRequest.ttl(request.paramAsTime("ttl", null).millis()); } upsertRequest.version(RestActions.parseVersion(request)); upsertRequest.versionType( VersionType.fromString(request.param("version_type"), upsertRequest.versionType())); } IndexRequest doc = updateRequest.doc(); if (doc != null) { doc.routing(request.param("routing")); doc.parent( request.param( "parent")); // order is important, set it after routing, so it will set the // routing doc.timestamp(request.param("timestamp")); if (request.hasParam("ttl")) { doc.ttl(request.paramAsTime("ttl", null).millis()); } doc.version(RestActions.parseVersion(request)); doc.versionType(VersionType.fromString(request.param("version_type"), doc.versionType())); } } catch (Exception e) { try { channel.sendResponse(new XContentThrowableRestResponse(request, e)); } catch (IOException e1) { logger.warn("Failed to send response", e1); } return; } } client.update( updateRequest, new ActionListener<UpdateResponse>() { @Override public void onResponse(UpdateResponse response) { try { XContentBuilder builder = RestXContentBuilder.restContentBuilder(request); builder .startObject() .field(Fields.OK, true) .field(Fields._INDEX, response.index()) .field(Fields._TYPE, response.type()) .field(Fields._ID, response.id()) .field(Fields._VERSION, response.version()); if (response.getResult() != null) { builder.startObject(Fields.GET); response.getResult().toXContentEmbedded(builder, request); builder.endObject(); } if (response.matches() != null) { builder.startArray(Fields.MATCHES); for (String match : response.matches()) { builder.value(match); } builder.endArray(); } builder.endObject(); RestStatus status = OK; if (response.version() == 1) { status = CREATED; } channel.sendResponse(new XContentRestResponse(request, status, builder)); } catch (Exception e) { onFailure(e); } } @Override public void onFailure(Throwable e) { try { channel.sendResponse(new XContentThrowableRestResponse(request, e)); } catch (IOException e1) { logger.error("Failed to send failure response", e1); } } }); }
@Test public void testUpdateRequest() throws Exception { UpdateRequest request = new UpdateRequest("test", "type", "1"); // simple script request.source( XContentFactory.jsonBuilder().startObject().field("script", "script1").endObject()); assertThat(request.script(), equalTo("script1")); // script with params request = new UpdateRequest("test", "type", "1"); request.source( XContentFactory.jsonBuilder() .startObject() .field("script", "script1") .startObject("params") .field("param1", "value1") .endObject() .endObject()); assertThat(request.script(), equalTo("script1")); assertThat(request.scriptParams().get("param1").toString(), equalTo("value1")); request = new UpdateRequest("test", "type", "1"); request.source( XContentFactory.jsonBuilder() .startObject() .startObject("params") .field("param1", "value1") .endObject() .field("script", "script1") .endObject()); assertThat(request.script(), equalTo("script1")); assertThat(request.scriptParams().get("param1").toString(), equalTo("value1")); // script with params and upsert request = new UpdateRequest("test", "type", "1"); request.source( XContentFactory.jsonBuilder() .startObject() .startObject("params") .field("param1", "value1") .endObject() .field("script", "script1") .startObject("upsert") .field("field1", "value1") .startObject("compound") .field("field2", "value2") .endObject() .endObject() .endObject()); assertThat(request.script(), equalTo("script1")); assertThat(request.scriptParams().get("param1").toString(), equalTo("value1")); Map<String, Object> upsertDoc = XContentHelper.convertToMap(request.upsertRequest().source(), true).v2(); assertThat(upsertDoc.get("field1").toString(), equalTo("value1")); assertThat(((Map) upsertDoc.get("compound")).get("field2").toString(), equalTo("value2")); request = new UpdateRequest("test", "type", "1"); request.source( XContentFactory.jsonBuilder() .startObject() .startObject("upsert") .field("field1", "value1") .startObject("compound") .field("field2", "value2") .endObject() .endObject() .startObject("params") .field("param1", "value1") .endObject() .field("script", "script1") .endObject()); assertThat(request.script(), equalTo("script1")); assertThat(request.scriptParams().get("param1").toString(), equalTo("value1")); upsertDoc = XContentHelper.convertToMap(request.upsertRequest().source(), true).v2(); assertThat(upsertDoc.get("field1").toString(), equalTo("value1")); assertThat(((Map) upsertDoc.get("compound")).get("field2").toString(), equalTo("value2")); request = new UpdateRequest("test", "type", "1"); request.source( XContentFactory.jsonBuilder() .startObject() .startObject("params") .field("param1", "value1") .endObject() .startObject("upsert") .field("field1", "value1") .startObject("compound") .field("field2", "value2") .endObject() .endObject() .field("script", "script1") .endObject()); assertThat(request.script(), equalTo("script1")); assertThat(request.scriptParams().get("param1").toString(), equalTo("value1")); upsertDoc = XContentHelper.convertToMap(request.upsertRequest().source(), true).v2(); assertThat(upsertDoc.get("field1").toString(), equalTo("value1")); assertThat(((Map) upsertDoc.get("compound")).get("field2").toString(), equalTo("value2")); // script with doc request = new UpdateRequest("test", "type", "1"); request.source( XContentFactory.jsonBuilder() .startObject() .startObject("doc") .field("field1", "value1") .startObject("compound") .field("field2", "value2") .endObject() .endObject() .endObject()); Map<String, Object> doc = request.doc().sourceAsMap(); assertThat(doc.get("field1").toString(), equalTo("value1")); assertThat(((Map) doc.get("compound")).get("field2").toString(), equalTo("value2")); }
@Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { UpdateRequest updateRequest = new UpdateRequest(request.param("index"), request.param("type"), request.param("id")); updateRequest.routing(request.param("routing")); updateRequest.parent(request.param("parent")); updateRequest.timeout(request.paramAsTime("timeout", updateRequest.timeout())); updateRequest.setRefreshPolicy(request.param("refresh")); String waitForActiveShards = request.param("wait_for_active_shards"); if (waitForActiveShards != null) { updateRequest.waitForActiveShards(ActiveShardCount.parseString(waitForActiveShards)); } updateRequest.docAsUpsert(request.paramAsBoolean("doc_as_upsert", updateRequest.docAsUpsert())); FetchSourceContext fetchSourceContext = FetchSourceContext.parseFromRestRequest(request); String sField = request.param("fields"); if (sField != null && fetchSourceContext != null) { throw new IllegalArgumentException( "[fields] and [_source] cannot be used in the same request"); } if (sField != null) { DEPRECATION_LOGGER.deprecated("Deprecated field [fields] used, expected [_source] instead"); String[] sFields = Strings.splitStringByCommaToArray(sField); updateRequest.fields(sFields); } else if (fetchSourceContext != null) { updateRequest.fetchSource(fetchSourceContext); } updateRequest.retryOnConflict( request.paramAsInt("retry_on_conflict", updateRequest.retryOnConflict())); updateRequest.version(RestActions.parseVersion(request)); updateRequest.versionType( VersionType.fromString(request.param("version_type"), updateRequest.versionType())); // see if we have it in the body if (request.hasContent()) { updateRequest.fromXContent(request.content()); IndexRequest upsertRequest = updateRequest.upsertRequest(); if (upsertRequest != null) { upsertRequest.routing(request.param("routing")); upsertRequest.parent( request.param( "parent")); // order is important, set it after routing, so it will set the routing upsertRequest.timestamp(request.param("timestamp")); if (request.hasParam("ttl")) { upsertRequest.ttl(request.param("ttl")); } upsertRequest.version(RestActions.parseVersion(request)); upsertRequest.versionType( VersionType.fromString(request.param("version_type"), upsertRequest.versionType())); } IndexRequest doc = updateRequest.doc(); if (doc != null) { doc.routing(request.param("routing")); doc.parent( request.param( "parent")); // order is important, set it after routing, so it will set the routing doc.timestamp(request.param("timestamp")); if (request.hasParam("ttl")) { doc.ttl(request.param("ttl")); } doc.version(RestActions.parseVersion(request)); doc.versionType(VersionType.fromString(request.param("version_type"), doc.versionType())); } } return channel -> client.update( updateRequest, new RestStatusToXContentListener<>( channel, r -> r.getLocation(updateRequest.routing()))); }