package org.codelibs.elasticsearch.df.content.json;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import org.apache.logging.log4j.Logger;
import org.codelibs.elasticsearch.df.content.ContentType;
import org.codelibs.elasticsearch.df.content.DataContent;
import org.codelibs.elasticsearch.df.util.RequestUtil;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
public class JsonContent extends DataContent {
private static final Logger logger = Loggers.getLogger(JsonContent.class);
private final String bulkIndex;
private final String bulkType;
public JsonContent(final Client client, final RestRequest request, final ContentType contentType) {
super(client, request, contentType);
bulkIndex = request.param("bulk.index");
bulkType = request.param("bulk.type");
}
@Override
public void write(final File outputFile, final SearchResponse response, final RestChannel channel,
final ActionListener<Void> listener) {
try {
final OnLoadListener onLoadListener = new OnLoadListener(
outputFile, listener);
onLoadListener.onResponse(response);
} catch (final Exception e) {
listener.onFailure(new ElasticsearchException("Failed to write data.",
e));
}
}
protected class OnLoadListener implements ActionListener<SearchResponse> {
protected ActionListener<Void> listener;
protected Writer writer;
protected File outputFile;
private long currentCount = 0;
protected OnLoadListener(final File outputFile, final ActionListener<Void> listener) {
this.outputFile = outputFile;
this.listener = listener;
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFile), "UTF-8"));
} catch (final Exception e) {
throw new ElasticsearchException("Could not open "
+ outputFile.getAbsolutePath(), e);
}
}
@Override
public void onResponse(final SearchResponse response) {
final String scrollId = response.getScrollId();
final SearchHits hits = response.getHits();
final int size = hits.getHits().length;
currentCount += size;
if (logger.isDebugEnabled()) {
logger.debug("scrollId: " + scrollId + ", totalHits: "
+ hits.totalHits() + ", hits: " + size + ", current: "
+ currentCount);
}
try {
for (final SearchHit hit : hits) {
final String index = bulkIndex == null ? hit.index()
: bulkIndex;
final String type = bulkType == null ? hit.type()
: bulkType;
final String operation = "{\"index\":{\"_index\":\""
+ index + "\",\"_type\":\"" + type
+ "\",\"_id\":\"" + hit.id() + "\"}}";
final String source = hit.sourceAsString();
writer.append(operation).append('\n');
writer.append(source).append('\n');
}
if (size == 0 || scrollId == null) {
// end
writer.flush();
close();
listener.onResponse(null);
} else {
client.prepareSearchScroll(scrollId)
.setScroll(RequestUtil.getScroll(request))
.execute(this);
}
} catch (final Exception e) {
onFailure(e);
}
}
@Override
public void onFailure(final Exception e) {
try {
close();
} catch (final Exception e1) {
// ignore
}
listener.onFailure(new ElasticsearchException("Failed to write data.",
e));
}
private void close() {
if (writer != null) {
try {
writer.close();
} catch (final IOException e) {
throw new ElasticsearchException("Could not close "
+ outputFile.getAbsolutePath(), e);
}
}
}
}
}