package com.github.obourgain.elasticsearch.http.handler.document.index; import java.net.URLEncoder; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.replication.ShardReplicationOperationRequest; import org.elasticsearch.common.lucene.uid.Versions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.obourgain.elasticsearch.http.client.HttpClient; import com.github.obourgain.elasticsearch.http.concurrent.ListenerCompleterObserver; import com.github.obourgain.elasticsearch.http.request.RequestUriBuilder; import com.github.obourgain.elasticsearch.http.response.ErrorHandler; import com.google.common.base.Charsets; import io.netty.buffer.ByteBuf; import io.reactivex.netty.protocol.http.client.HttpClientRequest; import io.reactivex.netty.protocol.http.client.HttpClientResponse; import rx.Observable; import rx.functions.Func1; /** * @author olivier bourgain */ public class IndexActionHandler { private static final Logger logger = LoggerFactory.getLogger(IndexActionHandler.class); private final HttpClient httpClient; public IndexActionHandler(HttpClient httpClient) { this.httpClient = httpClient; } public IndexAction getAction() { return IndexAction.INSTANCE; } public void execute(IndexRequest request, final ActionListener<IndexResponse> listener) { logger.debug("index request {}", request); try { String method; RequestUriBuilder uriBuilder; if (request.id() == null || request.id().length() == 0) { method = "POST"; uriBuilder = new RequestUriBuilder(request.index(), request.type()); } else { method = "PUT"; uriBuilder = new RequestUriBuilder(request.index(), request.type(), URLEncoder.encode(request.id(), Charsets.UTF_8.displayName())); } if (request.version() != Versions.MATCH_ANY) { uriBuilder.addQueryParameter("version", String.valueOf(request.version())); } uriBuilder.addVersionType(request.versionType()); if (request.opType() == IndexRequest.OpType.CREATE) { uriBuilder.addQueryParameter("op_type", "create"); } uriBuilder.addQueryParameterIfNotNull("routing", request.routing()); uriBuilder.addQueryParameterIfNotNull("parent", request.parent()); uriBuilder.addQueryParameterIfNotNull("timestamp", request.timestamp()); if (request.ttl() != -1) { uriBuilder.addQueryParameter("ttl", String.valueOf(request.ttl())); } uriBuilder.addConsistencyLevel(request.consistencyLevel()); if (request.refresh()) { uriBuilder.addQueryParameter("refresh", true); } if (request.timeout() != ShardReplicationOperationRequest.DEFAULT_TIMEOUT) { uriBuilder.addQueryParameter("timeout", request.timeout().toString()); } HttpClientRequest<ByteBuf> httpClientRequest; if (method.equals("POST")) { httpClientRequest = HttpClientRequest.createPost(uriBuilder.toString()); } else { httpClientRequest = HttpClientRequest.createPut(uriBuilder.toString()); } httpClient.getHttpClient().submit(httpClientRequest.withContent(request.source().toBytes())) .flatMap(ErrorHandler.AS_FUNC) .flatMap(new Func1<HttpClientResponse<ByteBuf>, Observable<IndexResponse>>() { @Override public Observable<IndexResponse> call(HttpClientResponse<ByteBuf> response) { return response.getContent().flatMap(new Func1<ByteBuf, Observable<IndexResponse>>() { @Override public Observable<IndexResponse> call(ByteBuf byteBuf) { return IndexResponse.parse(byteBuf); } }); } }) .single() .subscribe(new ListenerCompleterObserver<>(listener)); } catch (Exception e) { listener.onFailure(e); } } }