package com.github.obourgain.elasticsearch.http.handler.document.multiget;
import java.io.IOException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.get.GetAction;
import org.elasticsearch.action.get.MultiGetRequest;
import org.elasticsearch.common.lucene.uid.Versions;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.VersionType;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
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 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 MultiGetActionHandler {
private static final Logger logger = LoggerFactory.getLogger(MultiGetActionHandler.class);
private final HttpClient httpClient;
public MultiGetActionHandler(HttpClient httpClient) {
this.httpClient = httpClient;
}
public GetAction getAction() {
return GetAction.INSTANCE;
}
public void execute(final MultiGetRequest request, final ActionListener<MultiGetResponse> listener) {
logger.debug("multi get request {}", request);
try {
RequestUriBuilder uriBuilder = new RequestUriBuilder().addEndpoint("_mget");
uriBuilder.addQueryParameter("ignore_errors_on_generated_fields", request.ignoreErrorsOnGeneratedFields);
uriBuilder.addQueryParameterIfNotNull("preference", request.preference());
uriBuilder.addQueryParameterIfNotNull("refresh", request.refresh());
uriBuilder.addQueryParameterIfNotNull("realtime", request.realtime());
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject().field("docs").startArray();
for (MultiGetRequest.Item item : request.getItems()) {
writeItem(builder, item);
}
builder.endArray().endObject();
httpClient.getHttpClient().submit(HttpClientRequest.createPost(uriBuilder.toString())
.withContent(builder.bytes().toBytes()))
.flatMap(ErrorHandler.AS_FUNC)
.flatMap(new Func1<HttpClientResponse<ByteBuf>, Observable<MultiGetResponse>>() {
@Override
public Observable<MultiGetResponse> call(HttpClientResponse<ByteBuf> response) {
return response.getContent().flatMap(new Func1<ByteBuf, Observable<MultiGetResponse>>() {
@Override
public Observable<MultiGetResponse> call(ByteBuf byteBuf) {
return MultiGetResponse.parse(byteBuf);
}
});
}
})
.single()
.subscribe(new ListenerCompleterObserver<>(listener));
} catch (Exception e) {
listener.onFailure(e);
}
}
private void writeItem(XContentBuilder builder, MultiGetRequest.Item item) throws IOException {
builder.startObject();
builder.field("_index", item.index());
builder.field("_type", item.type());
builder.field("_id", item.id());
FetchSourceContext fetchSourceContext = item.fetchSourceContext();
if(fetchSourceContext != null) {
if(fetchSourceContext.fetchSource()) {
if(fetchSourceContext.includes().length != 0 | fetchSourceContext.excludes().length != 0) {
builder.startObject("_source");
if(fetchSourceContext.includes().length != 0) {
builder.array("include", fetchSourceContext.includes());
}
if(fetchSourceContext.excludes().length != 0) {
builder.array("exclude", fetchSourceContext.excludes());
}
builder.endObject();
}
} else {
builder.field("_source", false);
}
}
if(item.fields() != null && item.fields().length != 0) {
builder.array("fields", item.fields());
}
if(item.routing() != null) {
builder.array("_routing", item.routing());
}
if(item.indicesOptions() != null) {
builder.array("_routing", item.routing());
}
if(item.versionType() != VersionType.INTERNAL) {
builder.array("_version_type", item.versionType().name().toLowerCase());
}
if(item.version() != Versions.MATCH_ANY) {
builder.array("_version", item.version());
}
builder.endObject();
}
}