Add Failure Details to every NodesResponse (x-plugins side)

Original commit: elastic/x-pack-elasticsearch@9ffb88caaf
This commit is contained in:
Chris Earle 2016-04-27 02:48:10 -04:00
parent 35121bc206
commit ec0a4646ea
9 changed files with 47 additions and 71 deletions

View File

@ -5,9 +5,9 @@
*/
package org.elasticsearch.marvel.agent.collector.node;
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequest;
import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse;
import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags;
import org.elasticsearch.bootstrap.BootstrapInfo;
import org.elasticsearch.client.Client;
@ -72,16 +72,14 @@ public class NodeStatsCollector extends AbstractCollector<NodeStatsCollector> {
request.threadPool(true);
request.fs(true);
NodeStats[] nodesStatsResponses = client.admin().cluster().nodesStats(request).actionGet().getNodes();
NodesStatsResponse response = client.admin().cluster().nodesStats(request).actionGet();
// In unusual scenarios, node stats can be empty (e.g., closing an index in the middle of the request)
// Note: NodesStatsResponse does not currently override failures, so we cannot log the actual reason
if (nodesStatsResponses.length == 0) {
logger.debug("_local NodesStatsResponse is empty");
return null;
// if there's a failure, then we failed to work with the _local node (guaranteed a single exception)
if (response.hasFailures()) {
throw response.failures()[0];
}
NodeStats nodeStats = nodesStatsResponses[0];
NodeStats nodeStats = response.getAt(0);
// Here we are calling directly the DiskThresholdDecider to retrieve the high watermark value
// It would be nicer to use a settings API like documented in #6732

View File

@ -6,6 +6,7 @@
package org.elasticsearch.marvel.agent.resolver.cluster;
import org.elasticsearch.Version;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsNodeResponse;
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
import org.elasticsearch.cluster.ClusterName;
@ -46,7 +47,7 @@ public class ClusterInfoResolverTests extends MonitoringIndexNameResolverTestCas
doc.setLicense(licenseBuilder.build());
doc.setClusterName(randomAsciiOfLength(5));
doc.setClusterStats(new ClusterStatsResponse(Math.abs(randomLong()), ClusterName.DEFAULT,
randomAsciiOfLength(5), new ClusterStatsNodeResponse[]{}));
randomAsciiOfLength(5), new ClusterStatsNodeResponse[]{}, new FailedNodeException[0]));
return doc;
} catch (Exception e) {
throw new IllegalStateException("Failed to generated random ClusterInfoMarvelDoc", e);

View File

@ -6,6 +6,7 @@
package org.elasticsearch.marvel.agent.resolver.cluster;
import org.elasticsearch.Version;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules;
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
@ -97,7 +98,8 @@ public class ClusterStatsResolverTests extends MonitoringIndexNameResolverTestCa
emptyMap(), emptySet(), Version.CURRENT),
ClusterHealthStatus.GREEN, randomNodeInfo(), randomNodeStats(), randomShardStats())
};
return new ClusterStatsResponse(Math.abs(randomLong()), ClusterName.DEFAULT, UUID.randomUUID().toString(), responses);
return new ClusterStatsResponse(Math.abs(randomLong()), ClusterName.DEFAULT, UUID.randomUUID().toString(), responses,
new FailedNodeException[0]);
}
/**

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.shield.action.realm;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
import org.elasticsearch.cluster.ClusterName;
@ -25,32 +26,26 @@ public class ClearRealmCacheResponse extends BaseNodesResponse<ClearRealmCacheRe
public ClearRealmCacheResponse() {
}
public ClearRealmCacheResponse(ClusterName clusterName, Node[] nodes) {
super(clusterName, nodes);
public ClearRealmCacheResponse(ClusterName clusterName, Node[] nodes, FailedNodeException[] failures) {
super(clusterName, nodes, failures);
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
nodes = new Node[in.readVInt()];
for (int i = 0; i < nodes.length; i++) {
nodes[i] = Node.readNodeResponse(in);
}
nodes = in.readArray(Node[]::new, Node::readNodeResponse);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeVInt(nodes.length);
for (Node node : nodes) {
node.writeTo(out);
}
out.writeArray(nodes);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field("cluster_name", getClusterName().value());
super.toInnerXContent(builder, params);
builder.startObject("nodes");
for (ClearRealmCacheResponse.Node node: getNodes()) {
builder.startObject(node.getNode().getId());
@ -58,7 +53,8 @@ public class ClearRealmCacheResponse extends BaseNodesResponse<ClearRealmCacheRe
builder.endObject();
}
builder.endObject();
return builder.endObject();
return builder;
}
@Override

View File

@ -6,6 +6,7 @@
package org.elasticsearch.shield.action.realm;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.nodes.TransportNodesAction;
import org.elasticsearch.cluster.ClusterName;
@ -19,10 +20,6 @@ import org.elasticsearch.shield.authc.support.CachingRealm;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReferenceArray;
/**
*
*/
@ -37,23 +34,15 @@ public class TransportClearRealmCacheAction extends TransportNodesAction<ClearRe
ActionFilters actionFilters, Realms realms,
IndexNameExpressionResolver indexNameExpressionResolver) {
super(settings, ClearRealmCacheAction.NAME, clusterName, threadPool, clusterService, transportService, actionFilters,
indexNameExpressionResolver, ClearRealmCacheRequest::new, ClearRealmCacheRequest.Node::new, ThreadPool.Names.MANAGEMENT);
indexNameExpressionResolver, ClearRealmCacheRequest::new, ClearRealmCacheRequest.Node::new, ThreadPool.Names.MANAGEMENT,
ClearRealmCacheResponse.Node.class);
this.realms = realms;
}
@Override
protected ClearRealmCacheResponse newResponse(ClearRealmCacheRequest request, AtomicReferenceArray responses) {
final List<ClearRealmCacheResponse.Node> nodes = new ArrayList<>();
for (int i = 0; i < responses.length(); i++) {
Object resp = responses.get(i);
if (resp instanceof ClearRealmCacheResponse.Node) {
nodes.add((ClearRealmCacheResponse.Node) resp);
} else if (resp != null) {
// null is possible if there is an error and we do not accumulate exceptions...
throw new IllegalArgumentException("node response [" + resp.getClass() + "] is not the correct type");
}
}
return new ClearRealmCacheResponse(clusterName, nodes.toArray(new ClearRealmCacheResponse.Node[nodes.size()]));
protected ClearRealmCacheResponse newResponse(ClearRealmCacheRequest request,
ClearRealmCacheResponse.Node[] responses, FailedNodeException[] failures) {
return new ClearRealmCacheResponse(clusterName, responses, failures);
}
@Override

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.support.nodes.BaseNodeResponse;
import org.elasticsearch.action.support.nodes.BaseNodesResponse;
import org.elasticsearch.cluster.ClusterName;
@ -25,32 +26,26 @@ public class ClearRolesCacheResponse extends BaseNodesResponse<ClearRolesCacheRe
public ClearRolesCacheResponse() {
}
public ClearRolesCacheResponse(ClusterName clusterName, Node[] nodes) {
super(clusterName, nodes);
public ClearRolesCacheResponse(ClusterName clusterName, Node[] nodes, FailedNodeException[] failures) {
super(clusterName, nodes, failures);
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
nodes = new Node[in.readVInt()];
for (int i = 0; i < nodes.length; i++) {
nodes[i] = Node.readNodeResponse(in);
}
nodes = in.readArray(Node[]::new, Node::readNodeResponse);
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeVInt(nodes.length);
for (Node node : nodes) {
node.writeTo(out);
}
out.writeArray(nodes);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
builder.field("cluster_name", getClusterName().value());
super.toInnerXContent(builder, params);
builder.startObject("nodes");
for (ClearRolesCacheResponse.Node node: getNodes()) {
builder.startObject(node.getNode().getId());
@ -58,7 +53,8 @@ public class ClearRolesCacheResponse extends BaseNodesResponse<ClearRolesCacheRe
builder.endObject();
}
builder.endObject();
return builder.endObject();
return builder;
}
@Override

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.FailedNodeException;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.action.support.nodes.TransportNodesAction;
import org.elasticsearch.cluster.ClusterName;
@ -16,10 +17,6 @@ import org.elasticsearch.shield.authz.store.NativeRolesStore;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReferenceArray;
/**
*
*/
@ -33,24 +30,15 @@ public class TransportClearRolesCacheAction extends TransportNodesAction<ClearRo
ClusterService clusterService, TransportService transportService, ActionFilters actionFilters,
NativeRolesStore rolesStore, IndexNameExpressionResolver indexNameExpressionResolver) {
super(settings, ClearRolesCacheAction.NAME, clusterName, threadPool, clusterService, transportService,
actionFilters, indexNameExpressionResolver, ClearRolesCacheRequest::new, ClearRolesCacheRequest.Node::new,
ThreadPool.Names.MANAGEMENT);
actionFilters, indexNameExpressionResolver, ClearRolesCacheRequest::new, ClearRolesCacheRequest.Node::new,
ThreadPool.Names.MANAGEMENT, ClearRolesCacheResponse.Node.class);
this.rolesStore = rolesStore;
}
@Override
protected ClearRolesCacheResponse newResponse(ClearRolesCacheRequest request, AtomicReferenceArray nodesResponses) {
List<ClearRolesCacheResponse.Node> responses = new ArrayList<>(nodesResponses.length());
for (int i = 0; i < nodesResponses.length(); i++) {
Object resp = nodesResponses.get(i);
if (resp instanceof ClearRolesCacheResponse.Node) {
responses.add((ClearRolesCacheResponse.Node) resp);
} else if (resp == null) {
// null is possible if there is an error and we do not accumulate exceptions...
throw new IllegalArgumentException("node response [" + resp.getClass() + "] is not the correct type");
}
}
return new ClearRolesCacheResponse(clusterName, responses.toArray(new ClearRolesCacheResponse.Node[responses.size()]));
protected ClearRolesCacheResponse newResponse(ClearRolesCacheRequest request,
ClearRolesCacheResponse.Node[] responses, FailedNodeException[] failures) {
return new ClearRolesCacheResponse(clusterName, responses, failures);
}
@Override

View File

@ -44,7 +44,10 @@ public class RestClearRealmCacheAction extends BaseRestHandler {
new SecurityClient(client).clearRealmCache(req, new RestBuilderListener<ClearRealmCacheResponse>(channel) {
@Override
public RestResponse buildResponse(ClearRealmCacheResponse response, XContentBuilder builder) throws Exception {
builder.startObject();
response.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
return new BytesRestResponse(RestStatus.OK, builder);
}
});

View File

@ -45,7 +45,10 @@ public class RestClearRolesCacheAction extends BaseRestHandler {
new SecurityClient(client).clearRolesCache(req, new RestBuilderListener<ClearRolesCacheResponse>(channel) {
@Override
public RestResponse buildResponse(ClearRolesCacheResponse response, XContentBuilder builder) throws Exception {
builder.startObject();
response.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
return new BytesRestResponse(RestStatus.OK, builder);
}
});