package org.xbib.elasticsearch.action.gatherer;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.nodes.TransportNodesOperationAction;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.hppc.ObjectOpenHashSet;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.node.service.NodeService;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.xbib.elasticsearch.gatherer.GathererConstants;
import java.util.SortedSet;
import java.util.concurrent.atomic.AtomicReferenceArray;
import static org.elasticsearch.common.collect.Sets.newTreeSet;
public class TransportGathererAction extends TransportNodesOperationAction<GathererRequest, GathererResponse, GathererNodeRequest, GathererNodeResponse> {
private final NodeService nodeService;
private GathererRequest request;
@Inject
public TransportGathererAction(Settings settings, ClusterName clusterName, ThreadPool threadPool,
ClusterService clusterService, TransportService transportService,
NodeService nodeService) {
super(settings, clusterName, threadPool, clusterService, transportService);
this.nodeService = nodeService;
}
@Override
protected String transportAction() {
return GathererAction.NAME;
}
@Override
protected String executor() {
return ThreadPool.Names.MANAGEMENT;
}
@Override
protected GathererRequest newRequest() {
return new GathererRequest();
}
@Override
protected GathererResponse newResponse(GathererRequest request, AtomicReferenceArray nodesResponses) {
return null;
}
@Override
protected GathererNodeRequest newNodeRequest() {
return new GathererNodeRequest();
}
@Override
protected GathererNodeRequest newNodeRequest(String nodeId, GathererRequest request) {
return new GathererNodeRequest(nodeId, request);
}
@Override
protected GathererNodeResponse newNodeResponse() {
return new GathererNodeResponse();
}
@Override
protected GathererNodeResponse nodeOperation(GathererNodeRequest request) throws ElasticSearchException {
GathererNodeResponse response = new GathererNodeResponse();
return response;
}
@Override
protected boolean accumulateExceptions() {
return false;
}
@Override
protected void doExecute(GathererRequest request, ActionListener<GathererResponse> listener) {
this.request = request;
super.doExecute(request, listener);
}
@Override
protected String[] filterNodeIds(DiscoveryNodes nodes, String[] nodesIds) {
// select one node with least system load
if (request.getLeastBusy()) {
// filter out all nodes that have gatherer load set
SortedSet<WeightedDiscoveryNode> set = newTreeSet();
for (DiscoveryNode node : nodes) {
String s = node.attributes().get(GathererConstants.GATHERER_LOAD);
if (s != null) {
set.add(new WeightedDiscoveryNode(node, s));
}
}
return new String[] { set.first().node.getId() };
} else if (request.getMinimumLength()) {
// filter out all nodes that have gatherer queue length set
SortedSet<WeightedDiscoveryNode> set = newTreeSet();
for (DiscoveryNode node : nodes) {
String s = node.attributes().get(GathererConstants.GATHERER_LENGTH);
if (s != null) {
set.add(new WeightedDiscoveryNode(node, s));
}
}
return new String[] { set.first().node.getId() };
} else {
ObjectOpenHashSet<String> filteredNodesIds = new ObjectOpenHashSet<String>();
for (DiscoveryNode node : nodes) {
filteredNodesIds.add(node.getId());
}
return filteredNodesIds.toArray(String.class);
}
}
class WeightedDiscoveryNode implements Comparable<WeightedDiscoveryNode> {
DiscoveryNode node;
Double weight;
WeightedDiscoveryNode(DiscoveryNode node, String weight) {
this.node = node;
this.weight = weight != null ? Double.parseDouble(weight) : Double.MAX_VALUE;
}
@Override
public int compareTo(WeightedDiscoveryNode otherNode) {
return weight.compareTo(otherNode.weight);
}
}
}