package net.iponweb.disthene.reader.service.index;
import com.google.common.base.Joiner;
import net.iponweb.disthene.reader.config.IndexConfiguration;
import net.iponweb.disthene.reader.utils.WildcardUtil;
import org.apache.log4j.Logger;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Andrei Ivanov
*/
public class IndexService {
final static Logger logger = Logger.getLogger(IndexService.class);
private IndexConfiguration indexConfiguration;
private TransportClient client;
private Joiner joiner = Joiner.on(",").skipNulls();
public IndexService(IndexConfiguration indexConfiguration) {
this.indexConfiguration = indexConfiguration;
Settings settings = ImmutableSettings.settingsBuilder()
.put("cluster.name", indexConfiguration.getName())
.build();
client = new TransportClient(settings);
for (String node : indexConfiguration.getCluster()) {
client.addTransportAddress(new InetSocketTransportAddress(node, indexConfiguration.getPort()));
}
}
public List<String> getPaths(String tenant, List<String> wildcards) {
List<String> regExs = new ArrayList<>();
List<String> result = new ArrayList<>();
for(String wildcard : wildcards) {
if (WildcardUtil.isPlainPath(wildcard)) {
result.add(wildcard);
} else {
regExs.add(WildcardUtil.getPathsRegExFromWildcard(wildcard));
}
}
logger.debug("getPaths plain paths: " + result.size() + ", wildcard paths: " + regExs.size());
if (regExs.size() > 0) {
String regEx = Joiner.on("|").skipNulls().join(regExs);
SearchResponse response = client.prepareSearch(indexConfiguration.getIndex())
.setScroll(new TimeValue(indexConfiguration.getTimeout()))
.setSize(indexConfiguration.getScroll())
.setQuery(QueryBuilders.filteredQuery(QueryBuilders.regexpQuery("path", regEx),
FilterBuilders.termFilter("tenant", tenant)))
.addField("path")
.execute().actionGet();
// if total hits exceeds maximum - abort right away returning empty array
if (response.getHits().totalHits() > indexConfiguration.getMaxPaths()) {
return Collections.emptyList();
}
while (response.getHits().getHits().length > 0) {
for (SearchHit hit : response.getHits()) {
result.add((String) hit.field("path").getValue());
}
response = client.prepareSearchScroll(response.getScrollId())
.setScroll(new TimeValue(indexConfiguration.getTimeout()))
.execute().actionGet();
}
}
return result;
}
public String getPathsAsJsonArray(String tenant, String wildcard) {
String regEx = WildcardUtil.getPathsRegExFromWildcard(wildcard);
SearchResponse response = client.prepareSearch(indexConfiguration.getIndex())
.setScroll(new TimeValue(indexConfiguration.getTimeout()))
.setSize(indexConfiguration.getScroll())
.setQuery(QueryBuilders.filteredQuery(
QueryBuilders.regexpQuery("path", regEx),
FilterBuilders.termFilter("tenant", tenant)))
.execute().actionGet();
// if total hits exceeds maximum - abort right away returning empty array
if (response.getHits().totalHits() > indexConfiguration.getMaxPaths()) {
return "[]";
}
List<String> paths = new ArrayList<>();
while (response.getHits().getHits().length > 0) {
for (SearchHit hit : response.getHits()) {
paths.add(hit.getSourceAsString());
}
response = client.prepareSearchScroll(response.getScrollId())
.setScroll(new TimeValue(indexConfiguration.getTimeout()))
.execute().actionGet();
}
return "[" + joiner.join(paths) + "]";
}
public String getSearchPathsAsString(String tenant, String regEx, int limit) {
SearchResponse response = client.prepareSearch(indexConfiguration.getIndex())
.setScroll(new TimeValue(indexConfiguration.getTimeout()))
.setSize(limit)
.setQuery(QueryBuilders.filteredQuery(
QueryBuilders.regexpQuery("path", regEx),
FilterBuilders.termFilter("tenant", tenant)))
.addField("path")
.execute().actionGet();
List<String> paths = new ArrayList<>();
for (SearchHit hit : response.getHits()) {
paths.add((String) hit.field("path").getValue());
}
return Joiner.on(",").skipNulls().join(paths);
}
public void shutdown() {
client.close();
}
}